Migrate absl::optional to std::optional

Bug: webrtc:342905193
No-Try: True
Change-Id: Icc968be43b8830038ea9a1f5f604307220457807
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/361021
Auto-Submit: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42911}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index 53e4caa..bf258c5 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -127,7 +127,6 @@
     "../rtc_base/system:rtc_export",
     "units:timestamp",
     "video:video_rtp_headers",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -147,14 +146,12 @@
     "../rtc_base/system:rtc_export",
     "units:time_delta",
     "units:timestamp",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
 rtc_source_set("video_track_source_constraints") {
   visibility = [ "*" ]
   sources = [ "video_track_source_constraints.h" ]
-  deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
 }
 
 rtc_library("media_stream_interface") {
@@ -181,7 +178,6 @@
     "video:recordable_encoded_frame",
     "video:video_frame",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -243,7 +239,6 @@
     "../rtc_base:ssl",
     "../rtc_base/system:rtc_export",
     "//third_party/abseil-cpp/absl/base:core_headers",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -391,7 +386,6 @@
     "//third_party/abseil-cpp/absl/functional:any_invocable",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
 
     # Basically, don't add stuff here. You might break sensitive downstream
     # targets like pnacl. API should not depend on anything outside of this
@@ -421,7 +415,6 @@
     "units:timestamp",
     "video:encoded_frame",
     "video:video_frame_metadata",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -437,7 +430,6 @@
     "../rtc_base:macromagic",
     "../rtc_base/system:rtc_export",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -498,7 +490,6 @@
     "video:video_rtp_headers",
     "video_codecs:video_codecs_api",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -542,7 +533,6 @@
     "video_codecs:scalability_mode",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -634,7 +624,6 @@
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -649,7 +638,6 @@
     ":scoped_refptr",
     "../rtc_base:checks",
     "video:video_frame",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -688,7 +676,6 @@
         "transport:bitrate_settings",
         "transport:network_control",
         "video_codecs:video_codecs_api",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
 
@@ -758,7 +745,6 @@
     "environment:environment_factory",
     "//third_party/abseil-cpp/absl/base:nullability",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -777,7 +763,6 @@
     "../test:fileutils",
     "test/pclf:media_configuration",
     "units:time_delta",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -824,7 +809,6 @@
     "../rtc_base:refcount",
     "../rtc_base/system:rtc_export",
     "units:timestamp",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -840,7 +824,6 @@
     ":array_view",
     "../rtc_base:stringutils",
     "../rtc_base/system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -875,7 +858,6 @@
     "../rtc_base:random",
     "units:data_rate",
     "//third_party/abseil-cpp/absl/functional:any_invocable",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -905,7 +887,6 @@
     "units:data_size",
     "units:timestamp",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1052,7 +1033,6 @@
         "//third_party/abseil-cpp/absl/flags:flag",
         "//third_party/abseil-cpp/absl/flags:parse",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
   }
@@ -1089,7 +1069,6 @@
       "../api/units:frequency",
       "../rtc_base:stringutils",
       "video:video_frame_type",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -1104,7 +1083,6 @@
       "video:encoded_image",
       "video:video_frame",
       "video_codecs:video_codecs_api",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -1143,7 +1121,6 @@
     deps = [
       "../api:media_stream_interface",
       "../test:test_support",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -1160,7 +1137,6 @@
       "../rtc_base:refcount",
       "../test:test_support",
       "//third_party/abseil-cpp/absl/functional:any_invocable",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -1238,7 +1214,6 @@
       "../test:test_support",
       "units:data_rate",
       "video:render_resolution",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -1329,7 +1304,6 @@
       "transport:bandwidth_estimation_settings",
       "transport:bitrate_settings",
       "transport:network_control",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -1414,7 +1388,6 @@
       "crypto:frame_encryptor_interface",
       "transport/rtp:rtp_source",
       "video_codecs:video_codecs_api",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -1428,7 +1401,6 @@
       ":frame_transformer_interface",
       "../api/units:timestamp",
       "../test:test_support",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -1443,7 +1415,6 @@
       "../test:test_support",
       "units:timestamp",
       "video:video_frame_metadata",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -1498,7 +1469,6 @@
       "../test:test_support",
       "video:encoded_image",
       "video:video_frame",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -1630,7 +1600,6 @@
       "//third_party/abseil-cpp/absl/functional:any_invocable",
       "//third_party/abseil-cpp/absl/strings",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
diff --git a/api/audio/BUILD.gn b/api/audio/BUILD.gn
index 1f9e43d..22c3296 100644
--- a/api/audio/BUILD.gn
+++ b/api/audio/BUILD.gn
@@ -20,7 +20,6 @@
     "../../rtc_base:checks",
     "../../rtc_base:stringutils",
     "../task_queue",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -41,7 +40,6 @@
     "../../rtc_base:logging",
     "../../rtc_base:macromagic",
     "../../rtc_base:timeutils",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -83,7 +81,6 @@
     "../task_queue",
     "//third_party/abseil-cpp/absl/base:nullability",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -93,10 +90,7 @@
     "audio_processing_statistics.cc",
     "audio_processing_statistics.h",
   ]
-  deps = [
-    "../../rtc_base/system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
-  ]
+  deps = [ "../../rtc_base/system:rtc_export" ]
 }
 
 rtc_library("aec3_config") {
@@ -125,7 +119,6 @@
     ":echo_control",
     "../../modules/audio_processing/aec3",
     "../../rtc_base/system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/api/audio/audio_device.h b/api/audio/audio_device.h
index eb8b7ec..5a2c2d2 100644
--- a/api/audio/audio_device.h
+++ b/api/audio/audio_device.h
@@ -11,7 +11,7 @@
 #ifndef API_AUDIO_AUDIO_DEVICE_H_
 #define API_AUDIO_AUDIO_DEVICE_H_
 
-#include "absl/types/optional.h"
+#include <optional>
 #include "api/audio/audio_device_defines.h"
 #include "api/ref_count.h"
 #include "api/scoped_refptr.h"
@@ -169,7 +169,7 @@
 
   // Used to generate RTC stats. If not implemented, RTCAudioPlayoutStats will
   // not be present in the stats.
-  virtual absl::optional<Stats> GetStats() const { return absl::nullopt; }
+  virtual std::optional<Stats> GetStats() const { return std::nullopt; }
 
 // Only supported on iOS.
 #if defined(WEBRTC_IOS)
diff --git a/api/audio/audio_device_defines.h b/api/audio/audio_device_defines.h
index 304b876..d27f732 100644
--- a/api/audio/audio_device_defines.h
+++ b/api/audio/audio_device_defines.h
@@ -14,9 +14,9 @@
 #include <stddef.h>
 
 #include <cstdint>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "rtc_base/strings/string_builder.h"
 
 namespace webrtc {
@@ -57,7 +57,7 @@
       uint32_t currentMicLevel,
       bool keyPressed,
       uint32_t& newMicLevel,
-      absl::optional<int64_t> estimatedCaptureTimeNS) {  // NOLINT
+      std::optional<int64_t> estimatedCaptureTimeNS) {  // NOLINT
     // TODO(webrtc:13620) Make the default behaver of the new API to behave as
     // the old API. This can be pure virtual if all uses of the old API is
     // removed.
diff --git a/api/audio/audio_frame.cc b/api/audio/audio_frame.cc
index a2aa774..ae4380e 100644
--- a/api/audio/audio_frame.cc
+++ b/api/audio/audio_frame.cc
@@ -13,8 +13,8 @@
 #include <string.h>
 
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/audio_view.h"
 #include "api/audio/channel_layout.h"
@@ -62,7 +62,7 @@
   vad_activity_ = kVadUnknown;
   profile_timestamp_ms_ = 0;
   packet_infos_ = RtpPacketInfos();
-  absolute_capture_timestamp_ms_ = absl::nullopt;
+  absolute_capture_timestamp_ms_ = std::nullopt;
 }
 
 void AudioFrame::UpdateFrame(uint32_t timestamp,
diff --git a/api/audio/audio_frame.h b/api/audio/audio_frame.h
index 5683e8b..9afd516 100644
--- a/api/audio/audio_frame.h
+++ b/api/audio/audio_frame.h
@@ -15,8 +15,8 @@
 #include <stdint.h>
 
 #include <array>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/audio_view.h"
 #include "api/audio/channel_layout.h"
@@ -164,7 +164,7 @@
     absolute_capture_timestamp_ms_ = absolute_capture_time_stamp_ms;
   }
 
-  absl::optional<int64_t> absolute_capture_timestamp_ms() const {
+  std::optional<int64_t> absolute_capture_timestamp_ms() const {
     return absolute_capture_timestamp_ms_;
   }
 
@@ -189,7 +189,7 @@
   // Typically used for measuring elapsed time between two different points in
   // the audio path. No lock is used to save resources and we are thread safe
   // by design.
-  // TODO(nisse@webrtc.org): consider using absl::optional.
+  // TODO(nisse@webrtc.org): consider using std::optional.
   int64_t profile_timestamp_ms_ = 0;
 
   // Information about packets used to assemble this audio frame. This is needed
@@ -222,7 +222,7 @@
   // This is only valid for audio frames captured on this machine. The absolute
   // capture timestamp of a received frame is found in `packet_infos_`.
   // This timestamp MUST be based on the same clock as rtc::TimeMillis().
-  absl::optional<int64_t> absolute_capture_timestamp_ms_;
+  std::optional<int64_t> absolute_capture_timestamp_ms_;
 };
 
 }  // namespace webrtc
diff --git a/api/audio/audio_processing.h b/api/audio/audio_processing.h
index 2448c9f..dca75f2 100644
--- a/api/audio/audio_processing.h
+++ b/api/audio/audio_processing.h
@@ -24,12 +24,12 @@
 #include <array>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 
 #include "absl/base/nullability.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/audio_processing_statistics.h"
 #include "api/audio/echo_control.h"
@@ -931,8 +931,8 @@
       rtc::ArrayView<const float> capture_audio) = 0;
 
   struct Metrics {
-    absl::optional<double> echo_likelihood;
-    absl::optional<double> echo_likelihood_recent_max;
+    std::optional<double> echo_likelihood;
+    std::optional<double> echo_likelihood_recent_max;
   };
 
   // Collect current metrics from the echo detector.
diff --git a/api/audio/audio_processing_statistics.h b/api/audio/audio_processing_statistics.h
index 6f77d07..d6f8b6e 100644
--- a/api/audio/audio_processing_statistics.h
+++ b/api/audio/audio_processing_statistics.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
@@ -30,16 +31,16 @@
   // It is conservative in flagging audio as speech, with low likelihood of
   // incorrectly flagging a frame as voice.
   // Only reported if voice detection is enabled in AudioProcessing::Config.
-  absl::optional<bool> voice_detected;
+  std::optional<bool> voice_detected;
 
   // AEC Statistics.
   // ERL = 10log_10(P_far / P_echo)
-  absl::optional<double> echo_return_loss;
+  std::optional<double> echo_return_loss;
   // ERLE = 10log_10(P_echo / P_out)
-  absl::optional<double> echo_return_loss_enhancement;
+  std::optional<double> echo_return_loss_enhancement;
   // Fraction of time that the AEC linear filter is divergent, in a 1-second
   // non-overlapped aggregation window.
-  absl::optional<double> divergent_filter_fraction;
+  std::optional<double> divergent_filter_fraction;
 
   // The delay metrics consists of the delay median and standard deviation. It
   // also consists of the fraction of delay estimates that can make the echo
@@ -48,18 +49,18 @@
   // second. Note that if there are several clients pulling metrics from
   // `GetStatistics()` during a session the first call from any of them will
   // change to one second aggregation window for all.
-  absl::optional<int32_t> delay_median_ms;
-  absl::optional<int32_t> delay_standard_deviation_ms;
+  std::optional<int32_t> delay_median_ms;
+  std::optional<int32_t> delay_standard_deviation_ms;
 
   // Residual echo detector likelihood.
-  absl::optional<double> residual_echo_likelihood;
+  std::optional<double> residual_echo_likelihood;
   // Maximum residual echo likelihood from the last time period.
-  absl::optional<double> residual_echo_likelihood_recent_max;
+  std::optional<double> residual_echo_likelihood_recent_max;
 
   // The instantaneous delay estimate produced in the AEC. The unit is in
   // milliseconds and the value is the instantaneous value at the time of the
   // call to `GetStatistics()`.
-  absl::optional<int32_t> delay_ms;
+  std::optional<int32_t> delay_ms;
 };
 
 }  // namespace webrtc
diff --git a/api/audio/echo_canceller3_factory.cc b/api/audio/echo_canceller3_factory.cc
index 8422a3e..9b1273d 100644
--- a/api/audio/echo_canceller3_factory.cc
+++ b/api/audio/echo_canceller3_factory.cc
@@ -10,8 +10,8 @@
 #include "api/audio/echo_canceller3_factory.h"
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "api/audio/echo_control.h"
 #include "modules/audio_processing/aec3/echo_canceller3.h"
@@ -28,7 +28,7 @@
     int num_render_channels,
     int num_capture_channels) {
   return std::make_unique<EchoCanceller3>(
-      config_, /*multichannel_config=*/absl::nullopt, sample_rate_hz,
+      config_, /*multichannel_config=*/std::nullopt, sample_rate_hz,
       num_render_channels, num_capture_channels);
 }
 
diff --git a/api/audio_codecs/BUILD.gn b/api/audio_codecs/BUILD.gn
index d91c501..1995c6d 100644
--- a/api/audio_codecs/BUILD.gn
+++ b/api/audio_codecs/BUILD.gn
@@ -48,7 +48,6 @@
     "//third_party/abseil-cpp/absl/base:nullability",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -65,7 +64,6 @@
     "L16:audio_decoder_L16",
     "g711:audio_decoder_g711",
     "g722:audio_decoder_g722",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   defines = []
   if (rtc_include_ilbc) {
@@ -99,14 +97,12 @@
     "L16:audio_encoder_L16",
     "g711:audio_encoder_g711",
     "g722:audio_encoder_g722",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   defines = []
   if (rtc_include_ilbc) {
     deps += [
       "..:field_trials_view",
       "ilbc:audio_encoder_ilbc",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
     defines += [ "WEBRTC_USE_BUILTIN_ILBC=1" ]
   } else {
@@ -136,7 +132,6 @@
     "..:scoped_refptr",
     "opus:audio_decoder_multiopus",
     "opus:audio_decoder_opus",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -153,6 +148,5 @@
     "..:scoped_refptr",
     "opus:audio_encoder_multiopus",
     "opus:audio_encoder_opus",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
diff --git a/api/audio_codecs/L16/BUILD.gn b/api/audio_codecs/L16/BUILD.gn
index f2cefbd..8ce7122 100644
--- a/api/audio_codecs/L16/BUILD.gn
+++ b/api/audio_codecs/L16/BUILD.gn
@@ -29,7 +29,6 @@
     "../../../rtc_base:stringutils",
     "../../../rtc_base/system:rtc_export",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -47,6 +46,5 @@
     "../../../rtc_base:safe_conversions",
     "../../../rtc_base/system:rtc_export",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
diff --git a/api/audio_codecs/L16/audio_decoder_L16.cc b/api/audio_codecs/L16/audio_decoder_L16.cc
index b392523..a84aa1c 100644
--- a/api/audio_codecs/L16/audio_decoder_L16.cc
+++ b/api/audio_codecs/L16/audio_decoder_L16.cc
@@ -11,10 +11,10 @@
 #include "api/audio_codecs/L16/audio_decoder_L16.h"
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -25,7 +25,7 @@
 
 namespace webrtc {
 
-absl::optional<AudioDecoderL16::Config> AudioDecoderL16::SdpToConfig(
+std::optional<AudioDecoderL16::Config> AudioDecoderL16::SdpToConfig(
     const SdpAudioFormat& format) {
   Config config;
   config.sample_rate_hz = format.clockrate_hz;
@@ -33,7 +33,7 @@
   if (absl::EqualsIgnoreCase(format.name, "L16") && config.IsOk()) {
     return config;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void AudioDecoderL16::AppendSupportedDecoders(
@@ -43,7 +43,7 @@
 
 std::unique_ptr<AudioDecoder> AudioDecoderL16::MakeAudioDecoder(
     const Config& config,
-    absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+    std::optional<AudioCodecPairId> /*codec_pair_id*/,
     const FieldTrialsView* field_trials) {
   if (!config.IsOk()) {
     return nullptr;
diff --git a/api/audio_codecs/L16/audio_decoder_L16.h b/api/audio_codecs/L16/audio_decoder_L16.h
index 5a01b7d..339527f 100644
--- a/api/audio_codecs/L16/audio_decoder_L16.h
+++ b/api/audio_codecs/L16/audio_decoder_L16.h
@@ -12,9 +12,9 @@
 #define API_AUDIO_CODECS_L16_AUDIO_DECODER_L16_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -36,11 +36,11 @@
     int sample_rate_hz = 8000;
     int num_channels = 1;
   };
-  static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
   static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
   static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
       const Config& config,
-      absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+      std::optional<AudioCodecPairId> codec_pair_id = std::nullopt,
       const FieldTrialsView* field_trials = nullptr);
 };
 
diff --git a/api/audio_codecs/L16/audio_encoder_L16.cc b/api/audio_codecs/L16/audio_encoder_L16.cc
index 6435cd0..3bc3241 100644
--- a/api/audio_codecs/L16/audio_encoder_L16.cc
+++ b/api/audio_codecs/L16/audio_encoder_L16.cc
@@ -14,11 +14,11 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -32,11 +32,11 @@
 
 namespace webrtc {
 
-absl::optional<AudioEncoderL16::Config> AudioEncoderL16::SdpToConfig(
+std::optional<AudioEncoderL16::Config> AudioEncoderL16::SdpToConfig(
     const SdpAudioFormat& format) {
   if (!rtc::IsValueInRangeForNumericType<int>(format.num_channels)) {
     RTC_DCHECK_NOTREACHED();
-    return absl::nullopt;
+    return std::nullopt;
   }
   Config config;
   config.sample_rate_hz = format.clockrate_hz;
@@ -51,7 +51,7 @@
   if (absl::EqualsIgnoreCase(format.name, "L16") && config.IsOk()) {
     return config;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void AudioEncoderL16::AppendSupportedEncoders(
@@ -70,7 +70,7 @@
 std::unique_ptr<AudioEncoder> AudioEncoderL16::MakeAudioEncoder(
     const AudioEncoderL16::Config& config,
     int payload_type,
-    absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+    std::optional<AudioCodecPairId> /*codec_pair_id*/,
     const FieldTrialsView* field_trials) {
   AudioEncoderPcm16B::Config c;
   c.sample_rate_hz = config.sample_rate_hz;
diff --git a/api/audio_codecs/L16/audio_encoder_L16.h b/api/audio_codecs/L16/audio_encoder_L16.h
index 4750984..a104a63 100644
--- a/api/audio_codecs/L16/audio_encoder_L16.h
+++ b/api/audio_codecs/L16/audio_encoder_L16.h
@@ -12,9 +12,9 @@
 #define API_AUDIO_CODECS_L16_AUDIO_ENCODER_L16_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -39,13 +39,13 @@
     int num_channels = 1;
     int frame_size_ms = 10;
   };
-  static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
   static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
   static AudioCodecInfo QueryAudioEncoder(const Config& config);
   static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
       const Config& config,
       int payload_type,
-      absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+      std::optional<AudioCodecPairId> codec_pair_id = std::nullopt,
       const FieldTrialsView* field_trials = nullptr);
 };
 
diff --git a/api/audio_codecs/audio_decoder.cc b/api/audio_codecs/audio_decoder.cc
index 84a3eb2..23ef2c8 100644
--- a/api/audio_codecs/audio_decoder.cc
+++ b/api/audio_codecs/audio_decoder.cc
@@ -13,10 +13,10 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "rtc_base/buffer.h"
 #include "rtc_base/checks.h"
@@ -37,14 +37,14 @@
     return ret < 0 ? 0 : static_cast<size_t>(ret);
   }
 
-  absl::optional<DecodeResult> Decode(
+  std::optional<DecodeResult> Decode(
       rtc::ArrayView<int16_t> decoded) const override {
     auto speech_type = AudioDecoder::kSpeech;
     const int ret = decoder_->Decode(
         payload_.data(), payload_.size(), decoder_->SampleRateHz(),
         decoded.size() * sizeof(int16_t), decoded.data(), &speech_type);
-    return ret < 0 ? absl::nullopt
-                   : absl::optional<DecodeResult>(
+    return ret < 0 ? std::nullopt
+                   : std::optional<DecodeResult>(
                          {static_cast<size_t>(ret), speech_type});
   }
 
diff --git a/api/audio_codecs/audio_decoder.h b/api/audio_codecs/audio_decoder.h
index 4113874..21d6056 100644
--- a/api/audio_codecs/audio_decoder.h
+++ b/api/audio_codecs/audio_decoder.h
@@ -15,9 +15,9 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "rtc_base/buffer.h"
 
@@ -57,11 +57,11 @@
 
     // Decodes this frame of audio and writes the result in `decoded`.
     // `decoded` must be large enough to store as many samples as indicated by a
-    // call to Duration() . On success, returns an absl::optional containing the
+    // call to Duration() . On success, returns an std::optional containing the
     // total number of samples across all channels, as well as whether the
     // decoder produced comfort noise or speech. On failure, returns an empty
-    // absl::optional. Decode may be called at most once per frame object.
-    virtual absl::optional<DecodeResult> Decode(
+    // std::optional. Decode may be called at most once per frame object.
+    virtual std::optional<DecodeResult> Decode(
         rtc::ArrayView<int16_t> decoded) const = 0;
   };
 
diff --git a/api/audio_codecs/audio_decoder_factory.h b/api/audio_codecs/audio_decoder_factory.h
index 282d4d9..a1ef2ca 100644
--- a/api/audio_codecs/audio_decoder_factory.h
+++ b/api/audio_codecs/audio_decoder_factory.h
@@ -12,10 +12,10 @@
 #define API_AUDIO_CODECS_AUDIO_DECODER_FACTORY_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "absl/base/nullability.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -49,7 +49,7 @@
   [[deprecated("bugs.webrtc.org/356878416 - Use `Create` instead")]]  //
   virtual std::unique_ptr<AudioDecoder>
   MakeAudioDecoder(const SdpAudioFormat& format,
-                   absl::optional<AudioCodecPairId> codec_pair_id) {
+                   std::optional<AudioCodecPairId> codec_pair_id) {
     RTC_DCHECK_NOTREACHED();
     return nullptr;
   }
@@ -59,7 +59,7 @@
   virtual absl::Nullable<std::unique_ptr<AudioDecoder>> Create(
       const Environment& env,
       const SdpAudioFormat& format,
-      absl::optional<AudioCodecPairId> codec_pair_id) {
+      std::optional<AudioCodecPairId> codec_pair_id) {
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
     return MakeAudioDecoder(format, codec_pair_id);
diff --git a/api/audio_codecs/audio_decoder_factory_template.h b/api/audio_codecs/audio_decoder_factory_template.h
index f72531c..257a609 100644
--- a/api/audio_codecs/audio_decoder_factory_template.h
+++ b/api/audio_codecs/audio_decoder_factory_template.h
@@ -12,10 +12,10 @@
 #define API_AUDIO_CODECS_AUDIO_DECODER_FACTORY_TEMPLATE_H_
 
 #include <memory>
+#include <optional>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_decoder_factory.h"
@@ -40,7 +40,7 @@
   static absl::Nullable<std::unique_ptr<AudioDecoder>> MakeAudioDecoder(
       const Environment& env,
       const SdpAudioFormat& format,
-      absl::optional<AudioCodecPairId> codec_pair_id) {
+      std::optional<AudioCodecPairId> codec_pair_id) {
     return nullptr;
   }
 };
@@ -54,13 +54,13 @@
               decltype(Trait::MakeAudioDecoder(
                   std::declval<Environment>(),
                   std::declval<typename Trait::Config>(),
-                  std::declval<absl::optional<AudioCodecPairId>>())),
+                  std::declval<std::optional<AudioCodecPairId>>())),
               std::unique_ptr<AudioDecoder>>>>
 absl::Nullable<std::unique_ptr<AudioDecoder>> CreateDecoder(
     Rank1,
     const Environment& env,
     const typename Trait::Config& config,
-    absl::optional<AudioCodecPairId> codec_pair_id) {
+    std::optional<AudioCodecPairId> codec_pair_id) {
   return Trait::MakeAudioDecoder(env, config, codec_pair_id);
 }
 
@@ -68,13 +68,13 @@
           typename = std::enable_if_t<std::is_convertible_v<
               decltype(Trait::MakeAudioDecoder(
                   std::declval<typename Trait::Config>(),
-                  std::declval<absl::optional<AudioCodecPairId>>())),
+                  std::declval<std::optional<AudioCodecPairId>>())),
               std::unique_ptr<AudioDecoder>>>>
 absl::Nullable<std::unique_ptr<AudioDecoder>> CreateDecoder(
     Rank0,
     const Environment& env,
     const typename Trait::Config& config,
-    absl::optional<AudioCodecPairId> codec_pair_id) {
+    std::optional<AudioCodecPairId> codec_pair_id) {
   return Trait::MakeAudioDecoder(config, codec_pair_id);
 }
 
@@ -89,16 +89,16 @@
   static bool IsSupportedDecoder(const SdpAudioFormat& format) {
     auto opt_config = T::SdpToConfig(format);
     static_assert(std::is_same<decltype(opt_config),
-                               absl::optional<typename T::Config>>::value,
+                               std::optional<typename T::Config>>::value,
                   "T::SdpToConfig() must return a value of type "
-                  "absl::optional<T::Config>");
+                  "std::optional<T::Config>");
     return opt_config ? true : Helper<Ts...>::IsSupportedDecoder(format);
   }
 
   static absl::Nullable<std::unique_ptr<AudioDecoder>> MakeAudioDecoder(
       const Environment& env,
       const SdpAudioFormat& format,
-      absl::optional<AudioCodecPairId> codec_pair_id) {
+      std::optional<AudioCodecPairId> codec_pair_id) {
     auto opt_config = T::SdpToConfig(format);
     return opt_config.has_value()
                ? CreateDecoder<T>(Rank1{}, env, *opt_config, codec_pair_id)
@@ -122,7 +122,7 @@
   absl::Nullable<std::unique_ptr<AudioDecoder>> Create(
       const Environment& env,
       const SdpAudioFormat& format,
-      absl::optional<AudioCodecPairId> codec_pair_id) override {
+      std::optional<AudioCodecPairId> codec_pair_id) override {
     return Helper<Ts...>::MakeAudioDecoder(env, format, codec_pair_id);
   }
 };
@@ -137,7 +137,7 @@
 //   // Converts `audio_format` to a ConfigType instance. Returns an empty
 //   // optional if `audio_format` doesn't correctly specify a decoder of our
 //   // type.
-//   absl::optional<ConfigType> SdpToConfig(const SdpAudioFormat& audio_format);
+//   std::optional<ConfigType> SdpToConfig(const SdpAudioFormat& audio_format);
 //
 //   // Appends zero or more AudioCodecSpecs to the list that will be returned
 //   // by AudioDecoderFactory::GetSupportedDecoders().
@@ -148,11 +148,11 @@
 //   std::unique_ptr<AudioEncoder> MakeAudioDecoder(
 //       const Environment& env,
 //       const ConfigType& config,
-//       absl::optional<AudioCodecPairId> codec_pair_id);
+//       std::optional<AudioCodecPairId> codec_pair_id);
 //   or
 //   std::unique_ptr<AudioDecoder> MakeAudioDecoder(
 //       const ConfigType& config,
-//       absl::optional<AudioCodecPairId> codec_pair_id);
+//       std::optional<AudioCodecPairId> codec_pair_id);
 //
 // ConfigType should be a type that encapsulates all the settings needed to
 // create an AudioDecoder. T::Config (where T is the decoder struct) should
diff --git a/api/audio_codecs/audio_encoder.cc b/api/audio_codecs/audio_encoder.cc
index bb558be..de64550 100644
--- a/api/audio_codecs/audio_encoder.cc
+++ b/api/audio_codecs/audio_encoder.cc
@@ -13,9 +13,9 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/call/bitrate_allocation.h"
 #include "rtc_base/buffer.h"
@@ -96,12 +96,12 @@
 }
 
 void AudioEncoder::OnReceivedTargetAudioBitrate(int target_audio_bitrate_bps) {
-  OnReceivedUplinkBandwidth(target_audio_bitrate_bps, absl::nullopt);
+  OnReceivedUplinkBandwidth(target_audio_bitrate_bps, std::nullopt);
 }
 
 void AudioEncoder::OnReceivedUplinkBandwidth(
     int target_audio_bitrate_bps,
-    absl::optional<int64_t> bwe_period_ms) {}
+    std::optional<int64_t> bwe_period_ms) {}
 
 void AudioEncoder::OnReceivedUplinkAllocation(BitrateAllocationUpdate update) {
   OnReceivedUplinkBandwidth(update.target_bitrate.bps(),
diff --git a/api/audio_codecs/audio_encoder.h b/api/audio_codecs/audio_encoder.h
index 552319b..d84d2b5 100644
--- a/api/audio_codecs/audio_encoder.h
+++ b/api/audio_codecs/audio_encoder.h
@@ -15,12 +15,12 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/base/attributes.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/call/bitrate_allocation.h"
 #include "api/units/data_rate.h"
@@ -39,30 +39,30 @@
   // Number of actions taken by the ANA bitrate controller since the start of
   // the call. If this value is not set, it indicates that the bitrate
   // controller is disabled.
-  absl::optional<uint32_t> bitrate_action_counter;
+  std::optional<uint32_t> bitrate_action_counter;
   // Number of actions taken by the ANA channel controller since the start of
   // the call. If this value is not set, it indicates that the channel
   // controller is disabled.
-  absl::optional<uint32_t> channel_action_counter;
+  std::optional<uint32_t> channel_action_counter;
   // Number of actions taken by the ANA DTX controller since the start of the
   // call. If this value is not set, it indicates that the DTX controller is
   // disabled.
-  absl::optional<uint32_t> dtx_action_counter;
+  std::optional<uint32_t> dtx_action_counter;
   // Number of actions taken by the ANA FEC controller since the start of the
   // call. If this value is not set, it indicates that the FEC controller is
   // disabled.
-  absl::optional<uint32_t> fec_action_counter;
+  std::optional<uint32_t> fec_action_counter;
   // Number of times the ANA frame length controller decided to increase the
   // frame length since the start of the call. If this value is not set, it
   // indicates that the frame length controller is disabled.
-  absl::optional<uint32_t> frame_length_increase_counter;
+  std::optional<uint32_t> frame_length_increase_counter;
   // Number of times the ANA frame length controller decided to decrease the
   // frame length since the start of the call. If this value is not set, it
   // indicates that the frame length controller is disabled.
-  absl::optional<uint32_t> frame_length_decrease_counter;
+  std::optional<uint32_t> frame_length_decrease_counter;
   // The uplink packet loss fractions as set by the ANA FEC controller. If this
   // value is not set, it indicates that the ANA FEC controller is not active.
-  absl::optional<float> uplink_packet_loss_fraction;
+  std::optional<float> uplink_packet_loss_fraction;
 };
 
 // This is the interface class for encoders in AudioCoding module. Each codec
@@ -223,7 +223,7 @@
   // Provides target audio bitrate and corresponding probing interval of
   // the bandwidth estimator to this encoder to allow it to adapt.
   virtual void OnReceivedUplinkBandwidth(int target_audio_bitrate_bps,
-                                         absl::optional<int64_t> bwe_period_ms);
+                                         std::optional<int64_t> bwe_period_ms);
 
   // Provides target audio bitrate and corresponding probing interval of
   // the bandwidth estimator to this encoder to allow it to adapt.
@@ -247,15 +247,14 @@
   // The range of frame lengths that are supported or nullopt if there's no such
   // information. This is used together with the bitrate range to calculate the
   // full bitrate range, including overhead.
-  virtual absl::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
+  virtual std::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
       const = 0;
 
   // The range of payload bitrates that are supported. This is used together
   // with the frame length range to calculate the full bitrate range, including
   // overhead.
-  virtual absl::optional<std::pair<DataRate, DataRate>> GetBitrateRange()
-      const {
-    return absl::nullopt;
+  virtual std::optional<std::pair<DataRate, DataRate>> GetBitrateRange() const {
+    return std::nullopt;
   }
 
   // The maximum number of audio channels supported by WebRTC encoders.
diff --git a/api/audio_codecs/audio_encoder_factory.h b/api/audio_codecs/audio_encoder_factory.h
index 8fe09f9..c73fe22 100644
--- a/api/audio_codecs/audio_encoder_factory.h
+++ b/api/audio_codecs/audio_encoder_factory.h
@@ -12,9 +12,9 @@
 #define API_AUDIO_CODECS_AUDIO_ENCODER_FACTORY_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -44,7 +44,7 @@
     // Note: Implementations need to be robust against combinations other than
     // one encoder, one decoder getting the same ID; such encoders must still
     // work.
-    absl::optional<AudioCodecPairId> codec_pair_id;
+    std::optional<AudioCodecPairId> codec_pair_id;
   };
 
   // Returns a prioritized list of audio codecs, to use for signaling etc.
@@ -53,7 +53,7 @@
   // Returns information about how this format would be encoded, provided it's
   // supported. More format and format variations may be supported than those
   // returned by GetSupportedEncoders().
-  virtual absl::optional<AudioCodecInfo> QueryAudioEncoder(
+  virtual std::optional<AudioCodecInfo> QueryAudioEncoder(
       const SdpAudioFormat& format) = 0;
 
   // Creates an AudioEncoder for the specified format.
diff --git a/api/audio_codecs/audio_encoder_factory_template.h b/api/audio_codecs/audio_encoder_factory_template.h
index 6a70c57..8b26330 100644
--- a/api/audio_codecs/audio_encoder_factory_template.h
+++ b/api/audio_codecs/audio_encoder_factory_template.h
@@ -12,11 +12,11 @@
 #define API_AUDIO_CODECS_AUDIO_ENCODER_FACTORY_TEMPLATE_H_
 
 #include <memory>
+#include <optional>
 #include <type_traits>
 #include <vector>
 
 #include "absl/base/nullability.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_encoder_factory.h"
@@ -36,9 +36,9 @@
 template <>
 struct Helper<> {
   static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs) {}
-  static absl::optional<AudioCodecInfo> QueryAudioEncoder(
+  static std::optional<AudioCodecInfo> QueryAudioEncoder(
       const SdpAudioFormat& format) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   static absl::Nullable<std::unique_ptr<AudioEncoder>> CreateAudioEncoder(
       const Environment& env,
@@ -72,7 +72,7 @@
               decltype(Trait::MakeAudioEncoder(
                   std::declval<typename Trait::Config>(),
                   int{},
-                  std::declval<absl::optional<AudioCodecPairId>>())),
+                  std::declval<std::optional<AudioCodecPairId>>())),
               std::unique_ptr<AudioEncoder>>>>
 absl::Nullable<std::unique_ptr<AudioEncoder>> CreateEncoder(
     Rank0,
@@ -91,14 +91,14 @@
     T::AppendSupportedEncoders(specs);
     Helper<Ts...>::AppendSupportedEncoders(specs);
   }
-  static absl::optional<AudioCodecInfo> QueryAudioEncoder(
+  static std::optional<AudioCodecInfo> QueryAudioEncoder(
       const SdpAudioFormat& format) {
     auto opt_config = T::SdpToConfig(format);
     static_assert(std::is_same<decltype(opt_config),
-                               absl::optional<typename T::Config>>::value,
+                               std::optional<typename T::Config>>::value,
                   "T::SdpToConfig() must return a value of type "
-                  "absl::optional<T::Config>");
-    return opt_config ? absl::optional<AudioCodecInfo>(
+                  "std::optional<T::Config>");
+    return opt_config ? std::optional<AudioCodecInfo>(
                             T::QueryAudioEncoder(*opt_config))
                       : Helper<Ts...>::QueryAudioEncoder(format);
   }
@@ -123,7 +123,7 @@
     return specs;
   }
 
-  absl::optional<AudioCodecInfo> QueryAudioEncoder(
+  std::optional<AudioCodecInfo> QueryAudioEncoder(
       const SdpAudioFormat& format) override {
     return Helper<Ts...>::QueryAudioEncoder(format);
   }
@@ -146,7 +146,7 @@
 //   // Converts `audio_format` to a ConfigType instance. Returns an empty
 //   // optional if `audio_format` doesn't correctly specify an encoder of our
 //   // type.
-//   absl::optional<ConfigType> SdpToConfig(const SdpAudioFormat& audio_format);
+//   std::optional<ConfigType> SdpToConfig(const SdpAudioFormat& audio_format);
 //
 //   // Appends zero or more AudioCodecSpecs to the list that will be returned
 //   // by AudioEncoderFactory::GetSupportedEncoders().
@@ -166,7 +166,7 @@
 //   std::unique_ptr<AudioEncoder> MakeAudioEncoder(
 //       const ConfigType& config,
 //       int payload_type,
-//       absl::optional<AudioCodecPairId> codec_pair_id);
+//       std::optional<AudioCodecPairId> codec_pair_id);
 //
 // ConfigType should be a type that encapsulates all the settings needed to
 // create an AudioEncoder. T::Config (where T is the encoder struct) should
diff --git a/api/audio_codecs/builtin_audio_decoder_factory.cc b/api/audio_codecs/builtin_audio_decoder_factory.cc
index 25be26e..ce3b534 100644
--- a/api/audio_codecs/builtin_audio_decoder_factory.cc
+++ b/api/audio_codecs/builtin_audio_decoder_factory.cc
@@ -11,9 +11,9 @@
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/L16/audio_decoder_L16.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
@@ -39,8 +39,7 @@
 template <typename T>
 struct NotAdvertised {
   using Config = typename T::Config;
-  static absl::optional<Config> SdpToConfig(
-      const SdpAudioFormat& audio_format) {
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format) {
     return T::SdpToConfig(audio_format);
   }
   static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs) {
@@ -48,7 +47,7 @@
   }
   static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
       const Config& config,
-      absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt) {
+      std::optional<AudioCodecPairId> codec_pair_id = std::nullopt) {
     return T::MakeAudioDecoder(config, codec_pair_id);
   }
 };
diff --git a/api/audio_codecs/builtin_audio_encoder_factory.cc b/api/audio_codecs/builtin_audio_encoder_factory.cc
index 864d1a6..8d9c62c 100644
--- a/api/audio_codecs/builtin_audio_encoder_factory.cc
+++ b/api/audio_codecs/builtin_audio_encoder_factory.cc
@@ -11,9 +11,9 @@
 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/L16/audio_encoder_L16.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
@@ -40,8 +40,7 @@
 template <typename T>
 struct NotAdvertised {
   using Config = typename T::Config;
-  static absl::optional<Config> SdpToConfig(
-      const SdpAudioFormat& audio_format) {
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format) {
     return T::SdpToConfig(audio_format);
   }
   static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs) {
@@ -53,7 +52,7 @@
   static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
       const Config& config,
       int payload_type,
-      absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+      std::optional<AudioCodecPairId> codec_pair_id = std::nullopt,
       const FieldTrialsView* field_trials = nullptr) {
     return T::MakeAudioEncoder(config, payload_type, codec_pair_id,
                                field_trials);
diff --git a/api/audio_codecs/g711/BUILD.gn b/api/audio_codecs/g711/BUILD.gn
index df377e2..6c00e04 100644
--- a/api/audio_codecs/g711/BUILD.gn
+++ b/api/audio_codecs/g711/BUILD.gn
@@ -29,7 +29,6 @@
     "../../../rtc_base:stringutils",
     "../../../rtc_base/system:rtc_export",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -48,6 +47,5 @@
     "../../../rtc_base:safe_conversions",
     "../../../rtc_base/system:rtc_export",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
diff --git a/api/audio_codecs/g711/audio_decoder_g711.cc b/api/audio_codecs/g711/audio_decoder_g711.cc
index 28963c5..724e09f 100644
--- a/api/audio_codecs/g711/audio_decoder_g711.cc
+++ b/api/audio_codecs/g711/audio_decoder_g711.cc
@@ -12,10 +12,10 @@
 
 #include <initializer_list>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -26,7 +26,7 @@
 
 namespace webrtc {
 
-absl::optional<AudioDecoderG711::Config> AudioDecoderG711::SdpToConfig(
+std::optional<AudioDecoderG711::Config> AudioDecoderG711::SdpToConfig(
     const SdpAudioFormat& format) {
   const bool is_pcmu = absl::EqualsIgnoreCase(format.name, "PCMU");
   const bool is_pcma = absl::EqualsIgnoreCase(format.name, "PCMA");
@@ -37,11 +37,11 @@
     config.num_channels = rtc::dchecked_cast<int>(format.num_channels);
     if (!config.IsOk()) {
       RTC_DCHECK_NOTREACHED();
-      return absl::nullopt;
+      return std::nullopt;
     }
     return config;
   } else {
-    return absl::nullopt;
+    return std::nullopt;
   }
 }
 
@@ -54,7 +54,7 @@
 
 std::unique_ptr<AudioDecoder> AudioDecoderG711::MakeAudioDecoder(
     const Config& config,
-    absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+    std::optional<AudioCodecPairId> /*codec_pair_id*/,
     const FieldTrialsView* field_trials) {
   if (!config.IsOk()) {
     RTC_DCHECK_NOTREACHED();
diff --git a/api/audio_codecs/g711/audio_decoder_g711.h b/api/audio_codecs/g711/audio_decoder_g711.h
index 0f7a98d..155c13d 100644
--- a/api/audio_codecs/g711/audio_decoder_g711.h
+++ b/api/audio_codecs/g711/audio_decoder_g711.h
@@ -12,9 +12,9 @@
 #define API_AUDIO_CODECS_G711_AUDIO_DECODER_G711_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -36,11 +36,11 @@
     Type type;
     int num_channels;
   };
-  static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
   static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
   static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
       const Config& config,
-      absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+      std::optional<AudioCodecPairId> codec_pair_id = std::nullopt,
       const FieldTrialsView* field_trials = nullptr);
 };
 
diff --git a/api/audio_codecs/g711/audio_encoder_g711.cc b/api/audio_codecs/g711/audio_encoder_g711.cc
index e32aa28..aa00318 100644
--- a/api/audio_codecs/g711/audio_encoder_g711.cc
+++ b/api/audio_codecs/g711/audio_encoder_g711.cc
@@ -15,11 +15,11 @@
 #include <initializer_list>
 #include <map>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -32,7 +32,7 @@
 
 namespace webrtc {
 
-absl::optional<AudioEncoderG711::Config> AudioEncoderG711::SdpToConfig(
+std::optional<AudioEncoderG711::Config> AudioEncoderG711::SdpToConfig(
     const SdpAudioFormat& format) {
   const bool is_pcmu = absl::EqualsIgnoreCase(format.name, "PCMU");
   const bool is_pcma = absl::EqualsIgnoreCase(format.name, "PCMA");
@@ -51,11 +51,11 @@
     }
     if (!config.IsOk()) {
       RTC_DCHECK_NOTREACHED();
-      return absl::nullopt;
+      return std::nullopt;
     }
     return config;
   } else {
-    return absl::nullopt;
+    return std::nullopt;
   }
 }
 
@@ -75,7 +75,7 @@
 std::unique_ptr<AudioEncoder> AudioEncoderG711::MakeAudioEncoder(
     const Config& config,
     int payload_type,
-    absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+    std::optional<AudioCodecPairId> /*codec_pair_id*/,
     const FieldTrialsView* field_trials) {
   if (!config.IsOk()) {
     RTC_DCHECK_NOTREACHED();
diff --git a/api/audio_codecs/g711/audio_encoder_g711.h b/api/audio_codecs/g711/audio_encoder_g711.h
index 4b3eb84..db39a98 100644
--- a/api/audio_codecs/g711/audio_encoder_g711.h
+++ b/api/audio_codecs/g711/audio_encoder_g711.h
@@ -12,9 +12,9 @@
 #define API_AUDIO_CODECS_G711_AUDIO_ENCODER_G711_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -38,14 +38,14 @@
     int num_channels = 1;
     int frame_size_ms = 20;
   };
-  static absl::optional<AudioEncoderG711::Config> SdpToConfig(
+  static std::optional<AudioEncoderG711::Config> SdpToConfig(
       const SdpAudioFormat& audio_format);
   static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
   static AudioCodecInfo QueryAudioEncoder(const Config& config);
   static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
       const Config& config,
       int payload_type,
-      absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+      std::optional<AudioCodecPairId> codec_pair_id = std::nullopt,
       const FieldTrialsView* field_trials = nullptr);
 };
 
diff --git a/api/audio_codecs/g722/BUILD.gn b/api/audio_codecs/g722/BUILD.gn
index 58b6e24..a3ee0d4 100644
--- a/api/audio_codecs/g722/BUILD.gn
+++ b/api/audio_codecs/g722/BUILD.gn
@@ -36,7 +36,6 @@
     "../../../rtc_base:stringutils",
     "../../../rtc_base/system:rtc_export",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -55,6 +54,5 @@
     "../../../rtc_base:safe_conversions",
     "../../../rtc_base/system:rtc_export",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
diff --git a/api/audio_codecs/g722/audio_decoder_g722.cc b/api/audio_codecs/g722/audio_decoder_g722.cc
index b5e5f42..2b8c4f7 100644
--- a/api/audio_codecs/g722/audio_decoder_g722.cc
+++ b/api/audio_codecs/g722/audio_decoder_g722.cc
@@ -11,10 +11,10 @@
 #include "api/audio_codecs/g722/audio_decoder_g722.h"
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -25,14 +25,14 @@
 
 namespace webrtc {
 
-absl::optional<AudioDecoderG722::Config> AudioDecoderG722::SdpToConfig(
+std::optional<AudioDecoderG722::Config> AudioDecoderG722::SdpToConfig(
     const SdpAudioFormat& format) {
   if (absl::EqualsIgnoreCase(format.name, "G722") &&
       format.clockrate_hz == 8000 &&
       (format.num_channels == 1 || format.num_channels == 2)) {
     return Config{rtc::dchecked_cast<int>(format.num_channels)};
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void AudioDecoderG722::AppendSupportedDecoders(
@@ -42,7 +42,7 @@
 
 std::unique_ptr<AudioDecoder> AudioDecoderG722::MakeAudioDecoder(
     Config config,
-    absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+    std::optional<AudioCodecPairId> /*codec_pair_id*/,
     const FieldTrialsView* field_trials) {
   if (!config.IsOk()) {
     RTC_DCHECK_NOTREACHED();
diff --git a/api/audio_codecs/g722/audio_decoder_g722.h b/api/audio_codecs/g722/audio_decoder_g722.h
index 6f7b253..1859866 100644
--- a/api/audio_codecs/g722/audio_decoder_g722.h
+++ b/api/audio_codecs/g722/audio_decoder_g722.h
@@ -12,9 +12,9 @@
 #define API_AUDIO_CODECS_G722_AUDIO_DECODER_G722_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -30,11 +30,11 @@
     bool IsOk() const { return num_channels == 1 || num_channels == 2; }
     int num_channels;
   };
-  static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
   static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
   static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
       Config config,
-      absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+      std::optional<AudioCodecPairId> codec_pair_id = std::nullopt,
       const FieldTrialsView* field_trials = nullptr);
 };
 
diff --git a/api/audio_codecs/g722/audio_encoder_g722.cc b/api/audio_codecs/g722/audio_encoder_g722.cc
index d7a1c89..5ba9598 100644
--- a/api/audio_codecs/g722/audio_encoder_g722.cc
+++ b/api/audio_codecs/g722/audio_encoder_g722.cc
@@ -14,11 +14,11 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -32,11 +32,11 @@
 
 namespace webrtc {
 
-absl::optional<AudioEncoderG722Config> AudioEncoderG722::SdpToConfig(
+std::optional<AudioEncoderG722Config> AudioEncoderG722::SdpToConfig(
     const SdpAudioFormat& format) {
   if (!absl::EqualsIgnoreCase(format.name, "g722") ||
       format.clockrate_hz != 8000) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   AudioEncoderG722Config config;
@@ -51,7 +51,7 @@
   }
   if (!config.IsOk()) {
     RTC_DCHECK_NOTREACHED();
-    return absl::nullopt;
+    return std::nullopt;
   }
   return config;
 }
@@ -73,7 +73,7 @@
 std::unique_ptr<AudioEncoder> AudioEncoderG722::MakeAudioEncoder(
     const AudioEncoderG722Config& config,
     int payload_type,
-    absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+    std::optional<AudioCodecPairId> /*codec_pair_id*/,
     const FieldTrialsView* field_trials) {
   if (!config.IsOk()) {
     RTC_DCHECK_NOTREACHED();
diff --git a/api/audio_codecs/g722/audio_encoder_g722.h b/api/audio_codecs/g722/audio_encoder_g722.h
index 78ceddd..0997d8b 100644
--- a/api/audio_codecs/g722/audio_encoder_g722.h
+++ b/api/audio_codecs/g722/audio_encoder_g722.h
@@ -12,9 +12,9 @@
 #define API_AUDIO_CODECS_G722_AUDIO_ENCODER_G722_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -28,14 +28,14 @@
 // CreateAudioEncoderFactory<...>().
 struct RTC_EXPORT AudioEncoderG722 {
   using Config = AudioEncoderG722Config;
-  static absl::optional<AudioEncoderG722Config> SdpToConfig(
+  static std::optional<AudioEncoderG722Config> SdpToConfig(
       const SdpAudioFormat& audio_format);
   static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
   static AudioCodecInfo QueryAudioEncoder(const AudioEncoderG722Config& config);
   static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
       const AudioEncoderG722Config& config,
       int payload_type,
-      absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+      std::optional<AudioCodecPairId> codec_pair_id = std::nullopt,
       const FieldTrialsView* field_trials = nullptr);
 };
 
diff --git a/api/audio_codecs/ilbc/BUILD.gn b/api/audio_codecs/ilbc/BUILD.gn
index a71867a..8ab719f 100644
--- a/api/audio_codecs/ilbc/BUILD.gn
+++ b/api/audio_codecs/ilbc/BUILD.gn
@@ -34,7 +34,6 @@
     "../../../rtc_base:safe_minmax",
     "../../../rtc_base:stringutils",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -50,6 +49,5 @@
     "../../../api:field_trials_view",
     "../../../modules/audio_coding:ilbc",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
diff --git a/api/audio_codecs/ilbc/audio_decoder_ilbc.cc b/api/audio_codecs/ilbc/audio_decoder_ilbc.cc
index 6b3c0cb..4b1c7de 100644
--- a/api/audio_codecs/ilbc/audio_decoder_ilbc.cc
+++ b/api/audio_codecs/ilbc/audio_decoder_ilbc.cc
@@ -11,10 +11,10 @@
 #include "api/audio_codecs/ilbc/audio_decoder_ilbc.h"
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -23,13 +23,13 @@
 
 namespace webrtc {
 
-absl::optional<AudioDecoderIlbc::Config> AudioDecoderIlbc::SdpToConfig(
+std::optional<AudioDecoderIlbc::Config> AudioDecoderIlbc::SdpToConfig(
     const SdpAudioFormat& format) {
   if (absl::EqualsIgnoreCase(format.name, "ILBC") &&
       format.clockrate_hz == 8000 && format.num_channels == 1) {
     return Config();
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void AudioDecoderIlbc::AppendSupportedDecoders(
@@ -39,7 +39,7 @@
 
 std::unique_ptr<AudioDecoder> AudioDecoderIlbc::MakeAudioDecoder(
     Config config,
-    absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+    std::optional<AudioCodecPairId> /*codec_pair_id*/,
     const FieldTrialsView* field_trials) {
   return std::make_unique<AudioDecoderIlbcImpl>();
 }
diff --git a/api/audio_codecs/ilbc/audio_decoder_ilbc.h b/api/audio_codecs/ilbc/audio_decoder_ilbc.h
index 60566c8..f1a89b9 100644
--- a/api/audio_codecs/ilbc/audio_decoder_ilbc.h
+++ b/api/audio_codecs/ilbc/audio_decoder_ilbc.h
@@ -12,9 +12,9 @@
 #define API_AUDIO_CODECS_ILBC_AUDIO_DECODER_ILBC_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -26,11 +26,11 @@
 // CreateAudioDecoderFactory<...>().
 struct AudioDecoderIlbc {
   struct Config {};  // Empty---no config values needed!
-  static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
   static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
   static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
       Config config,
-      absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+      std::optional<AudioCodecPairId> codec_pair_id = std::nullopt,
       const FieldTrialsView* field_trials = nullptr);
 };
 
diff --git a/api/audio_codecs/ilbc/audio_encoder_ilbc.cc b/api/audio_codecs/ilbc/audio_encoder_ilbc.cc
index 7345591..5fac14b 100644
--- a/api/audio_codecs/ilbc/audio_encoder_ilbc.cc
+++ b/api/audio_codecs/ilbc/audio_encoder_ilbc.cc
@@ -12,12 +12,12 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -46,11 +46,11 @@
 }
 }  // namespace
 
-absl::optional<AudioEncoderIlbcConfig> AudioEncoderIlbc::SdpToConfig(
+std::optional<AudioEncoderIlbcConfig> AudioEncoderIlbc::SdpToConfig(
     const SdpAudioFormat& format) {
   if (!absl::EqualsIgnoreCase(format.name.c_str(), "ILBC") ||
       format.clockrate_hz != 8000 || format.num_channels != 1) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   AudioEncoderIlbcConfig config;
@@ -64,7 +64,7 @@
   }
   if (!config.IsOk()) {
     RTC_DCHECK_NOTREACHED();
-    return absl::nullopt;
+    return std::nullopt;
   }
   return config;
 }
@@ -85,7 +85,7 @@
 std::unique_ptr<AudioEncoder> AudioEncoderIlbc::MakeAudioEncoder(
     const AudioEncoderIlbcConfig& config,
     int payload_type,
-    absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+    std::optional<AudioCodecPairId> /*codec_pair_id*/,
     const FieldTrialsView* field_trials) {
   if (!config.IsOk()) {
     RTC_DCHECK_NOTREACHED();
diff --git a/api/audio_codecs/ilbc/audio_encoder_ilbc.h b/api/audio_codecs/ilbc/audio_encoder_ilbc.h
index a530684..74c75fd 100644
--- a/api/audio_codecs/ilbc/audio_encoder_ilbc.h
+++ b/api/audio_codecs/ilbc/audio_encoder_ilbc.h
@@ -12,9 +12,9 @@
 #define API_AUDIO_CODECS_ILBC_AUDIO_ENCODER_ILBC_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -27,14 +27,14 @@
 // CreateAudioEncoderFactory<...>().
 struct AudioEncoderIlbc {
   using Config = AudioEncoderIlbcConfig;
-  static absl::optional<AudioEncoderIlbcConfig> SdpToConfig(
+  static std::optional<AudioEncoderIlbcConfig> SdpToConfig(
       const SdpAudioFormat& audio_format);
   static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
   static AudioCodecInfo QueryAudioEncoder(const AudioEncoderIlbcConfig& config);
   static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
       const AudioEncoderIlbcConfig& config,
       int payload_type,
-      absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+      std::optional<AudioCodecPairId> codec_pair_id = std::nullopt,
       const FieldTrialsView* field_trials = nullptr);
 };
 
diff --git a/api/audio_codecs/opus/BUILD.gn b/api/audio_codecs/opus/BUILD.gn
index f96256e..29b2999 100644
--- a/api/audio_codecs/opus/BUILD.gn
+++ b/api/audio_codecs/opus/BUILD.gn
@@ -20,10 +20,7 @@
     "audio_encoder_opus_config.cc",
     "audio_encoder_opus_config.h",
   ]
-  deps = [
-    "../../../rtc_base/system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
-  ]
+  deps = [ "../../../rtc_base/system:rtc_export" ]
   defines = []
   if (rtc_opus_variable_complexity) {
     defines += [ "WEBRTC_OPUS_VARIABLE_COMPLEXITY=1" ]
@@ -50,7 +47,6 @@
     "../../../rtc_base:checks",
     "../../../rtc_base/system:rtc_export",
     "../../environment",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -68,7 +64,6 @@
     "../../../rtc_base/system:rtc_export",
     "../../environment",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -83,7 +78,6 @@
     "../../../modules/audio_coding:webrtc_multiopus",
     "../../../rtc_base/system:rtc_export",
     "../opus:audio_encoder_opus_config",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -102,6 +96,5 @@
     "../../../rtc_base/system:rtc_export",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
diff --git a/api/audio_codecs/opus/audio_decoder_multi_channel_opus.cc b/api/audio_codecs/opus/audio_decoder_multi_channel_opus.cc
index 497e212..a9381c0 100644
--- a/api/audio_codecs/opus/audio_decoder_multi_channel_opus.cc
+++ b/api/audio_codecs/opus/audio_decoder_multi_channel_opus.cc
@@ -11,10 +11,10 @@
 #include "api/audio_codecs/opus/audio_decoder_multi_channel_opus.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -24,7 +24,7 @@
 
 namespace webrtc {
 
-absl::optional<AudioDecoderMultiChannelOpusConfig>
+std::optional<AudioDecoderMultiChannelOpusConfig>
 AudioDecoderMultiChannelOpus::SdpToConfig(const SdpAudioFormat& format) {
   return AudioDecoderMultiChannelOpusImpl::SdpToConfig(format);
 }
@@ -68,7 +68,7 @@
 
 std::unique_ptr<AudioDecoder> AudioDecoderMultiChannelOpus::MakeAudioDecoder(
     AudioDecoderMultiChannelOpusConfig config,
-    absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+    std::optional<AudioCodecPairId> /*codec_pair_id*/,
     const FieldTrialsView* field_trials) {
   return AudioDecoderMultiChannelOpusImpl::MakeAudioDecoder(config);
 }
diff --git a/api/audio_codecs/opus/audio_decoder_multi_channel_opus.h b/api/audio_codecs/opus/audio_decoder_multi_channel_opus.h
index eafd6c6..d9fc693 100644
--- a/api/audio_codecs/opus/audio_decoder_multi_channel_opus.h
+++ b/api/audio_codecs/opus/audio_decoder_multi_channel_opus.h
@@ -12,9 +12,9 @@
 #define API_AUDIO_CODECS_OPUS_AUDIO_DECODER_MULTI_CHANNEL_OPUS_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -28,12 +28,12 @@
 // CreateAudioDecoderFactory<...>().
 struct RTC_EXPORT AudioDecoderMultiChannelOpus {
   using Config = AudioDecoderMultiChannelOpusConfig;
-  static absl::optional<AudioDecoderMultiChannelOpusConfig> SdpToConfig(
+  static std::optional<AudioDecoderMultiChannelOpusConfig> SdpToConfig(
       const SdpAudioFormat& audio_format);
   static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
   static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
       AudioDecoderMultiChannelOpusConfig config,
-      absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+      std::optional<AudioCodecPairId> codec_pair_id = std::nullopt,
       const FieldTrialsView* field_trials = nullptr);
 };
 
diff --git a/api/audio_codecs/opus/audio_decoder_opus.cc b/api/audio_codecs/opus/audio_decoder_opus.cc
index c19cffc..4db27a3 100644
--- a/api/audio_codecs/opus/audio_decoder_opus.cc
+++ b/api/audio_codecs/opus/audio_decoder_opus.cc
@@ -12,12 +12,12 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -38,9 +38,9 @@
   return true;
 }
 
-absl::optional<AudioDecoderOpus::Config> AudioDecoderOpus::SdpToConfig(
+std::optional<AudioDecoderOpus::Config> AudioDecoderOpus::SdpToConfig(
     const SdpAudioFormat& format) {
-  const auto num_channels = [&]() -> absl::optional<int> {
+  const auto num_channels = [&]() -> std::optional<int> {
     auto stereo = format.parameters.find("stereo");
     if (stereo != format.parameters.end()) {
       if (stereo->second == "0") {
@@ -48,7 +48,7 @@
       } else if (stereo->second == "1") {
         return 2;
       } else {
-        return absl::nullopt;  // Bad stereo parameter.
+        return std::nullopt;  // Bad stereo parameter.
       }
     }
     return 1;  // Default to mono.
@@ -60,11 +60,11 @@
     config.num_channels = *num_channels;
     if (!config.IsOk()) {
       RTC_DCHECK_NOTREACHED();
-      return absl::nullopt;
+      return std::nullopt;
     }
     return config;
   } else {
-    return absl::nullopt;
+    return std::nullopt;
   }
 }
 
diff --git a/api/audio_codecs/opus/audio_decoder_opus.h b/api/audio_codecs/opus/audio_decoder_opus.h
index c2d5fda..802de98 100644
--- a/api/audio_codecs/opus/audio_decoder_opus.h
+++ b/api/audio_codecs/opus/audio_decoder_opus.h
@@ -12,9 +12,9 @@
 #define API_AUDIO_CODECS_OPUS_AUDIO_DECODER_OPUS_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -31,7 +31,7 @@
     int sample_rate_hz = 48000;
     int num_channels = 1;
   };
-  static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
   static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
 
   static std::unique_ptr<AudioDecoder> MakeAudioDecoder(const Environment& env,
@@ -39,7 +39,7 @@
   static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
       const Environment& env,
       Config config,
-      absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
+      std::optional<AudioCodecPairId> /*codec_pair_id*/) {
     return MakeAudioDecoder(env, config);
   }
 };
diff --git a/api/audio_codecs/opus/audio_encoder_multi_channel_opus.cc b/api/audio_codecs/opus/audio_encoder_multi_channel_opus.cc
index 14f480b..ef0699b 100644
--- a/api/audio_codecs/opus/audio_encoder_multi_channel_opus.cc
+++ b/api/audio_codecs/opus/audio_encoder_multi_channel_opus.cc
@@ -16,7 +16,7 @@
 
 namespace webrtc {
 
-absl::optional<AudioEncoderMultiChannelOpusConfig>
+std::optional<AudioEncoderMultiChannelOpusConfig>
 AudioEncoderMultiChannelOpus::SdpToConfig(const SdpAudioFormat& format) {
   return AudioEncoderMultiChannelOpusImpl::SdpToConfig(format);
 }
@@ -66,7 +66,7 @@
 std::unique_ptr<AudioEncoder> AudioEncoderMultiChannelOpus::MakeAudioEncoder(
     const AudioEncoderMultiChannelOpusConfig& config,
     int payload_type,
-    absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+    std::optional<AudioCodecPairId> /*codec_pair_id*/,
     const FieldTrialsView* field_trials) {
   return AudioEncoderMultiChannelOpusImpl::MakeAudioEncoder(config,
                                                             payload_type);
diff --git a/api/audio_codecs/opus/audio_encoder_multi_channel_opus.h b/api/audio_codecs/opus/audio_encoder_multi_channel_opus.h
index c1c4db3..923e5c0 100644
--- a/api/audio_codecs/opus/audio_encoder_multi_channel_opus.h
+++ b/api/audio_codecs/opus/audio_encoder_multi_channel_opus.h
@@ -12,9 +12,9 @@
 #define API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_MULTI_CHANNEL_OPUS_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -28,13 +28,13 @@
 // CreateAudioEncoderFactory<...>().
 struct RTC_EXPORT AudioEncoderMultiChannelOpus {
   using Config = AudioEncoderMultiChannelOpusConfig;
-  static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
   static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
   static AudioCodecInfo QueryAudioEncoder(const Config& config);
   static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
       const Config& config,
       int payload_type,
-      absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+      std::optional<AudioCodecPairId> codec_pair_id = std::nullopt,
       const FieldTrialsView* field_trials = nullptr);
 };
 
diff --git a/api/audio_codecs/opus/audio_encoder_opus.cc b/api/audio_codecs/opus/audio_encoder_opus.cc
index f099aeb..89033ea 100644
--- a/api/audio_codecs/opus/audio_encoder_opus.cc
+++ b/api/audio_codecs/opus/audio_encoder_opus.cc
@@ -11,9 +11,9 @@
 #include "api/audio_codecs/opus/audio_encoder_opus.h"
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_encoder_factory.h"
@@ -24,7 +24,7 @@
 
 namespace webrtc {
 
-absl::optional<AudioEncoderOpusConfig> AudioEncoderOpus::SdpToConfig(
+std::optional<AudioEncoderOpusConfig> AudioEncoderOpus::SdpToConfig(
     const SdpAudioFormat& format) {
   return AudioEncoderOpusImpl::SdpToConfig(format);
 }
diff --git a/api/audio_codecs/opus/audio_encoder_opus.h b/api/audio_codecs/opus/audio_encoder_opus.h
index d3e769e..1a7a4ca 100644
--- a/api/audio_codecs/opus/audio_encoder_opus.h
+++ b/api/audio_codecs/opus/audio_encoder_opus.h
@@ -12,9 +12,9 @@
 #define API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_OPUS_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_encoder_factory.h"
 #include "api/audio_codecs/audio_format.h"
@@ -28,7 +28,7 @@
 // CreateAudioEncoderFactory<...>().
 struct RTC_EXPORT AudioEncoderOpus {
   using Config = AudioEncoderOpusConfig;
-  static absl::optional<AudioEncoderOpusConfig> SdpToConfig(
+  static std::optional<AudioEncoderOpusConfig> SdpToConfig(
       const SdpAudioFormat& audio_format);
   static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
   static AudioCodecInfo QueryAudioEncoder(const AudioEncoderOpusConfig& config);
diff --git a/api/audio_codecs/opus/audio_encoder_opus_config.h b/api/audio_codecs/opus/audio_encoder_opus_config.h
index d5d7256..1fe5c18 100644
--- a/api/audio_codecs/opus/audio_encoder_opus_config.h
+++ b/api/audio_codecs/opus/audio_encoder_opus_config.h
@@ -13,9 +13,9 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
@@ -43,7 +43,7 @@
 
   // NOTE: This member must always be set.
   // TODO(kwiberg): Turn it into just an int.
-  absl::optional<int> bitrate_bps;
+  std::optional<int> bitrate_bps;
 
   bool fec_enabled;
   bool cbr_enabled;
diff --git a/api/audio_codecs/opus_audio_decoder_factory.cc b/api/audio_codecs/opus_audio_decoder_factory.cc
index cf7bda2..c3d5df4 100644
--- a/api/audio_codecs/opus_audio_decoder_factory.cc
+++ b/api/audio_codecs/opus_audio_decoder_factory.cc
@@ -11,9 +11,9 @@
 #include "api/audio_codecs/opus_audio_decoder_factory.h"
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_decoder_factory.h"
@@ -31,8 +31,7 @@
 template <typename T>
 struct NotAdvertised {
   using Config = typename T::Config;
-  static absl::optional<Config> SdpToConfig(
-      const SdpAudioFormat& audio_format) {
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format) {
     return T::SdpToConfig(audio_format);
   }
   static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs) {
@@ -40,7 +39,7 @@
   }
   static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
       const Config& config,
-      absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt) {
+      std::optional<AudioCodecPairId> codec_pair_id = std::nullopt) {
     return T::MakeAudioDecoder(config, codec_pair_id);
   }
 };
diff --git a/api/audio_codecs/opus_audio_encoder_factory.cc b/api/audio_codecs/opus_audio_encoder_factory.cc
index 8d1d150..164b7a1 100644
--- a/api/audio_codecs/opus_audio_encoder_factory.cc
+++ b/api/audio_codecs/opus_audio_encoder_factory.cc
@@ -11,9 +11,9 @@
 #include "api/audio_codecs/opus_audio_encoder_factory.h"
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_encoder_factory.h"
@@ -31,8 +31,7 @@
 template <typename T>
 struct NotAdvertised {
   using Config = typename T::Config;
-  static absl::optional<Config> SdpToConfig(
-      const SdpAudioFormat& audio_format) {
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format) {
     return T::SdpToConfig(audio_format);
   }
   static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs) {
@@ -44,7 +43,7 @@
   static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
       const Config& config,
       int payload_type,
-      absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+      std::optional<AudioCodecPairId> codec_pair_id = std::nullopt,
       const FieldTrialsView* field_trials = nullptr) {
     return T::MakeAudioEncoder(config, payload_type, codec_pair_id,
                                field_trials);
diff --git a/api/audio_codecs/test/BUILD.gn b/api/audio_codecs/test/BUILD.gn
index 0ed352c..e895884 100644
--- a/api/audio_codecs/test/BUILD.gn
+++ b/api/audio_codecs/test/BUILD.gn
@@ -37,7 +37,6 @@
       "../ilbc:audio_encoder_ilbc",
       "../opus:audio_decoder_opus",
       "../opus:audio_encoder_opus",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
diff --git a/api/audio_codecs/test/audio_decoder_factory_template_unittest.cc b/api/audio_codecs/test/audio_decoder_factory_template_unittest.cc
index 134e0f5..7994836 100644
--- a/api/audio_codecs/test/audio_decoder_factory_template_unittest.cc
+++ b/api/audio_codecs/test/audio_decoder_factory_template_unittest.cc
@@ -11,10 +11,10 @@
 #include "api/audio_codecs/audio_decoder_factory_template.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/L16/audio_decoder_L16.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
@@ -59,13 +59,12 @@
     SdpAudioFormat audio_format;
   };
 
-  static absl::optional<Config> SdpToConfig(
-      const SdpAudioFormat& audio_format) {
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format) {
     if (Params::AudioFormat() == audio_format) {
       Config config = {audio_format};
       return config;
     } else {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
@@ -79,7 +78,7 @@
 
   static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
       const Config&,
-      absl::optional<AudioCodecPairId> /*codec_pair_id*/ = absl::nullopt) {
+      std::optional<AudioCodecPairId> /*codec_pair_id*/ = std::nullopt) {
     auto dec = std::make_unique<testing::StrictMock<MockAudioDecoder>>();
     EXPECT_CALL(*dec, SampleRateHz())
         .WillOnce(::testing::Return(Params::CodecInfo().sample_rate_hz));
@@ -95,8 +94,7 @@
 
   static SdpAudioFormat AudioFormat() { return {"fake", 16'000, 2, {}}; }
 
-  static absl::optional<Config> SdpToConfig(
-      const SdpAudioFormat& audio_format) {
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format) {
     return Config();
   }
 
@@ -114,7 +112,7 @@
 
   static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
       const Config& config,
-      absl::optional<AudioCodecPairId> codec_pair_id) {
+      std::optional<AudioCodecPairId> codec_pair_id) {
     auto decoder = std::make_unique<NiceMock<MockAudioDecoder>>();
     ON_CALL(*decoder, SampleRateHz).WillByDefault(Return(kRateWithoutEnv));
     return decoder;
@@ -123,7 +121,7 @@
   static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
       const Environment& env,
       const Config& config,
-      absl::optional<AudioCodecPairId> codec_pair_id) {
+      std::optional<AudioCodecPairId> codec_pair_id) {
     auto decoder = std::make_unique<NiceMock<MockAudioDecoder>>();
     ON_CALL(*decoder, SampleRateHz).WillByDefault(Return(kRateWithEnv));
     return decoder;
@@ -143,7 +141,7 @@
 struct AudioDecoderApiWithV1Make : BaseAudioDecoderApi {
   static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
       const Config& config,
-      absl::optional<AudioCodecPairId> codec_pair_id) {
+      std::optional<AudioCodecPairId> codec_pair_id) {
     return std::make_unique<NiceMock<MockAudioDecoder>>();
   }
 };
@@ -163,7 +161,7 @@
           audio_decoder_factory_template_impl::AudioDecoderFactoryT<>>());
   EXPECT_THAT(factory->GetSupportedDecoders(), ::testing::IsEmpty());
   EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1}));
-  EXPECT_EQ(nullptr, factory->Create(env, {"bar", 16000, 1}, absl::nullopt));
+  EXPECT_EQ(nullptr, factory->Create(env, {"bar", 16000, 1}, std::nullopt));
 }
 
 TEST(AudioDecoderFactoryTemplateTest, OneDecoderType) {
@@ -174,8 +172,8 @@
                   AudioCodecSpec{{"bogus", 8000, 1}, {8000, 1, 12345}}));
   EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1}));
   EXPECT_TRUE(factory->IsSupportedDecoder({"bogus", 8000, 1}));
-  EXPECT_EQ(nullptr, factory->Create(env, {"bar", 16000, 1}, absl::nullopt));
-  auto dec = factory->Create(env, {"bogus", 8000, 1}, absl::nullopt);
+  EXPECT_EQ(nullptr, factory->Create(env, {"bar", 16000, 1}, std::nullopt));
+  auto dec = factory->Create(env, {"bogus", 8000, 1}, std::nullopt);
   ASSERT_NE(nullptr, dec);
   EXPECT_EQ(8000, dec->SampleRateHz());
 }
@@ -193,13 +191,13 @@
   EXPECT_TRUE(factory->IsSupportedDecoder({"bogus", 8000, 1}));
   EXPECT_TRUE(
       factory->IsSupportedDecoder({"sham", 16000, 2, {{"param", "value"}}}));
-  EXPECT_EQ(nullptr, factory->Create(env, {"bar", 16000, 1}, absl::nullopt));
-  auto dec1 = factory->Create(env, {"bogus", 8000, 1}, absl::nullopt);
+  EXPECT_EQ(nullptr, factory->Create(env, {"bar", 16000, 1}, std::nullopt));
+  auto dec1 = factory->Create(env, {"bogus", 8000, 1}, std::nullopt);
   ASSERT_NE(nullptr, dec1);
   EXPECT_EQ(8000, dec1->SampleRateHz());
-  EXPECT_EQ(nullptr, factory->Create(env, {"sham", 16000, 2}, absl::nullopt));
+  EXPECT_EQ(nullptr, factory->Create(env, {"sham", 16000, 2}, std::nullopt));
   auto dec2 = factory->Create(env, {"sham", 16000, 2, {{"param", "value"}}},
-                              absl::nullopt);
+                              std::nullopt);
   ASSERT_NE(nullptr, dec2);
   EXPECT_EQ(16000, dec2->SampleRateHz());
 }
@@ -214,11 +212,11 @@
   EXPECT_FALSE(factory->IsSupportedDecoder({"G711", 8000, 1}));
   EXPECT_TRUE(factory->IsSupportedDecoder({"PCMU", 8000, 1}));
   EXPECT_TRUE(factory->IsSupportedDecoder({"pcma", 8000, 1}));
-  EXPECT_EQ(nullptr, factory->Create(env, {"pcmu", 16000, 1}, absl::nullopt));
-  auto dec1 = factory->Create(env, {"pcmu", 8000, 1}, absl::nullopt);
+  EXPECT_EQ(nullptr, factory->Create(env, {"pcmu", 16000, 1}, std::nullopt));
+  auto dec1 = factory->Create(env, {"pcmu", 8000, 1}, std::nullopt);
   ASSERT_NE(nullptr, dec1);
   EXPECT_EQ(8000, dec1->SampleRateHz());
-  auto dec2 = factory->Create(env, {"PCMA", 8000, 1}, absl::nullopt);
+  auto dec2 = factory->Create(env, {"PCMA", 8000, 1}, std::nullopt);
   ASSERT_NE(nullptr, dec2);
   EXPECT_EQ(8000, dec2->SampleRateHz());
 }
@@ -231,16 +229,16 @@
                   AudioCodecSpec{{"G722", 8000, 1}, {16000, 1, 64000}}));
   EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1}));
   EXPECT_TRUE(factory->IsSupportedDecoder({"G722", 8000, 1}));
-  EXPECT_EQ(nullptr, factory->Create(env, {"bar", 16000, 1}, absl::nullopt));
-  auto dec1 = factory->Create(env, {"G722", 8000, 1}, absl::nullopt);
+  EXPECT_EQ(nullptr, factory->Create(env, {"bar", 16000, 1}, std::nullopt));
+  auto dec1 = factory->Create(env, {"G722", 8000, 1}, std::nullopt);
   ASSERT_NE(nullptr, dec1);
   EXPECT_EQ(16000, dec1->SampleRateHz());
   EXPECT_EQ(1u, dec1->Channels());
-  auto dec2 = factory->Create(env, {"G722", 8000, 2}, absl::nullopt);
+  auto dec2 = factory->Create(env, {"G722", 8000, 2}, std::nullopt);
   ASSERT_NE(nullptr, dec2);
   EXPECT_EQ(16000, dec2->SampleRateHz());
   EXPECT_EQ(2u, dec2->Channels());
-  auto dec3 = factory->Create(env, {"G722", 8000, 3}, absl::nullopt);
+  auto dec3 = factory->Create(env, {"G722", 8000, 3}, std::nullopt);
   ASSERT_EQ(nullptr, dec3);
 }
 
@@ -252,8 +250,8 @@
                   AudioCodecSpec{{"ILBC", 8000, 1}, {8000, 1, 13300}}));
   EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1}));
   EXPECT_TRUE(factory->IsSupportedDecoder({"ilbc", 8000, 1}));
-  EXPECT_EQ(nullptr, factory->Create(env, {"bar", 8000, 1}, absl::nullopt));
-  auto dec = factory->Create(env, {"ilbc", 8000, 1}, absl::nullopt);
+  EXPECT_EQ(nullptr, factory->Create(env, {"bar", 8000, 1}, std::nullopt));
+  auto dec = factory->Create(env, {"ilbc", 8000, 1}, std::nullopt);
   ASSERT_NE(nullptr, dec);
   EXPECT_EQ(8000, dec->SampleRateHz());
 }
@@ -273,8 +271,8 @@
   EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1}));
   EXPECT_TRUE(factory->IsSupportedDecoder({"L16", 48000, 1}));
   EXPECT_FALSE(factory->IsSupportedDecoder({"L16", 96000, 1}));
-  EXPECT_EQ(nullptr, factory->Create(env, {"L16", 8000, 0}, absl::nullopt));
-  auto dec = factory->Create(env, {"L16", 48000, 2}, absl::nullopt);
+  EXPECT_EQ(nullptr, factory->Create(env, {"L16", 8000, 0}, std::nullopt));
+  auto dec = factory->Create(env, {"L16", 48000, 2}, std::nullopt);
   ASSERT_NE(nullptr, dec);
   EXPECT_EQ(48000, dec->SampleRateHz());
 }
@@ -291,8 +289,8 @@
               ::testing::ElementsAre(AudioCodecSpec{opus_format, opus_info}));
   EXPECT_FALSE(factory->IsSupportedDecoder({"opus", 48000, 1}));
   EXPECT_TRUE(factory->IsSupportedDecoder({"opus", 48000, 2}));
-  EXPECT_EQ(nullptr, factory->Create(env, {"bar", 16000, 1}, absl::nullopt));
-  auto dec = factory->Create(env, {"opus", 48000, 2}, absl::nullopt);
+  EXPECT_EQ(nullptr, factory->Create(env, {"bar", 16000, 1}, std::nullopt));
+  auto dec = factory->Create(env, {"opus", 48000, 2}, std::nullopt);
   ASSERT_NE(nullptr, dec);
   EXPECT_EQ(48000, dec->SampleRateHz());
 }
diff --git a/api/audio_codecs/test/audio_encoder_factory_template_unittest.cc b/api/audio_codecs/test/audio_encoder_factory_template_unittest.cc
index 92277f5..ec60d91 100644
--- a/api/audio_codecs/test/audio_encoder_factory_template_unittest.cc
+++ b/api/audio_codecs/test/audio_encoder_factory_template_unittest.cc
@@ -11,10 +11,10 @@
 #include "api/audio_codecs/audio_encoder_factory_template.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/L16/audio_encoder_L16.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
@@ -59,13 +59,12 @@
     SdpAudioFormat audio_format;
   };
 
-  static absl::optional<Config> SdpToConfig(
-      const SdpAudioFormat& audio_format) {
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format) {
     if (Params::AudioFormat() == audio_format) {
       Config config = {audio_format};
       return config;
     } else {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
@@ -80,7 +79,7 @@
   static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
       const Config&,
       int payload_type,
-      absl::optional<AudioCodecPairId> /*codec_pair_id*/ = absl::nullopt) {
+      std::optional<AudioCodecPairId> /*codec_pair_id*/ = std::nullopt) {
     auto enc = std::make_unique<testing::StrictMock<MockAudioEncoder>>();
     EXPECT_CALL(*enc, SampleRateHz())
         .WillOnce(::testing::Return(Params::CodecInfo().sample_rate_hz));
@@ -101,8 +100,7 @@
   static SdpAudioFormat AudioFormat() { return {"fake", 16'000, 2, {}}; }
   static AudioCodecInfo CodecInfo() { return {16'000, 2, 23456}; }
 
-  static absl::optional<Config> SdpToConfig(
-      const SdpAudioFormat& audio_format) {
+  static std::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format) {
     return Config();
   }
 
@@ -117,7 +115,7 @@
   static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
       const Config&,
       int payload_type,
-      absl::optional<AudioCodecPairId> codec_pair_id) {
+      std::optional<AudioCodecPairId> codec_pair_id) {
     auto encoder = std::make_unique<NiceMock<MockAudioEncoder>>();
     ON_CALL(*encoder, SampleRateHz).WillByDefault(Return(kV1SameRate));
     return encoder;
@@ -139,7 +137,7 @@
   static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
       const Config&,
       int payload_type,
-      absl::optional<AudioCodecPairId> codec_pair_id) {
+      std::optional<AudioCodecPairId> codec_pair_id) {
     auto encoder = std::make_unique<NiceMock<MockAudioEncoder>>();
     ON_CALL(*encoder, SampleRateHz).WillByDefault(Return(kV1SameRate));
     return encoder;
@@ -190,7 +188,7 @@
       rtc::make_ref_counted<
           audio_encoder_factory_template_impl::AudioEncoderFactoryT<>>());
   EXPECT_THAT(factory->GetSupportedEncoders(), ::testing::IsEmpty());
-  EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
+  EXPECT_EQ(std::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
 
   EXPECT_THAT(factory->Create(env, {"bar", 16000, 1}, {}), IsNull());
 }
@@ -201,7 +199,7 @@
   EXPECT_THAT(factory->GetSupportedEncoders(),
               ::testing::ElementsAre(
                   AudioCodecSpec{{"bogus", 8000, 1}, {8000, 1, 12345}}));
-  EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
+  EXPECT_EQ(std::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
   EXPECT_EQ(AudioCodecInfo(8000, 1, 12345),
             factory->QueryAudioEncoder({"bogus", 8000, 1}));
 
@@ -219,7 +217,7 @@
                   AudioCodecSpec{{"bogus", 8000, 1}, {8000, 1, 12345}},
                   AudioCodecSpec{{"sham", 16000, 2, {{"param", "value"}}},
                                  {16000, 2, 23456}}));
-  EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
+  EXPECT_EQ(std::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
   EXPECT_EQ(AudioCodecInfo(8000, 1, 12345),
             factory->QueryAudioEncoder({"bogus", 8000, 1}));
   EXPECT_EQ(
@@ -242,7 +240,7 @@
               ::testing::ElementsAre(
                   AudioCodecSpec{{"PCMU", 8000, 1}, {8000, 1, 64000}},
                   AudioCodecSpec{{"PCMA", 8000, 1}, {8000, 1, 64000}}));
-  EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"PCMA", 16000, 1}));
+  EXPECT_EQ(std::nullopt, factory->QueryAudioEncoder({"PCMA", 16000, 1}));
   EXPECT_EQ(AudioCodecInfo(8000, 1, 64000),
             factory->QueryAudioEncoder({"PCMA", 8000, 1}));
 
@@ -259,7 +257,7 @@
   EXPECT_THAT(factory->GetSupportedEncoders(),
               ::testing::ElementsAre(
                   AudioCodecSpec{{"G722", 8000, 1}, {16000, 1, 64000}}));
-  EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
+  EXPECT_EQ(std::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
   EXPECT_EQ(AudioCodecInfo(16000, 1, 64000),
             factory->QueryAudioEncoder({"G722", 8000, 1}));
 
@@ -274,7 +272,7 @@
   EXPECT_THAT(factory->GetSupportedEncoders(),
               ::testing::ElementsAre(
                   AudioCodecSpec{{"ILBC", 8000, 1}, {8000, 1, 13333}}));
-  EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
+  EXPECT_EQ(std::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
   EXPECT_EQ(AudioCodecInfo(8000, 1, 13333),
             factory->QueryAudioEncoder({"ilbc", 8000, 1}));
 
@@ -295,7 +293,7 @@
           AudioCodecSpec{{"L16", 8000, 2}, {8000, 2, 8000 * 16 * 2}},
           AudioCodecSpec{{"L16", 16000, 2}, {16000, 2, 16000 * 16 * 2}},
           AudioCodecSpec{{"L16", 32000, 2}, {32000, 2, 32000 * 16 * 2}}));
-  EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"L16", 8000, 0}));
+  EXPECT_EQ(std::nullopt, factory->QueryAudioEncoder({"L16", 8000, 0}));
   EXPECT_EQ(AudioCodecInfo(48000, 1, 48000 * 16),
             factory->QueryAudioEncoder({"L16", 48000, 1}));
 
@@ -315,7 +313,7 @@
       ::testing::ElementsAre(AudioCodecSpec{
           {"opus", 48000, 2, {{"minptime", "10"}, {"useinbandfec", "1"}}},
           info}));
-  EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
+  EXPECT_EQ(std::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
   EXPECT_EQ(
       info,
       factory->QueryAudioEncoder(
diff --git a/api/audio_options.cc b/api/audio_options.cc
index a3f2b6e..f5baf06 100644
--- a/api/audio_options.cc
+++ b/api/audio_options.cc
@@ -19,14 +19,14 @@
 template <class T>
 void ToStringIfSet(rtc::SimpleStringBuilder* result,
                    const char* key,
-                   const absl::optional<T>& val) {
+                   const std::optional<T>& val) {
   if (val) {
     (*result) << key << ": " << *val << ", ";
   }
 }
 
 template <typename T>
-void SetFrom(absl::optional<T>* s, const absl::optional<T>& o) {
+void SetFrom(std::optional<T>* s, const std::optional<T>& o) {
   if (o) {
     *s = o;
   }
diff --git a/api/audio_options.h b/api/audio_options.h
index 2162471..b16808e 100644
--- a/api/audio_options.h
+++ b/api/audio_options.h
@@ -11,9 +11,9 @@
 #ifndef API_AUDIO_OPTIONS_H_
 #define API_AUDIO_OPTIONS_H_
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "rtc_base/system/rtc_export.h"
 
 namespace cricket {
@@ -34,38 +34,38 @@
 
   // Audio processing that attempts to filter away the output signal from
   // later inbound pickup.
-  absl::optional<bool> echo_cancellation;
+  std::optional<bool> echo_cancellation;
 #if defined(WEBRTC_IOS)
   // Forces software echo cancellation on iOS. This is a temporary workaround
   // (until Apple fixes the bug) for a device with non-functioning AEC. May
   // improve performance on that particular device, but will cause unpredictable
   // behavior in all other cases. See http://bugs.webrtc.org/8682.
-  absl::optional<bool> ios_force_software_aec_HACK;
+  std::optional<bool> ios_force_software_aec_HACK;
 #endif
   // Audio processing to adjust the sensitivity of the local mic dynamically.
-  absl::optional<bool> auto_gain_control;
+  std::optional<bool> auto_gain_control;
   // Audio processing to filter out background noise.
-  absl::optional<bool> noise_suppression;
+  std::optional<bool> noise_suppression;
   // Audio processing to remove background noise of lower frequencies.
-  absl::optional<bool> highpass_filter;
+  std::optional<bool> highpass_filter;
   // Audio processing to swap the left and right channels.
-  absl::optional<bool> stereo_swapping;
+  std::optional<bool> stereo_swapping;
   // Audio receiver jitter buffer (NetEq) max capacity in number of packets.
-  absl::optional<int> audio_jitter_buffer_max_packets;
+  std::optional<int> audio_jitter_buffer_max_packets;
   // Audio receiver jitter buffer (NetEq) fast accelerate mode.
-  absl::optional<bool> audio_jitter_buffer_fast_accelerate;
+  std::optional<bool> audio_jitter_buffer_fast_accelerate;
   // Audio receiver jitter buffer (NetEq) minimum target delay in milliseconds.
-  absl::optional<int> audio_jitter_buffer_min_delay_ms;
+  std::optional<int> audio_jitter_buffer_min_delay_ms;
   // Enable audio network adaptor.
   // TODO(webrtc:11717): Remove this API in favor of adaptivePtime in
   // RtpEncodingParameters.
-  absl::optional<bool> audio_network_adaptor;
+  std::optional<bool> audio_network_adaptor;
   // Config string for audio network adaptor.
-  absl::optional<std::string> audio_network_adaptor_config;
+  std::optional<std::string> audio_network_adaptor_config;
   // Pre-initialize the ADM for recording when starting to send. Default to
   // true.
   // TODO(webrtc:13566): Remove this option. See issue for details.
-  absl::optional<bool> init_recording_on_send;
+  std::optional<bool> init_recording_on_send;
 };
 
 }  // namespace cricket
diff --git a/api/data_channel_interface.cc b/api/data_channel_interface.cc
index 8e04009..966faf24 100644
--- a/api/data_channel_interface.cc
+++ b/api/data_channel_interface.cc
@@ -27,12 +27,12 @@
   return 0;
 }
 
-absl::optional<int> DataChannelInterface::maxRetransmitsOpt() const {
-  return absl::nullopt;
+std::optional<int> DataChannelInterface::maxRetransmitsOpt() const {
+  return std::nullopt;
 }
 
-absl::optional<int> DataChannelInterface::maxPacketLifeTime() const {
-  return absl::nullopt;
+std::optional<int> DataChannelInterface::maxPacketLifeTime() const {
+  return std::nullopt;
 }
 
 std::string DataChannelInterface::protocol() const {
diff --git a/api/data_channel_interface.h b/api/data_channel_interface.h
index 300012e..23936b1 100644
--- a/api/data_channel_interface.h
+++ b/api/data_channel_interface.h
@@ -17,10 +17,10 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 
 #include "absl/functional/any_invocable.h"
-#include "absl/types/optional.h"
 #include "api/priority.h"
 #include "api/ref_count.h"
 #include "api/rtc_error.h"
@@ -31,7 +31,7 @@
 namespace webrtc {
 
 // C++ version of: https://www.w3.org/TR/webrtc/#idl-def-rtcdatachannelinit
-// TODO(deadbeef): Use absl::optional for the "-1 if unset" things.
+// TODO(deadbeef): Use std::optional for the "-1 if unset" things.
 struct DataChannelInit {
   // Deprecated. Reliability is assumed, and channel will be unreliable if
   // maxRetransmitTime or MaxRetransmits is set.
@@ -46,13 +46,13 @@
   // Cannot be set along with `maxRetransmits`.
   // This is called `maxPacketLifeTime` in the WebRTC JS API.
   // Negative values are ignored, and positive values are clamped to [0-65535]
-  absl::optional<int> maxRetransmitTime;
+  std::optional<int> maxRetransmitTime;
 
   // The max number of retransmissions.
   //
   // Cannot be set along with `maxRetransmitTime`.
   // Negative values are ignored, and positive values are clamped to [0-65535]
-  absl::optional<int> maxRetransmits;
+  std::optional<int> maxRetransmits;
 
   // This is set by the application and opaque to the WebRTC implementation.
   std::string protocol;
@@ -67,7 +67,7 @@
   int id = -1;
 
   // https://w3c.github.io/webrtc-priority/#new-rtcdatachannelinit-member
-  absl::optional<PriorityValue> priority;
+  std::optional<PriorityValue> priority;
 };
 
 // At the JavaScript level, data can be passed in as a string or a blob, so
@@ -163,8 +163,8 @@
   // TODO(hta): Deprecate and remove the following two functions.
   virtual uint16_t maxRetransmitTime() const;
   virtual uint16_t maxRetransmits() const;
-  virtual absl::optional<int> maxRetransmitsOpt() const;
-  virtual absl::optional<int> maxPacketLifeTime() const;
+  virtual std::optional<int> maxRetransmitsOpt() const;
+  virtual std::optional<int> maxPacketLifeTime() const;
   virtual std::string protocol() const;
   virtual bool negotiated() const;
 
diff --git a/api/dtls_transport_interface.cc b/api/dtls_transport_interface.cc
index 8133525..7a560cf 100644
--- a/api/dtls_transport_interface.cc
+++ b/api/dtls_transport_interface.cc
@@ -11,9 +11,9 @@
 #include "api/dtls_transport_interface.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "rtc_base/ssl_certificate.h"
 
 namespace webrtc {
@@ -26,10 +26,10 @@
 
 DtlsTransportInformation::DtlsTransportInformation(
     DtlsTransportState state,
-    absl::optional<DtlsTransportTlsRole> role,
-    absl::optional<int> tls_version,
-    absl::optional<int> ssl_cipher_suite,
-    absl::optional<int> srtp_cipher_suite,
+    std::optional<DtlsTransportTlsRole> role,
+    std::optional<int> tls_version,
+    std::optional<int> ssl_cipher_suite,
+    std::optional<int> srtp_cipher_suite,
     std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates)
     : state_(state),
       role_(role),
@@ -41,12 +41,12 @@
 // Deprecated version
 DtlsTransportInformation::DtlsTransportInformation(
     DtlsTransportState state,
-    absl::optional<int> tls_version,
-    absl::optional<int> ssl_cipher_suite,
-    absl::optional<int> srtp_cipher_suite,
+    std::optional<int> tls_version,
+    std::optional<int> ssl_cipher_suite,
+    std::optional<int> srtp_cipher_suite,
     std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates)
     : state_(state),
-      role_(absl::nullopt),
+      role_(std::nullopt),
       tls_version_(tls_version),
       ssl_cipher_suite_(ssl_cipher_suite),
       srtp_cipher_suite_(srtp_cipher_suite),
diff --git a/api/dtls_transport_interface.h b/api/dtls_transport_interface.h
index 66ae4d4..0f78221 100644
--- a/api/dtls_transport_interface.h
+++ b/api/dtls_transport_interface.h
@@ -12,9 +12,9 @@
 #define API_DTLS_TRANSPORT_INTERFACE_H_
 
 #include <memory>
+#include <optional>
 
 #include "absl/base/attributes.h"
-#include "absl/types/optional.h"
 #include "api/ice_transport_interface.h"
 #include "api/ref_count.h"
 #include "api/rtc_error.h"
@@ -49,17 +49,17 @@
   explicit DtlsTransportInformation(DtlsTransportState state);
   DtlsTransportInformation(
       DtlsTransportState state,
-      absl::optional<DtlsTransportTlsRole> role,
-      absl::optional<int> tls_version,
-      absl::optional<int> ssl_cipher_suite,
-      absl::optional<int> srtp_cipher_suite,
+      std::optional<DtlsTransportTlsRole> role,
+      std::optional<int> tls_version,
+      std::optional<int> ssl_cipher_suite,
+      std::optional<int> srtp_cipher_suite,
       std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates);
   ABSL_DEPRECATED("Use version with role parameter")
   DtlsTransportInformation(
       DtlsTransportState state,
-      absl::optional<int> tls_version,
-      absl::optional<int> ssl_cipher_suite,
-      absl::optional<int> srtp_cipher_suite,
+      std::optional<int> tls_version,
+      std::optional<int> ssl_cipher_suite,
+      std::optional<int> srtp_cipher_suite,
       std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates);
 
   // Copy and assign
@@ -71,10 +71,10 @@
       default;
 
   DtlsTransportState state() const { return state_; }
-  absl::optional<DtlsTransportTlsRole> role() const { return role_; }
-  absl::optional<int> tls_version() const { return tls_version_; }
-  absl::optional<int> ssl_cipher_suite() const { return ssl_cipher_suite_; }
-  absl::optional<int> srtp_cipher_suite() const { return srtp_cipher_suite_; }
+  std::optional<DtlsTransportTlsRole> role() const { return role_; }
+  std::optional<int> tls_version() const { return tls_version_; }
+  std::optional<int> ssl_cipher_suite() const { return ssl_cipher_suite_; }
+  std::optional<int> srtp_cipher_suite() const { return srtp_cipher_suite_; }
   // The accessor returns a temporary pointer, it does not release ownership.
   const rtc::SSLCertChain* remote_ssl_certificates() const {
     return remote_ssl_certificates_.get();
@@ -82,10 +82,10 @@
 
  private:
   DtlsTransportState state_;
-  absl::optional<DtlsTransportTlsRole> role_;
-  absl::optional<int> tls_version_;
-  absl::optional<int> ssl_cipher_suite_;
-  absl::optional<int> srtp_cipher_suite_;
+  std::optional<DtlsTransportTlsRole> role_;
+  std::optional<int> tls_version_;
+  std::optional<int> ssl_cipher_suite_;
+  std::optional<int> srtp_cipher_suite_;
   std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates_;
 };
 
diff --git a/api/environment/BUILD.gn b/api/environment/BUILD.gn
index 10d008f..4db7c46 100644
--- a/api/environment/BUILD.gn
+++ b/api/environment/BUILD.gn
@@ -58,7 +58,6 @@
       "../units:timestamp",
       "//third_party/abseil-cpp/absl/functional:any_invocable",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
diff --git a/api/environment/environment_unittest.cc b/api/environment/environment_unittest.cc
index 17bc668..bcadb49 100644
--- a/api/environment/environment_unittest.cc
+++ b/api/environment/environment_unittest.cc
@@ -11,13 +11,13 @@
 #include "api/environment/environment.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/functional/any_invocable.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment_factory.h"
 #include "api/field_trials_view.h"
 #include "api/rtc_event_log/rtc_event.h"
@@ -168,10 +168,10 @@
       /*on_destroyed=*/[&] { utility_destroyed = true; });
 
   // Wrap Environment into optional to have explicit control when it is deleted.
-  absl::optional<Environment> env = CreateEnvironment(std::move(field_trials));
+  std::optional<Environment> env = CreateEnvironment(std::move(field_trials));
 
   EXPECT_FALSE(utility_destroyed);
-  env = absl::nullopt;
+  env = std::nullopt;
   EXPECT_TRUE(utility_destroyed);
 }
 
@@ -180,13 +180,13 @@
   auto field_trials = std::make_unique<FakeFieldTrials>(
       /*on_destroyed=*/[&] { utility_destroyed = true; });
 
-  absl::optional<Environment> env1 = CreateEnvironment(std::move(field_trials));
-  absl::optional<Environment> env2 = env1;
+  std::optional<Environment> env1 = CreateEnvironment(std::move(field_trials));
+  std::optional<Environment> env2 = env1;
 
   EXPECT_FALSE(utility_destroyed);
-  env1 = absl::nullopt;
+  env1 = std::nullopt;
   EXPECT_FALSE(utility_destroyed);
-  env2 = absl::nullopt;
+  env2 = std::nullopt;
   EXPECT_TRUE(utility_destroyed);
 }
 
@@ -234,27 +234,27 @@
 TEST(EnvironmentTest, KeepsOwnershipsWhenCreateNewEnvironmentFromExistingOne) {
   bool utility1_destroyed = false;
   bool utility2_destroyed = false;
-  absl::optional<Environment> env1 =
+  std::optional<Environment> env1 =
       CreateEnvironment(std::make_unique<FakeTaskQueueFactory>(
           /*on_destroyed=*/[&] { utility1_destroyed = true; }));
 
-  absl::optional<EnvironmentFactory> factory = EnvironmentFactory(*env1);
+  std::optional<EnvironmentFactory> factory = EnvironmentFactory(*env1);
 
   // Destroy env1, check utility1 it was using is still alive.
-  env1 = absl::nullopt;
+  env1 = std::nullopt;
   EXPECT_FALSE(utility1_destroyed);
 
   factory->Set(std::make_unique<FakeFieldTrials>(
       /*on_destroyed=*/[&] { utility2_destroyed = true; }));
-  absl::optional<Environment> env2 = factory->Create();
+  std::optional<Environment> env2 = factory->Create();
 
   // Destroy the factory, check all utilities used by env2 are alive.
-  factory = absl::nullopt;
+  factory = std::nullopt;
   EXPECT_FALSE(utility1_destroyed);
   EXPECT_FALSE(utility2_destroyed);
 
   // Once last Environment object is deleted, utilties should be deleted too.
-  env2 = absl::nullopt;
+  env2 = std::nullopt;
   EXPECT_TRUE(utility1_destroyed);
   EXPECT_TRUE(utility2_destroyed);
 }
@@ -266,11 +266,11 @@
   auto task_queue_factory = std::make_unique<FakeTaskQueueFactory>(
       /*on_destroyed=*/[&] { destroyed.push_back("task_queue_factory"); });
 
-  absl::optional<Environment> env =
+  std::optional<Environment> env =
       CreateEnvironment(std::move(field_trials), std::move(task_queue_factory));
 
   ASSERT_THAT(destroyed, IsEmpty());
-  env = absl::nullopt;
+  env = std::nullopt;
   EXPECT_THAT(destroyed, ElementsAre("task_queue_factory", "field_trials"));
 }
 
diff --git a/api/frame_transformer_interface.h b/api/frame_transformer_interface.h
index b1f5426..6959445 100644
--- a/api/frame_transformer_interface.h
+++ b/api/frame_transformer_interface.h
@@ -13,9 +13,9 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/ref_count.h"
 #include "api/scoped_refptr.h"
@@ -56,8 +56,8 @@
 
   // TODO(https://bugs.webrtc.org/14878): Change this to pure virtual after it
   // is implemented everywhere.
-  virtual absl::optional<Timestamp> GetCaptureTimeIdentifier() const {
-    return absl::nullopt;
+  virtual std::optional<Timestamp> GetCaptureTimeIdentifier() const {
+    return std::nullopt;
   }
 
   enum class Direction {
@@ -91,9 +91,9 @@
 
   virtual rtc::ArrayView<const uint32_t> GetContributingSources() const = 0;
 
-  virtual const absl::optional<uint16_t> SequenceNumber() const = 0;
+  virtual const std::optional<uint16_t> SequenceNumber() const = 0;
 
-  virtual absl::optional<uint64_t> AbsoluteCaptureTimestamp() const = 0;
+  virtual std::optional<uint64_t> AbsoluteCaptureTimestamp() const = 0;
 
   enum class FrameType { kEmptyFrame, kAudioFrameSpeech, kAudioFrameCN };
 
@@ -104,11 +104,11 @@
   // Audio level in -dBov. Values range from 0 to 127, representing 0 to -127
   // dBov. 127 represents digital silence. Only present on remote frames if
   // the audio level header extension was included.
-  virtual absl::optional<uint8_t> AudioLevel() const = 0;
+  virtual std::optional<uint8_t> AudioLevel() const = 0;
 
   // Timestamp at which the packet has been first seen on the network interface.
   // Only defined for received audio packet.
-  virtual absl::optional<Timestamp> ReceiveTime() const = 0;
+  virtual std::optional<Timestamp> ReceiveTime() const = 0;
 };
 
 // Objects implement this interface to be notified with the transformed frame.
diff --git a/api/jsep.cc b/api/jsep.cc
index 5fdc890..21781d9 100644
--- a/api/jsep.cc
+++ b/api/jsep.cc
@@ -40,7 +40,7 @@
   return "";
 }
 
-absl::optional<SdpType> SdpTypeFromString(const std::string& type_str) {
+std::optional<SdpType> SdpTypeFromString(const std::string& type_str) {
   if (type_str == SessionDescriptionInterface::kOffer) {
     return SdpType::kOffer;
   } else if (type_str == SessionDescriptionInterface::kPrAnswer) {
@@ -50,7 +50,7 @@
   } else if (type_str == SessionDescriptionInterface::kRollback) {
     return SdpType::kRollback;
   } else {
-    return absl::nullopt;
+    return std::nullopt;
   }
 }
 
diff --git a/api/jsep.h b/api/jsep.h
index 2578a28..d8fb27c 100644
--- a/api/jsep.h
+++ b/api/jsep.h
@@ -23,10 +23,10 @@
 #include <stddef.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/ref_count.h"
 #include "api/rtc_error.h"
 #include "rtc_base/system/rtc_export.h"
@@ -117,7 +117,7 @@
 // Returns the SdpType from its string form. The string form can be one of the
 // constants defined in SessionDescriptionInterface. Passing in any other string
 // results in nullopt.
-RTC_EXPORT absl::optional<SdpType> SdpTypeFromString(
+RTC_EXPORT std::optional<SdpType> SdpTypeFromString(
     const std::string& type_str);
 
 // Class representation of an SDP session description.
diff --git a/api/media_stream_interface.h b/api/media_stream_interface.h
index 1597b8d..9547d4a 100644
--- a/api/media_stream_interface.h
+++ b/api/media_stream_interface.h
@@ -19,10 +19,10 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_processing_statistics.h"
 #include "api/audio_options.h"
 #include "api/ref_count.h"
@@ -131,7 +131,7 @@
   // depending on video codec.
   // TODO(perkj): Remove this once denoising is done by the source, and not by
   // the encoder.
-  virtual absl::optional<bool> needs_denoising() const = 0;
+  virtual std::optional<bool> needs_denoising() const = 0;
 
   // Returns false if no stats are available, e.g, for a remote source, or a
   // source which has not seen its first frame yet.
@@ -217,7 +217,7 @@
                       int sample_rate,
                       size_t number_of_channels,
                       size_t number_of_frames,
-                      absl::optional<int64_t> absolute_capture_timestamp_ms) {
+                      std::optional<int64_t> absolute_capture_timestamp_ms) {
     // TODO(bugs.webrtc.org/10739): Deprecate the old OnData and make this one
     // pure virtual.
     return OnData(audio_data, bits_per_sample, sample_rate, number_of_channels,
diff --git a/api/neteq/BUILD.gn b/api/neteq/BUILD.gn
index 7cda234..cdc44fc 100644
--- a/api/neteq/BUILD.gn
+++ b/api/neteq/BUILD.gn
@@ -25,7 +25,6 @@
     "../audio_codecs:audio_codecs_api",
     "../environment",
     "../units:timestamp",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -57,7 +56,6 @@
     ":neteq_api",
     ":tick_timer",
     "../environment",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/api/neteq/neteq.h b/api/neteq/neteq.h
index f9ee3b6..faa5624 100644
--- a/api/neteq/neteq.h
+++ b/api/neteq/neteq.h
@@ -15,10 +15,10 @@
 #include <stdint.h>
 
 #include <map>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_format.h"
@@ -136,7 +136,7 @@
     bool enable_fast_accelerate = false;
     bool enable_muted_state = false;
     bool enable_rtx_handling = false;
-    absl::optional<AudioCodecPairId> codec_pair_id;
+    std::optional<AudioCodecPairId> codec_pair_id;
     bool for_test_no_time_stretching = false;  // Use only for testing.
   };
 
@@ -223,7 +223,7 @@
       AudioFrame* audio_frame,
       bool* muted = nullptr,
       int* current_sample_rate_hz = nullptr,
-      absl::optional<Operation> action_override = absl::nullopt) = 0;
+      std::optional<Operation> action_override = std::nullopt) = 0;
 
   // Replaces the current set of decoders with the given one.
   virtual void SetCodecs(const std::map<int, SdpAudioFormat>& codecs) = 0;
@@ -289,7 +289,7 @@
 
   // Returns the RTP timestamp for the last sample delivered by GetAudio().
   // The return value will be empty if no valid timestamp is available.
-  virtual absl::optional<uint32_t> GetPlayoutTimestamp() const = 0;
+  virtual std::optional<uint32_t> GetPlayoutTimestamp() const = 0;
 
   // Returns the sample rate in Hz of the audio produced in the last GetAudio
   // call. If GetAudio has not been called yet, the configured sample rate
@@ -299,14 +299,14 @@
   // Returns the decoder info for the given payload type. Returns empty if no
   // such payload type was registered.
   [[deprecated(
-      "Use GetCurrentDecoderFormat")]] virtual absl::optional<DecoderFormat>
+      "Use GetCurrentDecoderFormat")]] virtual std::optional<DecoderFormat>
   GetDecoderFormat(int payload_type) const {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Returns info for the most recently used decoder.
-  virtual absl::optional<DecoderFormat> GetCurrentDecoderFormat() const {
-    return absl::nullopt;
+  virtual std::optional<DecoderFormat> GetCurrentDecoderFormat() const {
+    return std::nullopt;
   }
 
   // Flushes both the packet buffer and the sync buffer.
diff --git a/api/neteq/neteq_controller.h b/api/neteq/neteq_controller.h
index 27ec218..f764417 100644
--- a/api/neteq/neteq_controller.h
+++ b/api/neteq/neteq_controller.h
@@ -15,8 +15,8 @@
 #include <cstdint>
 #include <functional>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/neteq/neteq.h"
 #include "api/neteq/tick_timer.h"
 
@@ -86,7 +86,7 @@
     uint32_t target_timestamp;
     int16_t expand_mutefactor;
     size_t last_packet_samples;
-    absl::optional<PacketInfo> next_packet;
+    std::optional<PacketInfo> next_packet;
     NetEq::Mode last_mode;
     bool play_dtmf;
     size_t generated_noise_samples;
@@ -161,9 +161,9 @@
 
   // Notify the NetEqController that a packet has arrived. Returns the relative
   // arrival delay, if it can be computed.
-  virtual absl::optional<int> PacketArrived(int fs_hz,
-                                            bool should_update_stats,
-                                            const PacketArrivedInfo& info) = 0;
+  virtual std::optional<int> PacketArrived(int fs_hz,
+                                           bool should_update_stats,
+                                           const PacketArrivedInfo& info) = 0;
 
   // Notify the NetEqController that we are currently in muted state.
   // TODO(bugs.webrtc.org/14270): Make pure virtual when downstream is updated.
diff --git a/api/peer_connection_interface.h b/api/peer_connection_interface.h
index 46b9133..8e2893a 100644
--- a/api/peer_connection_interface.h
+++ b/api/peer_connection_interface.h
@@ -73,12 +73,12 @@
 
 #include <functional>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/base/attributes.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/adaptation/resource.h"
 #include "api/async_dns_resolver.h"
 #include "api/audio/audio_device.h"
@@ -433,7 +433,7 @@
     // The below fields correspond to constraints from the deprecated
     // constraints interface for constructing a PeerConnection.
     //
-    // absl::optional fields can be "missing", in which case the implementation
+    // std::optional fields can be "missing", in which case the implementation
     // default will be used.
     //////////////////////////////////////////////////////////////////////////
 
@@ -457,7 +457,7 @@
     // Minimum bitrate at which screencast video tracks will be encoded at.
     // This means adding padding bits up to this bitrate, which can help
     // when switching from a static scene to one with motion.
-    absl::optional<int> screencast_min_bitrate;
+    std::optional<int> screencast_min_bitrate;
 
     /////////////////////////////////////////////////
     // The below fields are not part of the standard.
@@ -581,28 +581,28 @@
     // 3) ice_check_min_interval defines the minimal interval (equivalently the
     // maximum rate) that overrides the above two intervals when either of them
     // is less.
-    absl::optional<int> ice_check_interval_strong_connectivity;
-    absl::optional<int> ice_check_interval_weak_connectivity;
-    absl::optional<int> ice_check_min_interval;
+    std::optional<int> ice_check_interval_strong_connectivity;
+    std::optional<int> ice_check_interval_weak_connectivity;
+    std::optional<int> ice_check_min_interval;
 
     // The min time period for which a candidate pair must wait for response to
     // connectivity checks before it becomes unwritable. This parameter
     // overrides the default value in the ICE implementation if set.
-    absl::optional<int> ice_unwritable_timeout;
+    std::optional<int> ice_unwritable_timeout;
 
     // The min number of connectivity checks that a candidate pair must sent
     // without receiving response before it becomes unwritable. This parameter
     // overrides the default value in the ICE implementation if set.
-    absl::optional<int> ice_unwritable_min_checks;
+    std::optional<int> ice_unwritable_min_checks;
 
     // The min time period for which a candidate pair must wait for response to
     // connectivity checks it becomes inactive. This parameter overrides the
     // default value in the ICE implementation if set.
-    absl::optional<int> ice_inactive_timeout;
+    std::optional<int> ice_inactive_timeout;
 
     // The interval in milliseconds at which STUN candidates will resend STUN
     // binding requests to keep NAT bindings open.
-    absl::optional<int> stun_candidate_keepalive_interval;
+    std::optional<int> stun_candidate_keepalive_interval;
 
     // Optional TurnCustomizer.
     // With this class one can modify outgoing TURN messages.
@@ -614,7 +614,7 @@
     // A candidate pair on a preferred network has a higher precedence in ICE
     // than one on an un-preferred network, regardless of priority or network
     // cost.
-    absl::optional<rtc::AdapterType> network_preference;
+    std::optional<rtc::AdapterType> network_preference;
 
     // Configure the SDP semantics used by this PeerConnection. By default, this
     // is Unified Plan which is compliant to the WebRTC 1.0 specification. It is
@@ -648,7 +648,7 @@
     // Defines advanced optional cryptographic settings related to SRTP and
     // frame encryption for native WebRTC. Setting this will overwrite any
     // settings set in PeerConnectionFactory (which is deprecated).
-    absl::optional<CryptoOptions> crypto_options;
+    std::optional<CryptoOptions> crypto_options;
 
     // Configure if we should include the SDP attribute extmap-allow-mixed in
     // our offer on session level.
@@ -665,11 +665,11 @@
 
     // The delay before doing a usage histogram report for long-lived
     // PeerConnections. Used for testing only.
-    absl::optional<int> report_usage_pattern_delay_ms;
+    std::optional<int> report_usage_pattern_delay_ms;
 
     // The ping interval (ms) when the connection is stable and writable. This
     // parameter overrides the default value in the ICE implementation if set.
-    absl::optional<int> stable_writable_connection_ping_interval_ms;
+    std::optional<int> stable_writable_connection_ping_interval_ms;
 
     // Whether this PeerConnection will avoid VPNs (kAvoidVpn), prefer VPNs
     // (kPreferVpn), only work over VPN (kOnlyUseVpn) or only work over non-VPN
@@ -685,7 +685,7 @@
     PortAllocatorConfig port_allocator_config;
 
     // The burst interval of the pacer, see TaskQueuePacedSender constructor.
-    absl::optional<TimeDelta> pacer_burst_interval;
+    std::optional<TimeDelta> pacer_burst_interval;
 
     //
     // Don't forget to update operator== if adding something.
@@ -1187,7 +1187,7 @@
 
   // Returns the current state of canTrickleIceCandidates per
   // https://w3c.github.io/webrtc-pc/#attributes-1
-  virtual absl::optional<bool> can_trickle_ice_candidates() = 0;
+  virtual std::optional<bool> can_trickle_ice_candidates() = 0;
 
   // When a resource is overused, the PeerConnection will try to reduce the load
   // on the sysem, for example by reducing the resolution or frame rate of
diff --git a/api/rtc_error.h b/api/rtc_error.h
index 8579ff6..9de3b1c 100644
--- a/api/rtc_error.h
+++ b/api/rtc_error.h
@@ -13,11 +13,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <utility>  // For std::move.
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/system/rtc_export.h"
@@ -137,7 +137,7 @@
 
   RTCErrorDetailType error_detail() const { return error_detail_; }
   void set_error_detail(RTCErrorDetailType detail) { error_detail_ = detail; }
-  absl::optional<uint16_t> sctp_cause_code() const { return sctp_cause_code_; }
+  std::optional<uint16_t> sctp_cause_code() const { return sctp_cause_code_; }
   void set_sctp_cause_code(uint16_t cause_code) {
     sctp_cause_code_ = cause_code;
   }
@@ -150,7 +150,7 @@
   RTCErrorType type_ = RTCErrorType::NONE;
   std::string message_;
   RTCErrorDetailType error_detail_ = RTCErrorDetailType::NONE;
-  absl::optional<uint16_t> sctp_cause_code_;
+  std::optional<uint16_t> sctp_cause_code_;
 };
 
 // Outputs the error as a friendly string. Update this method when adding a new
@@ -309,7 +309,7 @@
 
  private:
   RTCError error_;
-  absl::optional<T> value_;
+  std::optional<T> value_;
 };
 
 }  // namespace webrtc
diff --git a/api/rtp_headers.h b/api/rtp_headers.h
index 129ab5f..6ba3292 100644
--- a/api/rtp_headers.h
+++ b/api/rtp_headers.h
@@ -14,9 +14,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/units/timestamp.h"
 #include "api/video/color_space.h"
 #include "api/video/video_content_type.h"
@@ -75,7 +75,7 @@
   // system’s NTP clock:
   //
   //   Capture NTP Clock = Sender NTP Clock + Capture Clock Offset
-  absl::optional<int64_t> estimated_capture_clock_offset;
+  std::optional<int64_t> estimated_capture_clock_offset;
 };
 
 // The audio level extension is used to indicate the voice activity and the
@@ -131,16 +131,16 @@
   int32_t transmissionTimeOffset;
   bool hasAbsoluteSendTime;
   uint32_t absoluteSendTime;
-  absl::optional<AbsoluteCaptureTime> absolute_capture_time;
+  std::optional<AbsoluteCaptureTime> absolute_capture_time;
   bool hasTransportSequenceNumber;
   uint16_t transportSequenceNumber;
-  absl::optional<FeedbackRequest> feedback_request;
+  std::optional<FeedbackRequest> feedback_request;
 
   // Audio Level includes both level in dBov and voiced/unvoiced bit. See:
   // https://tools.ietf.org/html/rfc6464#section-3
-  absl::optional<AudioLevel> audio_level() const { return audio_level_; }
+  std::optional<AudioLevel> audio_level() const { return audio_level_; }
 
-  void set_audio_level(absl::optional<AudioLevel> audio_level) {
+  void set_audio_level(std::optional<AudioLevel> audio_level) {
     audio_level_ = audio_level;
   }
 
@@ -150,7 +150,7 @@
   bool hasVideoRotation;
   VideoRotation videoRotation;
 
-  // TODO(ilnik): Refactor this and one above to be absl::optional() and remove
+  // TODO(ilnik): Refactor this and one above to be std::optional() and remove
   // a corresponding bool flag.
   bool hasVideoContentType;
   VideoContentType videoContentType;
@@ -169,10 +169,10 @@
   // https://tools.ietf.org/html/rfc8843
   std::string mid;
 
-  absl::optional<ColorSpace> color_space;
+  std::optional<ColorSpace> color_space;
 
  private:
-  absl::optional<AudioLevel> audio_level_;
+  std::optional<AudioLevel> audio_level_;
 };
 
 enum { kRtpCsrcSize = 15 };  // RFC 3550 page 13
diff --git a/api/rtp_packet_info.h b/api/rtp_packet_info.h
index 8df12a3..8e8236d 100644
--- a/api/rtp_packet_info.h
+++ b/api/rtp_packet_info.h
@@ -12,10 +12,10 @@
 #define API_RTP_PACKET_INFO_H_
 
 #include <cstdint>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/rtp_headers.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -56,26 +56,26 @@
   Timestamp receive_time() const { return receive_time_; }
   void set_receive_time(Timestamp value) { receive_time_ = value; }
 
-  absl::optional<uint8_t> audio_level() const { return audio_level_; }
-  RtpPacketInfo& set_audio_level(absl::optional<uint8_t> value) {
+  std::optional<uint8_t> audio_level() const { return audio_level_; }
+  RtpPacketInfo& set_audio_level(std::optional<uint8_t> value) {
     audio_level_ = value;
     return *this;
   }
 
-  const absl::optional<AbsoluteCaptureTime>& absolute_capture_time() const {
+  const std::optional<AbsoluteCaptureTime>& absolute_capture_time() const {
     return absolute_capture_time_;
   }
   RtpPacketInfo& set_absolute_capture_time(
-      const absl::optional<AbsoluteCaptureTime>& value) {
+      const std::optional<AbsoluteCaptureTime>& value) {
     absolute_capture_time_ = value;
     return *this;
   }
 
-  const absl::optional<TimeDelta>& local_capture_clock_offset() const {
+  const std::optional<TimeDelta>& local_capture_clock_offset() const {
     return local_capture_clock_offset_;
   }
   RtpPacketInfo& set_local_capture_clock_offset(
-      absl::optional<TimeDelta> value) {
+      std::optional<TimeDelta> value) {
     local_capture_clock_offset_ = value;
     return *this;
   }
@@ -92,18 +92,18 @@
 
   // Fields from the Audio Level header extension:
   // https://tools.ietf.org/html/rfc6464#section-3
-  absl::optional<uint8_t> audio_level_;
+  std::optional<uint8_t> audio_level_;
 
   // Fields from the Absolute Capture Time header extension:
   // http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time
-  absl::optional<AbsoluteCaptureTime> absolute_capture_time_;
+  std::optional<AbsoluteCaptureTime> absolute_capture_time_;
 
   // Clock offset between the local clock and the capturer's clock.
   // Do not confuse with `AbsoluteCaptureTime::estimated_capture_clock_offset`
   // which instead represents the clock offset between a remote sender and the
   // capturer. The following holds:
   //   Capture's NTP Clock = Local NTP Clock + Local-Capture Clock Offset
-  absl::optional<TimeDelta> local_capture_clock_offset_;
+  std::optional<TimeDelta> local_capture_clock_offset_;
 };
 
 bool operator==(const RtpPacketInfo& lhs, const RtpPacketInfo& rhs);
diff --git a/api/rtp_packet_info_unittest.cc b/api/rtp_packet_info_unittest.cc
index 49ed337..9aea11d 100644
--- a/api/rtp_packet_info_unittest.cc
+++ b/api/rtp_packet_info_unittest.cc
@@ -11,9 +11,9 @@
 #include "api/rtp_packet_info.h"
 
 #include <cstdint>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/rtp_headers.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -134,7 +134,7 @@
 }
 
 TEST(RtpPacketInfoTest, AudioLevel) {
-  constexpr absl::optional<uint8_t> kValue = 31;
+  constexpr std::optional<uint8_t> kValue = 31;
 
   RtpPacketInfo lhs;
   RtpPacketInfo rhs;
@@ -163,7 +163,7 @@
 }
 
 TEST(RtpPacketInfoTest, AbsoluteCaptureTime) {
-  constexpr absl::optional<AbsoluteCaptureTime> kValue = AbsoluteCaptureTime{
+  constexpr std::optional<AbsoluteCaptureTime> kValue = AbsoluteCaptureTime{
       .absolute_capture_timestamp = 12, .estimated_capture_clock_offset = 34};
 
   RtpPacketInfo lhs;
@@ -213,7 +213,7 @@
   EXPECT_FALSE(lhs != rhs);
 
   rhs = RtpPacketInfo();
-  EXPECT_EQ(rhs.local_capture_clock_offset(), absl::nullopt);
+  EXPECT_EQ(rhs.local_capture_clock_offset(), std::nullopt);
 
   rhs = RtpPacketInfo(/*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/{},
                       /*receive_time=*/Timestamp::Zero());
diff --git a/api/rtp_parameters.h b/api/rtp_parameters.h
index 70d7686..b393c3c 100644
--- a/api/rtp_parameters.h
+++ b/api/rtp_parameters.h
@@ -14,12 +14,12 @@
 #include <stdint.h>
 
 #include <map>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/container/inlined_vector.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/media_types.h"
 #include "api/priority.h"
 #include "api/rtp_transceiver_direction.h"
@@ -109,7 +109,7 @@
   // 1. It's an enum instead of a string.
   // 2. Generic NACK feedback is represented by a GENERIC_NACK message type,
   //    rather than an unset "parameter" value.
-  absl::optional<RtcpFeedbackMessageType> message_type;
+  std::optional<RtcpFeedbackMessageType> message_type;
 
   // Constructors for convenience.
   RtcpFeedback();
@@ -139,14 +139,14 @@
   cricket::MediaType kind = cricket::MEDIA_TYPE_AUDIO;
 
   // If unset, the implementation default is used.
-  absl::optional<int> clock_rate;
+  std::optional<int> clock_rate;
 
   // The number of audio channels used. Unset for video codecs. If unset for
   // audio, the implementation default is used.
   // TODO(deadbeef): The "implementation default" part isn't fully implemented.
   // Only defaults to 1, even though some codecs (such as opus) should really
   // default to 2.
-  absl::optional<int> num_channels;
+  std::optional<int> num_channels;
 
   // Feedback mechanisms to be used for this codec.
   // TODO(deadbeef): Not implemented with PeerConnection senders/receivers.
@@ -180,7 +180,7 @@
 
   // Default payload type for this codec. Mainly needed for codecs that have
   // statically assigned payload types.
-  absl::optional<int> preferred_payload_type;
+  std::optional<int> preferred_payload_type;
 
   // List of scalability modes supported by the video codec.
   absl::InlinedVector<ScalabilityMode, kScalabilityModeCount> scalability_modes;
@@ -209,7 +209,7 @@
   std::string uri;
 
   // Preferred value of ID that goes in the packet.
-  absl::optional<int> preferred_id;
+  std::optional<int> preferred_id;
 
   // If true, it's preferred that the value in the header is encrypted.
   // TODO(deadbeef): Not implemented.
@@ -397,7 +397,7 @@
 struct RTC_EXPORT RtpFecParameters {
   // If unset, a value is chosen by the implementation.
   // Works just like RtpEncodingParameters::ssrc.
-  absl::optional<uint32_t> ssrc;
+  std::optional<uint32_t> ssrc;
 
   FecMechanism mechanism = FecMechanism::RED;
 
@@ -417,7 +417,7 @@
 struct RTC_EXPORT RtpRtxParameters {
   // If unset, a value is chosen by the implementation.
   // Works just like RtpEncodingParameters::ssrc.
-  absl::optional<uint32_t> ssrc;
+  std::optional<uint32_t> ssrc;
 
   // Constructors for convenience.
   RtpRtxParameters();
@@ -440,7 +440,7 @@
   // may change due to an SSRC conflict, in which case the conflict is handled
   // internally without any event. Another way of looking at this is that an
   // unset SSRC acts as a "wildcard" SSRC.
-  absl::optional<uint32_t> ssrc;
+  std::optional<uint32_t> ssrc;
 
   // The relative bitrate priority of this encoding. Currently this is
   // implemented for the entire rtp sender by using the value of the first
@@ -475,24 +475,24 @@
   // bandwidth for the entire bandwidth estimator (audio and video). This is
   // just always how "b=AS" was handled, but it's not correct and should be
   // fixed.
-  absl::optional<int> max_bitrate_bps;
+  std::optional<int> max_bitrate_bps;
 
   // Specifies the minimum bitrate in bps for video.
-  absl::optional<int> min_bitrate_bps;
+  std::optional<int> min_bitrate_bps;
 
   // Specifies the maximum framerate in fps for video.
-  absl::optional<double> max_framerate;
+  std::optional<double> max_framerate;
 
   // Specifies the number of temporal layers for video (if the feature is
   // supported by the codec implementation).
   // Screencast support is experimental.
-  absl::optional<int> num_temporal_layers;
+  std::optional<int> num_temporal_layers;
 
   // For video, scale the resolution down by this factor.
-  absl::optional<double> scale_resolution_down_by;
+  std::optional<double> scale_resolution_down_by;
 
   // https://w3c.github.io/webrtc-svc/#rtcrtpencodingparameters
-  absl::optional<std::string> scalability_mode;
+  std::optional<std::string> scalability_mode;
 
   // Requested encode resolution.
   //
@@ -510,7 +510,7 @@
   //
   // It is an error to set both `requested_resolution` and
   // `scale_resolution_down_by`.
-  absl::optional<Resolution> requested_resolution;
+  std::optional<Resolution> requested_resolution;
 
   // For an RtpSender, set to true to cause this encoding to be encoded and
   // sent, and false for it not to be encoded and sent. This allows control
@@ -530,7 +530,7 @@
   bool adaptive_ptime = false;
 
   // Allow changing the used codec for this encoding.
-  absl::optional<RtpCodec> codec;
+  std::optional<RtpCodec> codec;
 
   bool operator==(const RtpEncodingParameters& o) const {
     return ssrc == o.ssrc && bitrate_priority == o.bitrate_priority &&
@@ -597,7 +597,7 @@
   // The SSRC to be used in the "SSRC of packet sender" field. If not set, one
   // will be chosen by the implementation.
   // TODO(deadbeef): Not implemented.
-  absl::optional<uint32_t> ssrc;
+  std::optional<uint32_t> ssrc;
 
   // The Canonical Name (CNAME) used by RTCP (e.g. in SDES messages).
   //
@@ -653,7 +653,7 @@
   // When bandwidth is constrained and the RtpSender needs to choose between
   // degrading resolution or degrading framerate, degradationPreference
   // indicates which is preferred. Only for video tracks.
-  absl::optional<DegradationPreference> degradation_preference;
+  std::optional<DegradationPreference> degradation_preference;
 
   bool operator==(const RtpParameters& o) const {
     return mid == o.mid && codecs == o.codecs &&
diff --git a/api/rtp_receiver_interface.h b/api/rtp_receiver_interface.h
index b1b36b5..f97ed53 100644
--- a/api/rtp_receiver_interface.h
+++ b/api/rtp_receiver_interface.h
@@ -14,11 +14,11 @@
 #ifndef API_RTP_RECEIVER_INTERFACE_H_
 #define API_RTP_RECEIVER_INTERFACE_H_
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/crypto/frame_decryptor_interface.h"
 #include "api/dtls_transport_interface.h"
 #include "api/frame_transformer_interface.h"
@@ -91,7 +91,7 @@
   // positive value including 0.0 measured in seconds. `nullopt` means default
   // value must be used.
   virtual void SetJitterBufferMinimumDelay(
-      absl::optional<double> delay_seconds) = 0;
+      std::optional<double> delay_seconds) = 0;
 
   // TODO(zhihuang): Remove the default implementation once the subclasses
   // implement this. Currently, the only relevant subclass is the
diff --git a/api/rtp_sender_interface.h b/api/rtp_sender_interface.h
index 7d92c42..aa2eb6f 100644
--- a/api/rtp_sender_interface.h
+++ b/api/rtp_sender_interface.h
@@ -53,7 +53,7 @@
 
   // Returns primary SSRC used by this sender for sending media.
   // Returns 0 if not yet determined.
-  // TODO(deadbeef): Change to absl::optional.
+  // TODO(deadbeef): Change to std::optional.
   // TODO(deadbeef): Remove? With GetParameters this should be redundant.
   virtual uint32_t ssrc() const = 0;
 
diff --git a/api/rtp_transceiver_interface.cc b/api/rtp_transceiver_interface.cc
index 7267b28..5f16767 100644
--- a/api/rtp_transceiver_interface.cc
+++ b/api/rtp_transceiver_interface.cc
@@ -20,9 +20,9 @@
 
 RtpTransceiverInit::~RtpTransceiverInit() = default;
 
-absl::optional<RtpTransceiverDirection>
+std::optional<RtpTransceiverDirection>
 RtpTransceiverInterface::fired_direction() const {
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool RtpTransceiverInterface::stopping() const {
diff --git a/api/rtp_transceiver_interface.h b/api/rtp_transceiver_interface.h
index 555566d..2d0bf29 100644
--- a/api/rtp_transceiver_interface.h
+++ b/api/rtp_transceiver_interface.h
@@ -11,11 +11,11 @@
 #ifndef API_RTP_TRANSCEIVER_INTERFACE_H_
 #define API_RTP_TRANSCEIVER_INTERFACE_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/base/attributes.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/media_types.h"
 #include "api/ref_count.h"
@@ -69,7 +69,7 @@
   // remote descriptions. Before negotiation is complete, the mid value may be
   // null. After rollbacks, the value may change from a non-null value to null.
   // https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-mid
-  virtual absl::optional<std::string> mid() const = 0;
+  virtual std::optional<std::string> mid() const = 0;
 
   // The sender attribute exposes the RtpSender corresponding to the RTP media
   // that may be sent with the transceiver's mid. The sender is always present,
@@ -119,14 +119,14 @@
   // for this transceiver. If this transceiver has never been represented in an
   // offer/answer exchange, or if the transceiver is stopped, the value is null.
   // https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-currentdirection
-  virtual absl::optional<RtpTransceiverDirection> current_direction() const = 0;
+  virtual std::optional<RtpTransceiverDirection> current_direction() const = 0;
 
   // An internal slot designating for which direction the relevant
   // PeerConnection events have been fired. This is to ensure that events like
   // OnAddTrack only get fired once even if the same session description is
   // applied again.
   // Exposed in the public interface for use by Chromium.
-  virtual absl::optional<RtpTransceiverDirection> fired_direction() const;
+  virtual std::optional<RtpTransceiverDirection> fired_direction() const;
 
   // Initiates a stop of the transceiver.
   // The stop is complete when stopped() returns true.
diff --git a/api/sctp_transport_interface.cc b/api/sctp_transport_interface.cc
index 8a0a866..8bd279c 100644
--- a/api/sctp_transport_interface.cc
+++ b/api/sctp_transport_interface.cc
@@ -20,8 +20,8 @@
 SctpTransportInformation::SctpTransportInformation(
     SctpTransportState state,
     rtc::scoped_refptr<DtlsTransportInterface> dtls_transport,
-    absl::optional<double> max_message_size,
-    absl::optional<int> max_channels)
+    std::optional<double> max_message_size,
+    std::optional<int> max_channels)
     : state_(state),
       dtls_transport_(std::move(dtls_transport)),
       max_message_size_(max_message_size),
diff --git a/api/sctp_transport_interface.h b/api/sctp_transport_interface.h
index 25c2ba0..173f3ef 100644
--- a/api/sctp_transport_interface.h
+++ b/api/sctp_transport_interface.h
@@ -11,7 +11,8 @@
 #ifndef API_SCTP_TRANSPORT_INTERFACE_H_
 #define API_SCTP_TRANSPORT_INTERFACE_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/dtls_transport_interface.h"
 #include "api/ref_count.h"
 #include "api/scoped_refptr.h"
@@ -41,22 +42,22 @@
   SctpTransportInformation(
       SctpTransportState state,
       rtc::scoped_refptr<DtlsTransportInterface> dtls_transport,
-      absl::optional<double> max_message_size,
-      absl::optional<int> max_channels);
+      std::optional<double> max_message_size,
+      std::optional<int> max_channels);
   ~SctpTransportInformation();
   // The DTLS transport that supports this SCTP transport.
   rtc::scoped_refptr<DtlsTransportInterface> dtls_transport() const {
     return dtls_transport_;
   }
   SctpTransportState state() const { return state_; }
-  absl::optional<double> MaxMessageSize() const { return max_message_size_; }
-  absl::optional<int> MaxChannels() const { return max_channels_; }
+  std::optional<double> MaxMessageSize() const { return max_message_size_; }
+  std::optional<int> MaxChannels() const { return max_channels_; }
 
  private:
   SctpTransportState state_ = SctpTransportState::kNew;
   rtc::scoped_refptr<DtlsTransportInterface> dtls_transport_;
-  absl::optional<double> max_message_size_;
-  absl::optional<int> max_channels_;
+  std::optional<double> max_message_size_;
+  std::optional<int> max_channels_;
 };
 
 class SctpTransportObserverInterface {
diff --git a/api/stats/attribute.h b/api/stats/attribute.h
index 36500db..b5dd8d5 100644
--- a/api/stats/attribute.h
+++ b/api/stats/attribute.h
@@ -13,10 +13,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/system/rtc_export.h"
@@ -24,30 +24,30 @@
 namespace webrtc {
 
 // A light-weight wrapper of an RTCStats attribute, i.e. an individual metric of
-// type absl::optional<T>.
+// type std::optional<T>.
 class RTC_EXPORT Attribute {
  public:
   // All supported attribute types.
-  typedef absl::variant<const absl::optional<bool>*,
-                        const absl::optional<int32_t>*,
-                        const absl::optional<uint32_t>*,
-                        const absl::optional<int64_t>*,
-                        const absl::optional<uint64_t>*,
-                        const absl::optional<double>*,
-                        const absl::optional<std::string>*,
-                        const absl::optional<std::vector<bool>>*,
-                        const absl::optional<std::vector<int32_t>>*,
-                        const absl::optional<std::vector<uint32_t>>*,
-                        const absl::optional<std::vector<int64_t>>*,
-                        const absl::optional<std::vector<uint64_t>>*,
-                        const absl::optional<std::vector<double>>*,
-                        const absl::optional<std::vector<std::string>>*,
-                        const absl::optional<std::map<std::string, uint64_t>>*,
-                        const absl::optional<std::map<std::string, double>>*>
+  typedef absl::variant<const std::optional<bool>*,
+                        const std::optional<int32_t>*,
+                        const std::optional<uint32_t>*,
+                        const std::optional<int64_t>*,
+                        const std::optional<uint64_t>*,
+                        const std::optional<double>*,
+                        const std::optional<std::string>*,
+                        const std::optional<std::vector<bool>>*,
+                        const std::optional<std::vector<int32_t>>*,
+                        const std::optional<std::vector<uint32_t>>*,
+                        const std::optional<std::vector<int64_t>>*,
+                        const std::optional<std::vector<uint64_t>>*,
+                        const std::optional<std::vector<double>>*,
+                        const std::optional<std::vector<std::string>>*,
+                        const std::optional<std::map<std::string, uint64_t>>*,
+                        const std::optional<std::map<std::string, double>>*>
       StatVariant;
 
   template <typename T>
-  Attribute(const char* name, const absl::optional<T>* attribute)
+  Attribute(const char* name, const std::optional<T>* attribute)
       : name_(name), attribute_(attribute) {}
 
   const char* name() const;
@@ -56,18 +56,18 @@
   bool has_value() const;
   template <typename T>
   bool holds_alternative() const {
-    return absl::holds_alternative<const absl::optional<T>*>(attribute_);
+    return absl::holds_alternative<const std::optional<T>*>(attribute_);
   }
   template <typename T>
-  const absl::optional<T>& as_optional() const {
+  const std::optional<T>& as_optional() const {
     RTC_CHECK(holds_alternative<T>());
-    return *absl::get<const absl::optional<T>*>(attribute_);
+    return *absl::get<const std::optional<T>*>(attribute_);
   }
   template <typename T>
   const T& get() const {
     RTC_CHECK(holds_alternative<T>());
     RTC_CHECK(has_value());
-    return absl::get<const absl::optional<T>*>(attribute_)->value();
+    return absl::get<const std::optional<T>*>(attribute_)->value();
   }
 
   bool is_sequence() const;
diff --git a/api/stats/rtc_stats.h b/api/stats/rtc_stats.h
index 74e7fc4..e1f3bb1 100644
--- a/api/stats/rtc_stats.h
+++ b/api/stats/rtc_stats.h
@@ -16,11 +16,11 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/stats/attribute.h"
 #include "api/units/timestamp.h"
 #include "rtc_base/checks.h"
@@ -39,7 +39,7 @@
 // Use the `WEBRTC_RTCSTATS_IMPL` macro when implementing subclasses, see macro
 // for details.
 //
-// Derived classes list their dictionary attributes, absl::optional<T>, as
+// Derived classes list their dictionary attributes, std::optional<T>, as
 // public fields, allowing the following:
 //
 // RTCFooStats foo("fooId", Timestamp::Micros(GetCurrentTime()));
@@ -73,13 +73,12 @@
   // metrics as viewed via the Attribute wrapper.
   std::vector<Attribute> Attributes() const;
   template <typename T>
-  Attribute GetAttribute(const absl::optional<T>& stat) const {
+  Attribute GetAttribute(const std::optional<T>& stat) const {
     for (const auto& attribute : Attributes()) {
       if (!attribute.holds_alternative<T>()) {
         continue;
       }
-      if (absl::get<const absl::optional<T>*>(attribute.as_variant()) ==
-          &stat) {
+      if (absl::get<const std::optional<T>*>(attribute.as_variant()) == &stat) {
         return attribute;
       }
     }
@@ -136,8 +135,8 @@
 //
 //     RTCFooStats(const std::string& id, Timestamp timestamp);
 //
-//     absl::optional<int32_t> foo;
-//     absl::optional<int32_t> bar;
+//     std::optional<int32_t> foo;
+//     std::optional<int32_t> bar;
 //   };
 //
 // rtcfoostats.cc:
diff --git a/api/stats/rtcstats_objects.h b/api/stats/rtcstats_objects.h
index 9f51f56..0645ee6 100644
--- a/api/stats/rtcstats_objects.h
+++ b/api/stats/rtcstats_objects.h
@@ -15,10 +15,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/stats/rtc_stats.h"
 #include "rtc_base/system/rtc_export.h"
 
@@ -31,10 +31,10 @@
   RTCCertificateStats(std::string id, Timestamp timestamp);
   ~RTCCertificateStats() override;
 
-  absl::optional<std::string> fingerprint;
-  absl::optional<std::string> fingerprint_algorithm;
-  absl::optional<std::string> base64_certificate;
-  absl::optional<std::string> issuer_certificate_id;
+  std::optional<std::string> fingerprint;
+  std::optional<std::string> fingerprint_algorithm;
+  std::optional<std::string> base64_certificate;
+  std::optional<std::string> issuer_certificate_id;
 };
 
 // https://w3c.github.io/webrtc-stats/#codec-dict*
@@ -44,12 +44,12 @@
   RTCCodecStats(std::string id, Timestamp timestamp);
   ~RTCCodecStats() override;
 
-  absl::optional<std::string> transport_id;
-  absl::optional<uint32_t> payload_type;
-  absl::optional<std::string> mime_type;
-  absl::optional<uint32_t> clock_rate;
-  absl::optional<uint32_t> channels;
-  absl::optional<std::string> sdp_fmtp_line;
+  std::optional<std::string> transport_id;
+  std::optional<uint32_t> payload_type;
+  std::optional<std::string> mime_type;
+  std::optional<uint32_t> clock_rate;
+  std::optional<uint32_t> channels;
+  std::optional<std::string> sdp_fmtp_line;
 };
 
 // https://w3c.github.io/webrtc-stats/#dcstats-dict*
@@ -59,14 +59,14 @@
   RTCDataChannelStats(std::string id, Timestamp timestamp);
   ~RTCDataChannelStats() override;
 
-  absl::optional<std::string> label;
-  absl::optional<std::string> protocol;
-  absl::optional<int32_t> data_channel_identifier;
-  absl::optional<std::string> state;
-  absl::optional<uint32_t> messages_sent;
-  absl::optional<uint64_t> bytes_sent;
-  absl::optional<uint32_t> messages_received;
-  absl::optional<uint64_t> bytes_received;
+  std::optional<std::string> label;
+  std::optional<std::string> protocol;
+  std::optional<int32_t> data_channel_identifier;
+  std::optional<std::string> state;
+  std::optional<uint32_t> messages_sent;
+  std::optional<uint64_t> bytes_sent;
+  std::optional<uint32_t> messages_received;
+  std::optional<uint64_t> bytes_received;
 };
 
 // https://w3c.github.io/webrtc-stats/#candidatepair-dict*
@@ -76,35 +76,35 @@
   RTCIceCandidatePairStats(std::string id, Timestamp timestamp);
   ~RTCIceCandidatePairStats() override;
 
-  absl::optional<std::string> transport_id;
-  absl::optional<std::string> local_candidate_id;
-  absl::optional<std::string> remote_candidate_id;
-  absl::optional<std::string> state;
+  std::optional<std::string> transport_id;
+  std::optional<std::string> local_candidate_id;
+  std::optional<std::string> remote_candidate_id;
+  std::optional<std::string> state;
   // Obsolete: priority
-  absl::optional<uint64_t> priority;
-  absl::optional<bool> nominated;
+  std::optional<uint64_t> priority;
+  std::optional<bool> nominated;
   // `writable` does not exist in the spec and old comments suggest it used to
   // exist but was incorrectly implemented.
   // TODO(https://crbug.com/webrtc/14171): Standardize and/or modify
   // implementation.
-  absl::optional<bool> writable;
-  absl::optional<uint64_t> packets_sent;
-  absl::optional<uint64_t> packets_received;
-  absl::optional<uint64_t> bytes_sent;
-  absl::optional<uint64_t> bytes_received;
-  absl::optional<double> total_round_trip_time;
-  absl::optional<double> current_round_trip_time;
-  absl::optional<double> available_outgoing_bitrate;
-  absl::optional<double> available_incoming_bitrate;
-  absl::optional<uint64_t> requests_received;
-  absl::optional<uint64_t> requests_sent;
-  absl::optional<uint64_t> responses_received;
-  absl::optional<uint64_t> responses_sent;
-  absl::optional<uint64_t> consent_requests_sent;
-  absl::optional<uint64_t> packets_discarded_on_send;
-  absl::optional<uint64_t> bytes_discarded_on_send;
-  absl::optional<double> last_packet_received_timestamp;
-  absl::optional<double> last_packet_sent_timestamp;
+  std::optional<bool> writable;
+  std::optional<uint64_t> packets_sent;
+  std::optional<uint64_t> packets_received;
+  std::optional<uint64_t> bytes_sent;
+  std::optional<uint64_t> bytes_received;
+  std::optional<double> total_round_trip_time;
+  std::optional<double> current_round_trip_time;
+  std::optional<double> available_outgoing_bitrate;
+  std::optional<double> available_incoming_bitrate;
+  std::optional<uint64_t> requests_received;
+  std::optional<uint64_t> requests_sent;
+  std::optional<uint64_t> responses_received;
+  std::optional<uint64_t> responses_sent;
+  std::optional<uint64_t> consent_requests_sent;
+  std::optional<uint64_t> packets_discarded_on_send;
+  std::optional<uint64_t> bytes_discarded_on_send;
+  std::optional<double> last_packet_received_timestamp;
+  std::optional<double> last_packet_sent_timestamp;
 };
 
 // https://w3c.github.io/webrtc-stats/#icecandidate-dict*
@@ -113,28 +113,28 @@
   WEBRTC_RTCSTATS_DECL();
   ~RTCIceCandidateStats() override;
 
-  absl::optional<std::string> transport_id;
+  std::optional<std::string> transport_id;
   // Obsolete: is_remote
-  absl::optional<bool> is_remote;
-  absl::optional<std::string> network_type;
-  absl::optional<std::string> ip;
-  absl::optional<std::string> address;
-  absl::optional<int32_t> port;
-  absl::optional<std::string> protocol;
-  absl::optional<std::string> relay_protocol;
-  absl::optional<std::string> candidate_type;
-  absl::optional<int32_t> priority;
-  absl::optional<std::string> url;
-  absl::optional<std::string> foundation;
-  absl::optional<std::string> related_address;
-  absl::optional<int32_t> related_port;
-  absl::optional<std::string> username_fragment;
-  absl::optional<std::string> tcp_type;
+  std::optional<bool> is_remote;
+  std::optional<std::string> network_type;
+  std::optional<std::string> ip;
+  std::optional<std::string> address;
+  std::optional<int32_t> port;
+  std::optional<std::string> protocol;
+  std::optional<std::string> relay_protocol;
+  std::optional<std::string> candidate_type;
+  std::optional<int32_t> priority;
+  std::optional<std::string> url;
+  std::optional<std::string> foundation;
+  std::optional<std::string> related_address;
+  std::optional<int32_t> related_port;
+  std::optional<std::string> username_fragment;
+  std::optional<std::string> tcp_type;
 
   // The following metrics are NOT exposed to JavaScript. We should consider
   // standardizing or removing them.
-  absl::optional<bool> vpn;
-  absl::optional<std::string> network_adapter_type;
+  std::optional<bool> vpn;
+  std::optional<std::string> network_adapter_type;
 
  protected:
   RTCIceCandidateStats(std::string id, Timestamp timestamp, bool is_remote);
@@ -169,8 +169,8 @@
   RTCPeerConnectionStats(std::string id, Timestamp timestamp);
   ~RTCPeerConnectionStats() override;
 
-  absl::optional<uint32_t> data_channels_opened;
-  absl::optional<uint32_t> data_channels_closed;
+  std::optional<uint32_t> data_channels_opened;
+  std::optional<uint32_t> data_channels_closed;
 };
 
 // https://w3c.github.io/webrtc-stats/#streamstats-dict*
@@ -179,10 +179,10 @@
   WEBRTC_RTCSTATS_DECL();
   ~RTCRtpStreamStats() override;
 
-  absl::optional<uint32_t> ssrc;
-  absl::optional<std::string> kind;
-  absl::optional<std::string> transport_id;
-  absl::optional<std::string> codec_id;
+  std::optional<uint32_t> ssrc;
+  std::optional<std::string> kind;
+  std::optional<std::string> transport_id;
+  std::optional<std::string> codec_id;
 
  protected:
   RTCRtpStreamStats(std::string id, Timestamp timestamp);
@@ -194,8 +194,8 @@
   WEBRTC_RTCSTATS_DECL();
   ~RTCReceivedRtpStreamStats() override;
 
-  absl::optional<double> jitter;
-  absl::optional<int32_t> packets_lost;  // Signed per RFC 3550
+  std::optional<double> jitter;
+  std::optional<int32_t> packets_lost;  // Signed per RFC 3550
 
  protected:
   RTCReceivedRtpStreamStats(std::string id, Timestamp timestamp);
@@ -207,8 +207,8 @@
   WEBRTC_RTCSTATS_DECL();
   ~RTCSentRtpStreamStats() override;
 
-  absl::optional<uint64_t> packets_sent;
-  absl::optional<uint64_t> bytes_sent;
+  std::optional<uint64_t> packets_sent;
+  std::optional<uint64_t> bytes_sent;
 
  protected:
   RTCSentRtpStreamStats(std::string id, Timestamp timestamp);
@@ -222,51 +222,51 @@
   RTCInboundRtpStreamStats(std::string id, Timestamp timestamp);
   ~RTCInboundRtpStreamStats() override;
 
-  absl::optional<std::string> playout_id;
-  absl::optional<std::string> track_identifier;
-  absl::optional<std::string> mid;
-  absl::optional<std::string> remote_id;
-  absl::optional<uint32_t> packets_received;
-  absl::optional<uint64_t> packets_discarded;
-  absl::optional<uint64_t> fec_packets_received;
-  absl::optional<uint64_t> fec_bytes_received;
-  absl::optional<uint64_t> fec_packets_discarded;
+  std::optional<std::string> playout_id;
+  std::optional<std::string> track_identifier;
+  std::optional<std::string> mid;
+  std::optional<std::string> remote_id;
+  std::optional<uint32_t> packets_received;
+  std::optional<uint64_t> packets_discarded;
+  std::optional<uint64_t> fec_packets_received;
+  std::optional<uint64_t> fec_bytes_received;
+  std::optional<uint64_t> fec_packets_discarded;
   // Inbound FEC SSRC. Only present if a mechanism like FlexFEC is negotiated.
-  absl::optional<uint32_t> fec_ssrc;
-  absl::optional<uint64_t> bytes_received;
-  absl::optional<uint64_t> header_bytes_received;
+  std::optional<uint32_t> fec_ssrc;
+  std::optional<uint64_t> bytes_received;
+  std::optional<uint64_t> header_bytes_received;
   // Inbound RTX stats. Only defined when RTX is used and it is therefore
   // possible to distinguish retransmissions.
-  absl::optional<uint64_t> retransmitted_packets_received;
-  absl::optional<uint64_t> retransmitted_bytes_received;
-  absl::optional<uint32_t> rtx_ssrc;
+  std::optional<uint64_t> retransmitted_packets_received;
+  std::optional<uint64_t> retransmitted_bytes_received;
+  std::optional<uint32_t> rtx_ssrc;
 
-  absl::optional<double> last_packet_received_timestamp;
-  absl::optional<double> jitter_buffer_delay;
-  absl::optional<double> jitter_buffer_target_delay;
-  absl::optional<double> jitter_buffer_minimum_delay;
-  absl::optional<uint64_t> jitter_buffer_emitted_count;
-  absl::optional<uint64_t> total_samples_received;
-  absl::optional<uint64_t> concealed_samples;
-  absl::optional<uint64_t> silent_concealed_samples;
-  absl::optional<uint64_t> concealment_events;
-  absl::optional<uint64_t> inserted_samples_for_deceleration;
-  absl::optional<uint64_t> removed_samples_for_acceleration;
-  absl::optional<double> audio_level;
-  absl::optional<double> total_audio_energy;
-  absl::optional<double> total_samples_duration;
+  std::optional<double> last_packet_received_timestamp;
+  std::optional<double> jitter_buffer_delay;
+  std::optional<double> jitter_buffer_target_delay;
+  std::optional<double> jitter_buffer_minimum_delay;
+  std::optional<uint64_t> jitter_buffer_emitted_count;
+  std::optional<uint64_t> total_samples_received;
+  std::optional<uint64_t> concealed_samples;
+  std::optional<uint64_t> silent_concealed_samples;
+  std::optional<uint64_t> concealment_events;
+  std::optional<uint64_t> inserted_samples_for_deceleration;
+  std::optional<uint64_t> removed_samples_for_acceleration;
+  std::optional<double> audio_level;
+  std::optional<double> total_audio_energy;
+  std::optional<double> total_samples_duration;
   // Stats below are only implemented or defined for video.
-  absl::optional<uint32_t> frames_received;
-  absl::optional<uint32_t> frame_width;
-  absl::optional<uint32_t> frame_height;
-  absl::optional<double> frames_per_second;
-  absl::optional<uint32_t> frames_decoded;
-  absl::optional<uint32_t> key_frames_decoded;
-  absl::optional<uint32_t> frames_dropped;
-  absl::optional<double> total_decode_time;
-  absl::optional<double> total_processing_delay;
-  absl::optional<double> total_assembly_time;
-  absl::optional<uint32_t> frames_assembled_from_multiple_packets;
+  std::optional<uint32_t> frames_received;
+  std::optional<uint32_t> frame_width;
+  std::optional<uint32_t> frame_height;
+  std::optional<double> frames_per_second;
+  std::optional<uint32_t> frames_decoded;
+  std::optional<uint32_t> key_frames_decoded;
+  std::optional<uint32_t> frames_dropped;
+  std::optional<double> total_decode_time;
+  std::optional<double> total_processing_delay;
+  std::optional<double> total_assembly_time;
+  std::optional<uint32_t> frames_assembled_from_multiple_packets;
   // TODO(https://crbug.com/webrtc/15600): Implement framesRendered, which is
   // incremented at the same time that totalInterFrameDelay and
   // totalSquaredInterFrameDelay is incremented. (Dividing inter-frame delay by
@@ -278,43 +278,43 @@
   // at delivery to sink, not at actual render time. When we have an actual
   // frame rendered callback, move the calculating of these metrics to there in
   // order to make them more accurate.
-  absl::optional<double> total_inter_frame_delay;
-  absl::optional<double> total_squared_inter_frame_delay;
-  absl::optional<uint32_t> pause_count;
-  absl::optional<double> total_pauses_duration;
-  absl::optional<uint32_t> freeze_count;
-  absl::optional<double> total_freezes_duration;
+  std::optional<double> total_inter_frame_delay;
+  std::optional<double> total_squared_inter_frame_delay;
+  std::optional<uint32_t> pause_count;
+  std::optional<double> total_pauses_duration;
+  std::optional<uint32_t> freeze_count;
+  std::optional<double> total_freezes_duration;
   // https://w3c.github.io/webrtc-provisional-stats/#dom-rtcinboundrtpstreamstats-contenttype
-  absl::optional<std::string> content_type;
+  std::optional<std::string> content_type;
   // Only populated if audio/video sync is enabled.
   // TODO(https://crbug.com/webrtc/14177): Expose even if A/V sync is off?
-  absl::optional<double> estimated_playout_timestamp;
+  std::optional<double> estimated_playout_timestamp;
   // Only defined for video.
   // In JavaScript, this is only exposed if HW exposure is allowed.
-  absl::optional<std::string> decoder_implementation;
+  std::optional<std::string> decoder_implementation;
   // FIR and PLI counts are only defined for |kind == "video"|.
-  absl::optional<uint32_t> fir_count;
-  absl::optional<uint32_t> pli_count;
-  absl::optional<uint32_t> nack_count;
-  absl::optional<uint64_t> qp_sum;
+  std::optional<uint32_t> fir_count;
+  std::optional<uint32_t> pli_count;
+  std::optional<uint32_t> nack_count;
+  std::optional<uint64_t> qp_sum;
   // This is a remnant of the legacy getStats() API. When the "video-timing"
   // header extension is used,
   // https://webrtc.github.io/webrtc-org/experiments/rtp-hdrext/video-timing/,
   // `googTimingFrameInfo` is exposed with the value of
   // TimingFrameInfo::ToString().
   // TODO(https://crbug.com/webrtc/14586): Unship or standardize this metric.
-  absl::optional<std::string> goog_timing_frame_info;
+  std::optional<std::string> goog_timing_frame_info;
   // In JavaScript, this is only exposed if HW exposure is allowed.
-  absl::optional<bool> power_efficient_decoder;
+  std::optional<bool> power_efficient_decoder;
 
   // The following metrics are NOT exposed to JavaScript. We should consider
   // standardizing or removing them.
-  absl::optional<uint64_t> jitter_buffer_flushes;
-  absl::optional<uint64_t> delayed_packet_outage_samples;
-  absl::optional<double> relative_packet_arrival_delay;
-  absl::optional<uint32_t> interruption_count;
-  absl::optional<double> total_interruption_duration;
-  absl::optional<double> min_playout_delay;
+  std::optional<uint64_t> jitter_buffer_flushes;
+  std::optional<uint64_t> delayed_packet_outage_samples;
+  std::optional<double> relative_packet_arrival_delay;
+  std::optional<uint32_t> interruption_count;
+  std::optional<double> total_interruption_duration;
+  std::optional<double> min_playout_delay;
 };
 
 // https://w3c.github.io/webrtc-stats/#outboundrtpstats-dict*
@@ -325,46 +325,46 @@
   RTCOutboundRtpStreamStats(std::string id, Timestamp timestamp);
   ~RTCOutboundRtpStreamStats() override;
 
-  absl::optional<std::string> media_source_id;
-  absl::optional<std::string> remote_id;
-  absl::optional<std::string> mid;
-  absl::optional<std::string> rid;
-  absl::optional<uint64_t> retransmitted_packets_sent;
-  absl::optional<uint64_t> header_bytes_sent;
-  absl::optional<uint64_t> retransmitted_bytes_sent;
-  absl::optional<double> target_bitrate;
-  absl::optional<uint32_t> frames_encoded;
-  absl::optional<uint32_t> key_frames_encoded;
-  absl::optional<double> total_encode_time;
-  absl::optional<uint64_t> total_encoded_bytes_target;
-  absl::optional<uint32_t> frame_width;
-  absl::optional<uint32_t> frame_height;
-  absl::optional<double> frames_per_second;
-  absl::optional<uint32_t> frames_sent;
-  absl::optional<uint32_t> huge_frames_sent;
-  absl::optional<double> total_packet_send_delay;
-  absl::optional<std::string> quality_limitation_reason;
-  absl::optional<std::map<std::string, double>> quality_limitation_durations;
+  std::optional<std::string> media_source_id;
+  std::optional<std::string> remote_id;
+  std::optional<std::string> mid;
+  std::optional<std::string> rid;
+  std::optional<uint64_t> retransmitted_packets_sent;
+  std::optional<uint64_t> header_bytes_sent;
+  std::optional<uint64_t> retransmitted_bytes_sent;
+  std::optional<double> target_bitrate;
+  std::optional<uint32_t> frames_encoded;
+  std::optional<uint32_t> key_frames_encoded;
+  std::optional<double> total_encode_time;
+  std::optional<uint64_t> total_encoded_bytes_target;
+  std::optional<uint32_t> frame_width;
+  std::optional<uint32_t> frame_height;
+  std::optional<double> frames_per_second;
+  std::optional<uint32_t> frames_sent;
+  std::optional<uint32_t> huge_frames_sent;
+  std::optional<double> total_packet_send_delay;
+  std::optional<std::string> quality_limitation_reason;
+  std::optional<std::map<std::string, double>> quality_limitation_durations;
   // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-qualitylimitationresolutionchanges
-  absl::optional<uint32_t> quality_limitation_resolution_changes;
+  std::optional<uint32_t> quality_limitation_resolution_changes;
   // https://w3c.github.io/webrtc-provisional-stats/#dom-rtcoutboundrtpstreamstats-contenttype
-  absl::optional<std::string> content_type;
+  std::optional<std::string> content_type;
   // In JavaScript, this is only exposed if HW exposure is allowed.
   // Only implemented for video.
   // TODO(https://crbug.com/webrtc/14178): Implement for audio as well.
-  absl::optional<std::string> encoder_implementation;
+  std::optional<std::string> encoder_implementation;
   // FIR and PLI counts are only defined for |kind == "video"|.
-  absl::optional<uint32_t> fir_count;
-  absl::optional<uint32_t> pli_count;
-  absl::optional<uint32_t> nack_count;
-  absl::optional<uint64_t> qp_sum;
-  absl::optional<bool> active;
+  std::optional<uint32_t> fir_count;
+  std::optional<uint32_t> pli_count;
+  std::optional<uint32_t> nack_count;
+  std::optional<uint64_t> qp_sum;
+  std::optional<bool> active;
   // In JavaScript, this is only exposed if HW exposure is allowed.
-  absl::optional<bool> power_efficient_encoder;
-  absl::optional<std::string> scalability_mode;
+  std::optional<bool> power_efficient_encoder;
+  std::optional<std::string> scalability_mode;
 
   // RTX ssrc. Only present if RTX is negotiated.
-  absl::optional<uint32_t> rtx_ssrc;
+  std::optional<uint32_t> rtx_ssrc;
 };
 
 // https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
@@ -375,11 +375,11 @@
   RTCRemoteInboundRtpStreamStats(std::string id, Timestamp timestamp);
   ~RTCRemoteInboundRtpStreamStats() override;
 
-  absl::optional<std::string> local_id;
-  absl::optional<double> round_trip_time;
-  absl::optional<double> fraction_lost;
-  absl::optional<double> total_round_trip_time;
-  absl::optional<int32_t> round_trip_time_measurements;
+  std::optional<std::string> local_id;
+  std::optional<double> round_trip_time;
+  std::optional<double> fraction_lost;
+  std::optional<double> total_round_trip_time;
+  std::optional<int32_t> round_trip_time_measurements;
 };
 
 // https://w3c.github.io/webrtc-stats/#remoteoutboundrtpstats-dict*
@@ -390,12 +390,12 @@
   RTCRemoteOutboundRtpStreamStats(std::string id, Timestamp timestamp);
   ~RTCRemoteOutboundRtpStreamStats() override;
 
-  absl::optional<std::string> local_id;
-  absl::optional<double> remote_timestamp;
-  absl::optional<uint64_t> reports_sent;
-  absl::optional<double> round_trip_time;
-  absl::optional<uint64_t> round_trip_time_measurements;
-  absl::optional<double> total_round_trip_time;
+  std::optional<std::string> local_id;
+  std::optional<double> remote_timestamp;
+  std::optional<uint64_t> reports_sent;
+  std::optional<double> round_trip_time;
+  std::optional<uint64_t> round_trip_time_measurements;
+  std::optional<double> total_round_trip_time;
 };
 
 // https://w3c.github.io/webrtc-stats/#dom-rtcmediasourcestats
@@ -404,8 +404,8 @@
   WEBRTC_RTCSTATS_DECL();
   ~RTCMediaSourceStats() override;
 
-  absl::optional<std::string> track_identifier;
-  absl::optional<std::string> kind;
+  std::optional<std::string> track_identifier;
+  std::optional<std::string> kind;
 
  protected:
   RTCMediaSourceStats(std::string id, Timestamp timestamp);
@@ -418,11 +418,11 @@
   RTCAudioSourceStats(std::string id, Timestamp timestamp);
   ~RTCAudioSourceStats() override;
 
-  absl::optional<double> audio_level;
-  absl::optional<double> total_audio_energy;
-  absl::optional<double> total_samples_duration;
-  absl::optional<double> echo_return_loss;
-  absl::optional<double> echo_return_loss_enhancement;
+  std::optional<double> audio_level;
+  std::optional<double> total_audio_energy;
+  std::optional<double> total_samples_duration;
+  std::optional<double> echo_return_loss;
+  std::optional<double> echo_return_loss_enhancement;
 };
 
 // https://w3c.github.io/webrtc-stats/#dom-rtcvideosourcestats
@@ -432,10 +432,10 @@
   RTCVideoSourceStats(std::string id, Timestamp timestamp);
   ~RTCVideoSourceStats() override;
 
-  absl::optional<uint32_t> width;
-  absl::optional<uint32_t> height;
-  absl::optional<uint32_t> frames;
-  absl::optional<double> frames_per_second;
+  std::optional<uint32_t> width;
+  std::optional<uint32_t> height;
+  std::optional<uint32_t> frames;
+  std::optional<double> frames_per_second;
 };
 
 // https://w3c.github.io/webrtc-stats/#transportstats-dict*
@@ -445,23 +445,23 @@
   RTCTransportStats(std::string id, Timestamp timestamp);
   ~RTCTransportStats() override;
 
-  absl::optional<uint64_t> bytes_sent;
-  absl::optional<uint64_t> packets_sent;
-  absl::optional<uint64_t> bytes_received;
-  absl::optional<uint64_t> packets_received;
-  absl::optional<std::string> rtcp_transport_stats_id;
-  absl::optional<std::string> dtls_state;
-  absl::optional<std::string> selected_candidate_pair_id;
-  absl::optional<std::string> local_certificate_id;
-  absl::optional<std::string> remote_certificate_id;
-  absl::optional<std::string> tls_version;
-  absl::optional<std::string> dtls_cipher;
-  absl::optional<std::string> dtls_role;
-  absl::optional<std::string> srtp_cipher;
-  absl::optional<uint32_t> selected_candidate_pair_changes;
-  absl::optional<std::string> ice_role;
-  absl::optional<std::string> ice_local_username_fragment;
-  absl::optional<std::string> ice_state;
+  std::optional<uint64_t> bytes_sent;
+  std::optional<uint64_t> packets_sent;
+  std::optional<uint64_t> bytes_received;
+  std::optional<uint64_t> packets_received;
+  std::optional<std::string> rtcp_transport_stats_id;
+  std::optional<std::string> dtls_state;
+  std::optional<std::string> selected_candidate_pair_id;
+  std::optional<std::string> local_certificate_id;
+  std::optional<std::string> remote_certificate_id;
+  std::optional<std::string> tls_version;
+  std::optional<std::string> dtls_cipher;
+  std::optional<std::string> dtls_role;
+  std::optional<std::string> srtp_cipher;
+  std::optional<uint32_t> selected_candidate_pair_changes;
+  std::optional<std::string> ice_role;
+  std::optional<std::string> ice_local_username_fragment;
+  std::optional<std::string> ice_state;
 };
 
 // https://w3c.github.io/webrtc-stats/#playoutstats-dict*
@@ -471,12 +471,12 @@
   RTCAudioPlayoutStats(const std::string& id, Timestamp timestamp);
   ~RTCAudioPlayoutStats() override;
 
-  absl::optional<std::string> kind;
-  absl::optional<double> synthesized_samples_duration;
-  absl::optional<uint64_t> synthesized_samples_events;
-  absl::optional<double> total_samples_duration;
-  absl::optional<double> total_playout_delay;
-  absl::optional<uint64_t> total_samples_count;
+  std::optional<std::string> kind;
+  std::optional<double> synthesized_samples_duration;
+  std::optional<uint64_t> synthesized_samples_events;
+  std::optional<double> total_samples_duration;
+  std::optional<double> total_playout_delay;
+  std::optional<uint64_t> total_samples_count;
 };
 
 }  // namespace webrtc
diff --git a/api/test/create_frame_generator.cc b/api/test/create_frame_generator.cc
index f0d8e05..5750835 100644
--- a/api/test/create_frame_generator.cc
+++ b/api/test/create_frame_generator.cc
@@ -13,12 +13,12 @@
 #include <cstdint>
 #include <cstdio>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/base/nullability.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
 #include "api/test/frame_generator_interface.h"
@@ -32,8 +32,8 @@
 std::unique_ptr<FrameGeneratorInterface> CreateSquareFrameGenerator(
     int width,
     int height,
-    absl::optional<FrameGeneratorInterface::OutputType> type,
-    absl::optional<int> num_squares) {
+    std::optional<FrameGeneratorInterface::OutputType> type,
+    std::optional<int> num_squares) {
   return std::make_unique<SquareGenerator>(
       width, height, type.value_or(FrameGeneratorInterface::OutputType::kI420),
       num_squares.value_or(10));
diff --git a/api/test/create_frame_generator.h b/api/test/create_frame_generator.h
index 14c88d3..6e9a882 100644
--- a/api/test/create_frame_generator.h
+++ b/api/test/create_frame_generator.h
@@ -14,12 +14,12 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/base/nullability.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/test/frame_generator_interface.h"
 #include "system_wrappers/include/clock.h"
@@ -34,8 +34,8 @@
 std::unique_ptr<FrameGeneratorInterface> CreateSquareFrameGenerator(
     int width,
     int height,
-    absl::optional<FrameGeneratorInterface::OutputType> type,
-    absl::optional<int> num_squares);
+    std::optional<FrameGeneratorInterface::OutputType> type,
+    std::optional<int> num_squares);
 
 // Creates a frame generator that repeatedly plays a set of yuv files.
 // The frame_repeat_count determines how many times each frame is shown,
diff --git a/api/test/create_peer_connection_quality_test_frame_generator.cc b/api/test/create_peer_connection_quality_test_frame_generator.cc
index d4aa46d..b99f1bd 100644
--- a/api/test/create_peer_connection_quality_test_frame_generator.cc
+++ b/api/test/create_peer_connection_quality_test_frame_generator.cc
@@ -11,11 +11,11 @@
 #include "api/test/create_peer_connection_quality_test_frame_generator.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/test/create_frame_generator.h"
 #include "api/test/frame_generator_interface.h"
 #include "api/test/pclf/media_configuration.h"
@@ -55,9 +55,9 @@
 
 std::unique_ptr<test::FrameGeneratorInterface> CreateSquareFrameGenerator(
     const VideoConfig& video_config,
-    absl::optional<test::FrameGeneratorInterface::OutputType> type) {
+    std::optional<test::FrameGeneratorInterface::OutputType> type) {
   return test::CreateSquareFrameGenerator(
-      video_config.width, video_config.height, std::move(type), absl::nullopt);
+      video_config.width, video_config.height, std::move(type), std::nullopt);
 }
 
 std::unique_ptr<test::FrameGeneratorInterface> CreateFromYuvFileFrameGenerator(
diff --git a/api/test/create_peer_connection_quality_test_frame_generator.h b/api/test/create_peer_connection_quality_test_frame_generator.h
index 62043d1..a851507 100644
--- a/api/test/create_peer_connection_quality_test_frame_generator.h
+++ b/api/test/create_peer_connection_quality_test_frame_generator.h
@@ -11,9 +11,9 @@
 #define API_TEST_CREATE_PEER_CONNECTION_QUALITY_TEST_FRAME_GENERATOR_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/test/frame_generator_interface.h"
 #include "api/test/pclf/media_configuration.h"
 
@@ -26,7 +26,7 @@
 // weight and height.
 std::unique_ptr<test::FrameGeneratorInterface> CreateSquareFrameGenerator(
     const VideoConfig& video_config,
-    absl::optional<test::FrameGeneratorInterface::OutputType> type);
+    std::optional<test::FrameGeneratorInterface::OutputType> type);
 
 // Creates a frame generator that plays frames from the yuv file.
 std::unique_ptr<test::FrameGeneratorInterface> CreateFromYuvFileFrameGenerator(
diff --git a/api/test/frame_generator_interface.h b/api/test/frame_generator_interface.h
index 169ead8..ed03bce 100644
--- a/api/test/frame_generator_interface.h
+++ b/api/test/frame_generator_interface.h
@@ -12,9 +12,9 @@
 #define API_TEST_FRAME_GENERATOR_INTERFACE_H_
 
 #include <cstddef>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
 #include "api/video/video_frame.h"
 #include "api/video/video_frame_buffer.h"
@@ -30,11 +30,11 @@
   };
   struct VideoFrameData {
     VideoFrameData(rtc::scoped_refptr<VideoFrameBuffer> buffer,
-                   absl::optional<VideoFrame::UpdateRect> update_rect)
+                   std::optional<VideoFrame::UpdateRect> update_rect)
         : buffer(std::move(buffer)), update_rect(update_rect) {}
 
     rtc::scoped_refptr<VideoFrameBuffer> buffer;
-    absl::optional<VideoFrame::UpdateRect> update_rect;
+    std::optional<VideoFrame::UpdateRect> update_rect;
   };
 
   enum class OutputType { kI420, kI420A, kI010, kNV12 };
@@ -56,8 +56,8 @@
 
   // Returns the frames per second this generator is supposed to provide
   // according to its data source. Not all frame generators know the frames per
-  // second of the data source, in such case this method returns absl::nullopt.
-  virtual absl::optional<int> fps() const = 0;
+  // second of the data source, in such case this method returns std::nullopt.
+  virtual std::optional<int> fps() const = 0;
 };
 
 }  // namespace test
diff --git a/api/test/metrics/BUILD.gn b/api/test/metrics/BUILD.gn
index dbbb38a..04a28f4 100644
--- a/api/test/metrics/BUILD.gn
+++ b/api/test/metrics/BUILD.gn
@@ -49,10 +49,7 @@
     "metric.cc",
     "metric.h",
   ]
-  deps = [
-    "../../../api/units:timestamp",
-    "//third_party/abseil-cpp/absl/types:optional",
-  ]
+  deps = [ "../../../api/units:timestamp" ]
 }
 
 rtc_library("metrics_logger") {
@@ -71,7 +68,6 @@
     "../../numerics",
     "../../units:timestamp",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -111,7 +107,6 @@
     ":metrics_exporter",
     "../..:array_view",
     "../../../rtc_base:stringutils",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -203,7 +198,6 @@
       "../../../test:test_support",
       "../../numerics",
       "../../units:timestamp",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -215,7 +209,6 @@
       ":metrics_accumulator",
       "../../../test:test_support",
       "../../units:timestamp",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -251,7 +244,6 @@
       ":metrics_logger",
       "../../../system_wrappers",
       "../../../test:test_support",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
diff --git a/api/test/metrics/global_metrics_logger_and_exporter_test.cc b/api/test/metrics/global_metrics_logger_and_exporter_test.cc
index 567b3da..175fa6e 100644
--- a/api/test/metrics/global_metrics_logger_and_exporter_test.cc
+++ b/api/test/metrics/global_metrics_logger_and_exporter_test.cc
@@ -11,11 +11,11 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/test/metrics/metric.h"
 #include "api/test/metrics/metrics_exporter.h"
 #include "api/test/metrics/metrics_logger.h"
@@ -91,10 +91,10 @@
   EXPECT_THAT(metric.time_series.samples[0].value, Eq(10.0));
   EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
               Eq(std::map<std::string, std::string>{}));
-  ASSERT_THAT(metric.stats.mean, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.stddev, absl::nullopt);
-  ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.max, absl::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.mean, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.stddev, std::nullopt);
+  ASSERT_THAT(metric.stats.min, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.max, std::optional<double>(10.0));
 }
 
 TEST(ExportPerfMetricTest, OneFailedExporterDoesNotPreventExportToOthers) {
diff --git a/api/test/metrics/metric.h b/api/test/metrics/metric.h
index 17c1755..ee5680e 100644
--- a/api/test/metrics/metric.h
+++ b/api/test/metrics/metric.h
@@ -12,10 +12,10 @@
 #define API_TEST_METRICS_METRIC_H_
 
 #include <map>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/units/timestamp.h"
 
 namespace webrtc {
@@ -66,12 +66,12 @@
   struct Stats {
     // Sample mean of the metric
     // (https://en.wikipedia.org/wiki/Sample_mean_and_covariance).
-    absl::optional<double> mean;
+    std::optional<double> mean;
     // Standard deviation (https://en.wikipedia.org/wiki/Standard_deviation).
     // Is undefined if `time_series` contains only a single value.
-    absl::optional<double> stddev;
-    absl::optional<double> min;
-    absl::optional<double> max;
+    std::optional<double> stddev;
+    std::optional<double> min;
+    std::optional<double> max;
   };
 
   // Metric name, for example PSNR, SSIM, decode_time, etc.
diff --git a/api/test/metrics/metrics_accumulator_test.cc b/api/test/metrics/metrics_accumulator_test.cc
index 6b3efea..9f88395 100644
--- a/api/test/metrics/metrics_accumulator_test.cc
+++ b/api/test/metrics/metrics_accumulator_test.cc
@@ -10,10 +10,10 @@
 #include "api/test/metrics/metrics_accumulator.h"
 
 #include <map>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/test/metrics/metric.h"
 #include "api/units/timestamp.h"
 #include "test/gmock.h"
@@ -49,10 +49,10 @@
               Eq(Timestamp::Seconds(1)));
   EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
               Eq(std::map<std::string, std::string>{{"key", "value"}}));
-  ASSERT_THAT(metric.stats.mean, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.stddev, absl::optional<double>(0.0));
-  ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.max, absl::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.mean, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.stddev, std::optional<double>(0.0));
+  ASSERT_THAT(metric.stats.min, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.max, std::optional<double>(10.0));
 }
 
 TEST(MetricsAccumulatorTest, AddSamplesToExistingMetricWontCreateNewOne) {
@@ -88,10 +88,10 @@
               Eq(Timestamp::Seconds(2)));
   EXPECT_THAT(metric.time_series.samples[1].sample_metadata,
               Eq(std::map<std::string, std::string>{{"key2", "value2"}}));
-  ASSERT_THAT(metric.stats.mean, absl::optional<double>(15.0));
-  ASSERT_THAT(metric.stats.stddev, absl::optional<double>(5.0));
-  ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.max, absl::optional<double>(20.0));
+  ASSERT_THAT(metric.stats.mean, std::optional<double>(15.0));
+  ASSERT_THAT(metric.stats.stddev, std::optional<double>(5.0));
+  ASSERT_THAT(metric.stats.min, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.max, std::optional<double>(20.0));
 }
 
 TEST(MetricsAccumulatorTest, AddSampleToDifferentMetricsWillCreateBoth) {
@@ -121,10 +121,10 @@
               Eq(Timestamp::Seconds(1)));
   EXPECT_THAT(metrics[0].time_series.samples[0].sample_metadata,
               Eq(std::map<std::string, std::string>{{"key1", "value1"}}));
-  ASSERT_THAT(metrics[0].stats.mean, absl::optional<double>(10.0));
-  ASSERT_THAT(metrics[0].stats.stddev, absl::optional<double>(0.0));
-  ASSERT_THAT(metrics[0].stats.min, absl::optional<double>(10.0));
-  ASSERT_THAT(metrics[0].stats.max, absl::optional<double>(10.0));
+  ASSERT_THAT(metrics[0].stats.mean, std::optional<double>(10.0));
+  ASSERT_THAT(metrics[0].stats.stddev, std::optional<double>(0.0));
+  ASSERT_THAT(metrics[0].stats.min, std::optional<double>(10.0));
+  ASSERT_THAT(metrics[0].stats.max, std::optional<double>(10.0));
   EXPECT_THAT(metrics[1].name, Eq("metric_name2"));
   EXPECT_THAT(metrics[1].test_case, Eq("test_case_name2"));
   EXPECT_THAT(metrics[1].unit, Eq(Unit::kUnitless));
@@ -137,10 +137,10 @@
               Eq(Timestamp::Seconds(2)));
   EXPECT_THAT(metrics[1].time_series.samples[0].sample_metadata,
               Eq(std::map<std::string, std::string>{{"key2", "value2"}}));
-  ASSERT_THAT(metrics[1].stats.mean, absl::optional<double>(20.0));
-  ASSERT_THAT(metrics[1].stats.stddev, absl::optional<double>(0.0));
-  ASSERT_THAT(metrics[1].stats.min, absl::optional<double>(20.0));
-  ASSERT_THAT(metrics[1].stats.max, absl::optional<double>(20.0));
+  ASSERT_THAT(metrics[1].stats.mean, std::optional<double>(20.0));
+  ASSERT_THAT(metrics[1].stats.stddev, std::optional<double>(0.0));
+  ASSERT_THAT(metrics[1].stats.min, std::optional<double>(20.0));
+  ASSERT_THAT(metrics[1].stats.max, std::optional<double>(20.0));
 }
 
 TEST(MetricsAccumulatorTest, AddMetadataToTheNewMetricWillCreateOne) {
@@ -162,10 +162,10 @@
   EXPECT_THAT(metric.metric_metadata,
               Eq(std::map<std::string, std::string>{{"key", "value"}}));
   ASSERT_THAT(metric.time_series.samples, IsEmpty());
-  ASSERT_THAT(metric.stats.mean, absl::nullopt);
-  ASSERT_THAT(metric.stats.stddev, absl::nullopt);
-  ASSERT_THAT(metric.stats.min, absl::nullopt);
-  ASSERT_THAT(metric.stats.max, absl::nullopt);
+  ASSERT_THAT(metric.stats.mean, std::nullopt);
+  ASSERT_THAT(metric.stats.stddev, std::nullopt);
+  ASSERT_THAT(metric.stats.min, std::nullopt);
+  ASSERT_THAT(metric.stats.max, std::nullopt);
 }
 
 TEST(MetricsAccumulatorTest,
@@ -194,10 +194,10 @@
   EXPECT_THAT(metric.metric_metadata,
               Eq(std::map<std::string, std::string>{{"key2", "value2"}}));
   ASSERT_THAT(metric.time_series.samples, IsEmpty());
-  ASSERT_THAT(metric.stats.mean, absl::nullopt);
-  ASSERT_THAT(metric.stats.stddev, absl::nullopt);
-  ASSERT_THAT(metric.stats.min, absl::nullopt);
-  ASSERT_THAT(metric.stats.max, absl::nullopt);
+  ASSERT_THAT(metric.stats.mean, std::nullopt);
+  ASSERT_THAT(metric.stats.stddev, std::nullopt);
+  ASSERT_THAT(metric.stats.min, std::nullopt);
+  ASSERT_THAT(metric.stats.max, std::nullopt);
 }
 
 TEST(MetricsAccumulatorTest, AddMetadataToDifferentMetricsWillCreateBoth) {
@@ -224,10 +224,10 @@
   EXPECT_THAT(metrics[0].metric_metadata,
               Eq(std::map<std::string, std::string>{{"key1", "value1"}}));
   ASSERT_THAT(metrics[0].time_series.samples, IsEmpty());
-  ASSERT_THAT(metrics[0].stats.mean, absl::nullopt);
-  ASSERT_THAT(metrics[0].stats.stddev, absl::nullopt);
-  ASSERT_THAT(metrics[0].stats.min, absl::nullopt);
-  ASSERT_THAT(metrics[0].stats.max, absl::nullopt);
+  ASSERT_THAT(metrics[0].stats.mean, std::nullopt);
+  ASSERT_THAT(metrics[0].stats.stddev, std::nullopt);
+  ASSERT_THAT(metrics[0].stats.min, std::nullopt);
+  ASSERT_THAT(metrics[0].stats.max, std::nullopt);
   EXPECT_THAT(metrics[1].name, Eq("metric_name2"));
   EXPECT_THAT(metrics[1].test_case, Eq("test_case_name2"));
   EXPECT_THAT(metrics[1].unit, Eq(Unit::kBytes));
@@ -236,10 +236,10 @@
   EXPECT_THAT(metrics[1].metric_metadata,
               Eq(std::map<std::string, std::string>{{"key2", "value2"}}));
   ASSERT_THAT(metrics[1].time_series.samples, IsEmpty());
-  ASSERT_THAT(metrics[1].stats.mean, absl::nullopt);
-  ASSERT_THAT(metrics[1].stats.stddev, absl::nullopt);
-  ASSERT_THAT(metrics[1].stats.min, absl::nullopt);
-  ASSERT_THAT(metrics[1].stats.max, absl::nullopt);
+  ASSERT_THAT(metrics[1].stats.mean, std::nullopt);
+  ASSERT_THAT(metrics[1].stats.stddev, std::nullopt);
+  ASSERT_THAT(metrics[1].stats.min, std::nullopt);
+  ASSERT_THAT(metrics[1].stats.max, std::nullopt);
 }
 
 TEST(MetricsAccumulatorTest, AddMetadataAfterAddingSampleWontCreateNewMetric) {
@@ -271,10 +271,10 @@
               Eq(Timestamp::Seconds(1)));
   EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
               Eq(std::map<std::string, std::string>{{"key_s", "value_s"}}));
-  ASSERT_THAT(metric.stats.mean, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.stddev, absl::optional<double>(0.0));
-  ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.max, absl::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.mean, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.stddev, std::optional<double>(0.0));
+  ASSERT_THAT(metric.stats.min, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.max, std::optional<double>(10.0));
 }
 
 TEST(MetricsAccumulatorTest, AddSampleAfterAddingMetadataWontCreateNewMetric) {
@@ -306,10 +306,10 @@
               Eq(Timestamp::Seconds(1)));
   EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
               Eq(std::map<std::string, std::string>{{"key_s", "value_s"}}));
-  ASSERT_THAT(metric.stats.mean, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.stddev, absl::optional<double>(0.0));
-  ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.max, absl::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.mean, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.stddev, std::optional<double>(0.0));
+  ASSERT_THAT(metric.stats.min, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.max, std::optional<double>(10.0));
 }
 
 }  // namespace
diff --git a/api/test/metrics/metrics_logger.cc b/api/test/metrics/metrics_logger.cc
index 0695d73..ac927425 100644
--- a/api/test/metrics/metrics_logger.cc
+++ b/api/test/metrics/metrics_logger.cc
@@ -10,12 +10,12 @@
 #include "api/test/metrics/metrics_logger.h"
 
 #include <map>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/numerics/samples_stats_counter.h"
 #include "api/test/metrics/metric.h"
 #include "api/units/timestamp.h"
@@ -55,7 +55,7 @@
           Metric::TimeSeries{.samples = std::vector{Metric::TimeSeries::Sample{
                                  .timestamp = Now(), .value = value}}},
       .stats = Metric::Stats{
-          .mean = value, .stddev = absl::nullopt, .min = value, .max = value}});
+          .mean = value, .stddev = std::nullopt, .min = value, .max = value}});
 }
 
 void DefaultMetricsLogger::LogMetric(
diff --git a/api/test/metrics/metrics_logger_test.cc b/api/test/metrics/metrics_logger_test.cc
index 324a758..a75fdd6 100644
--- a/api/test/metrics/metrics_logger_test.cc
+++ b/api/test/metrics/metrics_logger_test.cc
@@ -10,10 +10,10 @@
 #include "api/test/metrics/metrics_logger.h"
 
 #include <map>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/numerics/samples_stats_counter.h"
 #include "api/test/metrics/metric.h"
 #include "api/units/timestamp.h"
@@ -54,10 +54,10 @@
   EXPECT_THAT(metric.time_series.samples[0].value, Eq(10.0));
   EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
               Eq(std::map<std::string, std::string>{}));
-  ASSERT_THAT(metric.stats.mean, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.stddev, absl::nullopt);
-  ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.max, absl::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.mean, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.stddev, std::nullopt);
+  ASSERT_THAT(metric.stats.min, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.max, std::optional<double>(10.0));
 }
 
 TEST(DefaultMetricsLoggerTest, LogMetricWithSamplesStatsCounterRecordsMetric) {
@@ -95,10 +95,10 @@
   EXPECT_THAT(metric.time_series.samples[1].value, Eq(20.0));
   EXPECT_THAT(metric.time_series.samples[1].sample_metadata,
               Eq(std::map<std::string, std::string>{{"point_key2", "value2"}}));
-  ASSERT_THAT(metric.stats.mean, absl::optional<double>(15.0));
-  ASSERT_THAT(metric.stats.stddev, absl::optional<double>(5.0));
-  ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.max, absl::optional<double>(20.0));
+  ASSERT_THAT(metric.stats.mean, std::optional<double>(15.0));
+  ASSERT_THAT(metric.stats.stddev, std::optional<double>(5.0));
+  ASSERT_THAT(metric.stats.min, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.max, std::optional<double>(20.0));
 }
 
 TEST(DefaultMetricsLoggerTest,
@@ -113,10 +113,10 @@
   EXPECT_THAT(metrics[0].name, Eq("metric_name"));
   EXPECT_THAT(metrics[0].test_case, Eq("test_case_name"));
   EXPECT_THAT(metrics[0].time_series.samples, IsEmpty());
-  ASSERT_THAT(metrics[0].stats.mean, Eq(absl::nullopt));
-  ASSERT_THAT(metrics[0].stats.stddev, Eq(absl::nullopt));
-  ASSERT_THAT(metrics[0].stats.min, Eq(absl::nullopt));
-  ASSERT_THAT(metrics[0].stats.max, Eq(absl::nullopt));
+  ASSERT_THAT(metrics[0].stats.mean, Eq(std::nullopt));
+  ASSERT_THAT(metrics[0].stats.stddev, Eq(std::nullopt));
+  ASSERT_THAT(metrics[0].stats.min, Eq(std::nullopt));
+  ASSERT_THAT(metrics[0].stats.max, Eq(std::nullopt));
 }
 
 TEST(DefaultMetricsLoggerTest, LogMetricWithStatsRecordsMetric) {
@@ -137,10 +137,10 @@
   EXPECT_THAT(metric.metric_metadata,
               Eq(std::map<std::string, std::string>{{"key", "value"}}));
   ASSERT_THAT(metric.time_series.samples, IsEmpty());
-  ASSERT_THAT(metric.stats.mean, absl::optional<double>(15.0));
-  ASSERT_THAT(metric.stats.stddev, absl::optional<double>(5.0));
-  ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.max, absl::optional<double>(20.0));
+  ASSERT_THAT(metric.stats.mean, std::optional<double>(15.0));
+  ASSERT_THAT(metric.stats.stddev, std::optional<double>(5.0));
+  ASSERT_THAT(metric.stats.min, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.max, std::optional<double>(20.0));
 }
 
 TEST(DefaultMetricsLoggerTest, LogSingleValueMetricRecordsMultipleMetrics) {
@@ -267,10 +267,10 @@
               Eq(Timestamp::Seconds(1)));
   EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
               Eq(std::map<std::string, std::string>{{"key", "value"}}));
-  ASSERT_THAT(metric.stats.mean, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.stddev, absl::optional<double>(0.0));
-  ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
-  ASSERT_THAT(metric.stats.max, absl::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.mean, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.stddev, std::optional<double>(0.0));
+  ASSERT_THAT(metric.stats.min, std::optional<double>(10.0));
+  ASSERT_THAT(metric.stats.max, std::optional<double>(10.0));
 }
 
 TEST(DefaultMetricsLoggerTest,
@@ -300,10 +300,10 @@
               Eq(Timestamp::Seconds(1)));
   EXPECT_THAT(metrics[0].time_series.samples[0].sample_metadata,
               Eq(std::map<std::string, std::string>{{"key_s", "value_s"}}));
-  ASSERT_THAT(metrics[0].stats.mean, absl::optional<double>(10.0));
-  ASSERT_THAT(metrics[0].stats.stddev, absl::optional<double>(0.0));
-  ASSERT_THAT(metrics[0].stats.min, absl::optional<double>(10.0));
-  ASSERT_THAT(metrics[0].stats.max, absl::optional<double>(10.0));
+  ASSERT_THAT(metrics[0].stats.mean, std::optional<double>(10.0));
+  ASSERT_THAT(metrics[0].stats.stddev, std::optional<double>(0.0));
+  ASSERT_THAT(metrics[0].stats.min, std::optional<double>(10.0));
+  ASSERT_THAT(metrics[0].stats.max, std::optional<double>(10.0));
   EXPECT_THAT(metrics[1].name, Eq("metric_name1"));
   EXPECT_THAT(metrics[1].test_case, Eq("test_case_name1"));
   EXPECT_THAT(metrics[1].unit, Eq(Unit::kMilliseconds));
@@ -315,10 +315,10 @@
   EXPECT_THAT(metrics[1].time_series.samples[0].value, Eq(10.0));
   EXPECT_THAT(metrics[1].time_series.samples[0].sample_metadata,
               Eq(std::map<std::string, std::string>{}));
-  ASSERT_THAT(metrics[1].stats.mean, absl::optional<double>(10.0));
-  ASSERT_THAT(metrics[1].stats.stddev, absl::nullopt);
-  ASSERT_THAT(metrics[1].stats.min, absl::optional<double>(10.0));
-  ASSERT_THAT(metrics[1].stats.max, absl::optional<double>(10.0));
+  ASSERT_THAT(metrics[1].stats.mean, std::optional<double>(10.0));
+  ASSERT_THAT(metrics[1].stats.stddev, std::nullopt);
+  ASSERT_THAT(metrics[1].stats.min, std::optional<double>(10.0));
+  ASSERT_THAT(metrics[1].stats.max, std::optional<double>(10.0));
 }
 
 }  // namespace
diff --git a/api/test/metrics/stdout_metrics_exporter.cc b/api/test/metrics/stdout_metrics_exporter.cc
index 22243e7..16ea7d1 100644
--- a/api/test/metrics/stdout_metrics_exporter.cc
+++ b/api/test/metrics/stdout_metrics_exporter.cc
@@ -12,9 +12,9 @@
 #include <stdio.h>
 
 #include <cmath>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/test/metrics/metric.h"
 #include "rtc_base/strings/string_builder.h"
diff --git a/api/test/mock_audio_sink.h b/api/test/mock_audio_sink.h
index 6218b86..dcb01cc 100644
--- a/api/test/mock_audio_sink.h
+++ b/api/test/mock_audio_sink.h
@@ -13,8 +13,8 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/media_stream_interface.h"
 #include "test/gmock.h"
 
@@ -38,7 +38,7 @@
                int sample_rate,
                size_t number_of_channels,
                size_t number_of_frames,
-               absl::optional<int64_t> absolute_capture_timestamp_ms),
+               std::optional<int64_t> absolute_capture_timestamp_ms),
               (override));
 };
 
diff --git a/api/test/mock_data_channel.h b/api/test/mock_data_channel.h
index 8b8d56a..f30fa74 100644
--- a/api/test/mock_data_channel.h
+++ b/api/test/mock_data_channel.h
@@ -12,10 +12,10 @@
 #define API_TEST_MOCK_DATA_CHANNEL_H_
 
 #include <cstdint>
+#include <optional>
 #include <string>
 
 #include "absl/functional/any_invocable.h"
-#include "absl/types/optional.h"
 #include "api/data_channel_interface.h"
 #include "api/priority.h"
 #include "api/rtc_error.h"
@@ -43,8 +43,8 @@
   MOCK_METHOD(bool, ordered, (), (const, override));
   MOCK_METHOD(uint16_t, maxRetransmitTime, (), (const, override));
   MOCK_METHOD(uint16_t, maxRetransmits, (), (const, override));
-  MOCK_METHOD(absl::optional<int>, maxRetransmitsOpt, (), (const, override));
-  MOCK_METHOD(absl::optional<int>, maxPacketLifeTime, (), (const, override));
+  MOCK_METHOD(std::optional<int>, maxRetransmitsOpt, (), (const, override));
+  MOCK_METHOD(std::optional<int>, maxPacketLifeTime, (), (const, override));
   MOCK_METHOD(std::string, protocol, (), (const, override));
   MOCK_METHOD(bool, negotiated, (), (const, override));
   MOCK_METHOD(int, id, (), (const, override));
diff --git a/api/test/mock_encoder_selector.h b/api/test/mock_encoder_selector.h
index a54c4c1..bb5c3a0 100644
--- a/api/test/mock_encoder_selector.h
+++ b/api/test/mock_encoder_selector.h
@@ -11,7 +11,8 @@
 #ifndef API_TEST_MOCK_ENCODER_SELECTOR_H_
 #define API_TEST_MOCK_ENCODER_SELECTOR_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/data_rate.h"
 #include "api/video/render_resolution.h"
 #include "api/video_codecs/sdp_video_format.h"
@@ -28,17 +29,17 @@
               (const SdpVideoFormat& format),
               (override));
 
-  MOCK_METHOD(absl::optional<SdpVideoFormat>,
+  MOCK_METHOD(std::optional<SdpVideoFormat>,
               OnAvailableBitrate,
               (const DataRate& rate),
               (override));
 
-  MOCK_METHOD(absl::optional<SdpVideoFormat>,
+  MOCK_METHOD(std::optional<SdpVideoFormat>,
               OnResolutionChange,
               (const RenderResolution& resolution),
               (override));
 
-  MOCK_METHOD(absl::optional<SdpVideoFormat>, OnEncoderBroken, (), (override));
+  MOCK_METHOD(std::optional<SdpVideoFormat>, OnEncoderBroken, (), (override));
 };
 
 }  // namespace webrtc
diff --git a/api/test/mock_peerconnectioninterface.h b/api/test/mock_peerconnectioninterface.h
index 782e45e..2b985f4 100644
--- a/api/test/mock_peerconnectioninterface.h
+++ b/api/test/mock_peerconnectioninterface.h
@@ -13,11 +13,11 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/adaptation/resource.h"
 #include "api/candidate.h"
 #include "api/data_channel_interface.h"
@@ -223,7 +223,7 @@
               AddAdaptationResource,
               (rtc::scoped_refptr<Resource>),
               (override));
-  MOCK_METHOD(absl::optional<bool>, can_trickle_ice_candidates, (), (override));
+  MOCK_METHOD(std::optional<bool>, can_trickle_ice_candidates, (), (override));
   MOCK_METHOD(bool,
               StartRtcEventLog,
               (std::unique_ptr<RtcEventLogOutput>, int64_t),
diff --git a/api/test/mock_rtp_transceiver.h b/api/test/mock_rtp_transceiver.h
index f3dbec6..8bc2a6f 100644
--- a/api/test/mock_rtp_transceiver.h
+++ b/api/test/mock_rtp_transceiver.h
@@ -11,10 +11,10 @@
 #ifndef API_TEST_MOCK_RTP_TRANSCEIVER_H_
 #define API_TEST_MOCK_RTP_TRANSCEIVER_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/make_ref_counted.h"
 #include "api/media_types.h"
@@ -38,7 +38,7 @@
   }
 
   MOCK_METHOD(cricket::MediaType, media_type, (), (const, override));
-  MOCK_METHOD(absl::optional<std::string>, mid, (), (const, override));
+  MOCK_METHOD(std::optional<std::string>, mid, (), (const, override));
   MOCK_METHOD(rtc::scoped_refptr<RtpSenderInterface>,
               sender,
               (),
@@ -58,11 +58,11 @@
               SetDirectionWithError,
               (RtpTransceiverDirection new_direction),
               (override));
-  MOCK_METHOD(absl::optional<RtpTransceiverDirection>,
+  MOCK_METHOD(std::optional<RtpTransceiverDirection>,
               current_direction,
               (),
               (const, override));
-  MOCK_METHOD(absl::optional<RtpTransceiverDirection>,
+  MOCK_METHOD(std::optional<RtpTransceiverDirection>,
               fired_direction,
               (),
               (const, override));
diff --git a/api/test/mock_rtpreceiver.h b/api/test/mock_rtpreceiver.h
index b591db4..8f8c3b4 100644
--- a/api/test/mock_rtpreceiver.h
+++ b/api/test/mock_rtpreceiver.h
@@ -11,10 +11,10 @@
 #ifndef API_TEST_MOCK_RTPRECEIVER_H_
 #define API_TEST_MOCK_RTPRECEIVER_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/crypto/frame_decryptor_interface.h"
 #include "api/media_stream_interface.h"
 #include "api/media_types.h"
@@ -47,7 +47,7 @@
   MOCK_METHOD(void, SetObserver, (RtpReceiverObserverInterface*), (override));
   MOCK_METHOD(void,
               SetJitterBufferMinimumDelay,
-              (absl::optional<double>),
+              (std::optional<double>),
               (override));
   MOCK_METHOD(std::vector<RtpSource>, GetSources, (), (const, override));
   MOCK_METHOD(void,
diff --git a/api/test/mock_transformable_audio_frame.h b/api/test/mock_transformable_audio_frame.h
index 0bed626..899624b 100644
--- a/api/test/mock_transformable_audio_frame.h
+++ b/api/test/mock_transformable_audio_frame.h
@@ -12,9 +12,9 @@
 #define API_TEST_MOCK_TRANSFORMABLE_AUDIO_FRAME_H_
 
 #include <cstdint>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/frame_transformer_interface.h"
 #include "api/units/timestamp.h"
@@ -37,7 +37,7 @@
               GetContributingSources,
               (),
               (const override));
-  MOCK_METHOD(const absl::optional<uint16_t>,
+  MOCK_METHOD(const std::optional<uint16_t>,
               SequenceNumber,
               (),
               (const, override));
@@ -45,7 +45,7 @@
               GetDirection,
               (),
               (const, override));
-  MOCK_METHOD(absl::optional<uint64_t>,
+  MOCK_METHOD(std::optional<uint64_t>,
               AbsoluteCaptureTimestamp,
               (),
               (const, override));
@@ -53,9 +53,9 @@
               Type,
               (),
               (const, override));
-  MOCK_METHOD(absl::optional<uint8_t>, AudioLevel, (), (const, override));
+  MOCK_METHOD(std::optional<uint8_t>, AudioLevel, (), (const, override));
 
-  MOCK_METHOD(absl::optional<Timestamp>, ReceiveTime, (), (const, override));
+  MOCK_METHOD(std::optional<Timestamp>, ReceiveTime, (), (const, override));
 };
 
 }  // namespace webrtc
diff --git a/api/test/mock_transformable_video_frame.h b/api/test/mock_transformable_video_frame.h
index 2ec3579..27a063e 100644
--- a/api/test/mock_transformable_video_frame.h
+++ b/api/test/mock_transformable_video_frame.h
@@ -12,10 +12,10 @@
 #define API_TEST_MOCK_TRANSFORMABLE_VIDEO_FRAME_H_
 
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <type_traits>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/frame_transformer_interface.h"
 #include "api/units/timestamp.h"
@@ -45,7 +45,7 @@
               (const, override));
   MOCK_METHOD(std::string, GetMimeType, (), (const, override));
   MOCK_METHOD(VideoFrameMetadata, Metadata, (), (const, override));
-  MOCK_METHOD(absl::optional<Timestamp>,
+  MOCK_METHOD(std::optional<Timestamp>,
               GetCaptureTimeIdentifier,
               (),
               (const, override));
diff --git a/api/test/mock_video_decoder.h b/api/test/mock_video_decoder.h
index c252c24..8a391a4 100644
--- a/api/test/mock_video_decoder.h
+++ b/api/test/mock_video_decoder.h
@@ -12,8 +12,8 @@
 #define API_TEST_MOCK_VIDEO_DECODER_H_
 
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/video/encoded_image.h"
 #include "api/video/video_frame.h"
 #include "api/video_codecs/video_decoder.h"
@@ -38,8 +38,8 @@
   MOCK_METHOD(void,
               Decoded,
               (VideoFrame & decoded_image,  // NOLINT
-               absl::optional<int32_t> decode_time_ms,
-               absl::optional<uint8_t> qp),
+               std::optional<int32_t> decode_time_ms,
+               std::optional<uint8_t> qp),
               (override));
 };
 
diff --git a/api/test/neteq_simulator_factory.h b/api/test/neteq_simulator_factory.h
index 79e515f..220daa5 100644
--- a/api/test/neteq_simulator_factory.h
+++ b/api/test/neteq_simulator_factory.h
@@ -13,10 +13,10 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/neteq/neteq_factory.h"
 #include "api/test/neteq_simulator.h"
 
@@ -44,15 +44,15 @@
     // A WebRTC field trial string to be used during the simulation.
     std::string field_trial_string;
     // A filename for the generated output audio file.
-    absl::optional<std::string> output_audio_filename;
+    std::optional<std::string> output_audio_filename;
     // A filename for the python plot.
-    absl::optional<std::string> python_plot_filename;
+    std::optional<std::string> python_plot_filename;
     // A filename for the text log.
-    absl::optional<std::string> text_log_filename;
+    std::optional<std::string> text_log_filename;
     // A custom NetEqFactory can be used.
     NetEqFactory* neteq_factory = nullptr;
     // The SSRC to use for the simulation.
-    absl::optional<uint32_t> ssrc_filter;
+    std::optional<uint32_t> ssrc_filter;
   };
   std::unique_ptr<NetEqSimulator> CreateSimulatorFromFile(
       absl::string_view event_log_filename,
diff --git a/api/test/network_emulation/BUILD.gn b/api/test/network_emulation/BUILD.gn
index 809b1b3..30e88a0 100644
--- a/api/test/network_emulation/BUILD.gn
+++ b/api/test/network_emulation/BUILD.gn
@@ -55,7 +55,6 @@
     "../../units:data_size",
     "../../units:time_delta",
     "../../units:timestamp",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/api/test/network_emulation/network_emulation_interfaces.h b/api/test/network_emulation/network_emulation_interfaces.h
index c5831f1..1789e04 100644
--- a/api/test/network_emulation/network_emulation_interfaces.h
+++ b/api/test/network_emulation/network_emulation_interfaces.h
@@ -14,9 +14,9 @@
 #include <cstdint>
 #include <functional>
 #include <map>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/numerics/samples_stats_counter.h"
 #include "api/units/data_rate.h"
 #include "api/units/data_size.h"
@@ -263,12 +263,12 @@
   //
   // Returns the port, that should be used (it will be equals to desired, if
   // `desired_port` != 0 and is free or will be the one, selected by endpoint)
-  // or absl::nullopt if desired_port in used. Also fails if there are no more
+  // or std::nullopt if desired_port in used. Also fails if there are no more
   // free ports to bind to.
   //
   // The Bind- and Unbind-methods must not be called from within a bound
   // receiver's OnPacketReceived method.
-  virtual absl::optional<uint16_t> BindReceiver(
+  virtual std::optional<uint16_t> BindReceiver(
       uint16_t desired_port,
       EmulatedNetworkReceiverInterface* receiver) = 0;
   // Unbinds receiver from the specified port. Do nothing if no receiver was
diff --git a/api/test/network_emulation_manager.h b/api/test/network_emulation_manager.h
index aeb32e7..5e20be5 100644
--- a/api/test/network_emulation_manager.h
+++ b/api/test/network_emulation_manager.h
@@ -14,12 +14,12 @@
 #include <cstdint>
 #include <functional>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/field_trials_view.h"
 #include "api/packet_socket_factory.h"
@@ -69,11 +69,11 @@
   enum class IpAddressFamily { kIpv4, kIpv6 };
 
   // If specified will be used to name endpoint for logging purposes.
-  absl::optional<std::string> name = absl::nullopt;
+  std::optional<std::string> name = std::nullopt;
   IpAddressFamily generated_ip_family = IpAddressFamily::kIpv4;
   // If specified will be used as IP address for endpoint node. Must be unique
   // among all created nodes.
-  absl::optional<rtc::IPAddress> ip;
+  std::optional<rtc::IPAddress> ip;
   // Should endpoint be enabled or not, when it will be created.
   // Enabled endpoints will be available for webrtc to send packets.
   bool start_as_enabled = true;
diff --git a/api/test/pclf/BUILD.gn b/api/test/pclf/BUILD.gn
index 047bca8..2f3c2dd 100644
--- a/api/test/pclf/BUILD.gn
+++ b/api/test/pclf/BUILD.gn
@@ -51,7 +51,6 @@
     "../video:video_frame_writer",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -86,7 +85,6 @@
     "../../neteq:neteq_api",
     "../../transport:bitrate_settings",
     "../../units:time_delta",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -121,7 +119,6 @@
     "../../../rtc_base:ssl",
     "../../audio:audio_processing",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
diff --git a/api/test/pclf/media_configuration.cc b/api/test/pclf/media_configuration.cc
index bf60837..126e474 100644
--- a/api/test/pclf/media_configuration.cc
+++ b/api/test/pclf/media_configuration.cc
@@ -15,12 +15,12 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/test/video/video_frame_writer.h"
 #include "api/units/time_delta.h"
@@ -64,8 +64,8 @@
   RTC_CHECK_GE(target_layer_index, 0);
 }
 
-EmulatedSFUConfig::EmulatedSFUConfig(absl::optional<int> target_layer_index,
-                                     absl::optional<int> target_temporal_index)
+EmulatedSFUConfig::EmulatedSFUConfig(std::optional<int> target_layer_index,
+                                     std::optional<int> target_temporal_index)
     : target_layer_index(target_layer_index),
       target_temporal_index(target_temporal_index) {
   RTC_CHECK_GE(target_temporal_index.value_or(0), 0);
@@ -127,7 +127,7 @@
     const VideoResolution& resolution) const {
   std::unique_ptr<test::VideoFrameWriter> writer = video_frame_writer_factory_(
       GetInputDumpFileName(stream_label, resolution), resolution);
-  absl::optional<std::string> frame_ids_file =
+  std::optional<std::string> frame_ids_file =
       GetInputFrameIdsDumpFileName(stream_label, resolution);
   if (frame_ids_file.has_value()) {
     writer = CreateVideoFrameWithIdsWriter(std::move(writer), *frame_ids_file);
@@ -142,7 +142,7 @@
     const VideoResolution& resolution) const {
   std::unique_ptr<test::VideoFrameWriter> writer = video_frame_writer_factory_(
       GetOutputDumpFileName(stream_label, receiver, resolution), resolution);
-  absl::optional<std::string> frame_ids_file =
+  std::optional<std::string> frame_ids_file =
       GetOutputFrameIdsDumpFileName(stream_label, receiver, resolution);
   if (frame_ids_file.has_value()) {
     writer = CreateVideoFrameWithIdsWriter(std::move(writer), *frame_ids_file);
@@ -168,11 +168,11 @@
   return test::JoinFilename(output_directory_, file_name.Release());
 }
 
-absl::optional<std::string> VideoDumpOptions::GetInputFrameIdsDumpFileName(
+std::optional<std::string> VideoDumpOptions::GetInputFrameIdsDumpFileName(
     absl::string_view stream_label,
     const VideoResolution& resolution) const {
   if (!export_frame_ids_) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return GetInputDumpFileName(stream_label, resolution) + ".frame_ids.txt";
 }
@@ -187,12 +187,12 @@
   return test::JoinFilename(output_directory_, file_name.Release());
 }
 
-absl::optional<std::string> VideoDumpOptions::GetOutputFrameIdsDumpFileName(
+std::optional<std::string> VideoDumpOptions::GetOutputFrameIdsDumpFileName(
     absl::string_view stream_label,
     absl::string_view receiver,
     const VideoResolution& resolution) const {
   if (!export_frame_ids_) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return GetOutputDumpFileName(stream_label, receiver, resolution) +
          ".frame_ids.txt";
@@ -231,7 +231,7 @@
     std::map<std::string, std::string> required_params)
     : name(name), required_params(std::move(required_params)) {}
 
-absl::optional<VideoResolution> VideoSubscription::GetMaxResolution(
+std::optional<VideoResolution> VideoSubscription::GetMaxResolution(
     rtc::ArrayView<const VideoConfig> video_configs) {
   std::vector<VideoResolution> resolutions;
   for (const auto& video_config : video_configs) {
@@ -240,10 +240,10 @@
   return GetMaxResolution(resolutions);
 }
 
-absl::optional<VideoResolution> VideoSubscription::GetMaxResolution(
+std::optional<VideoResolution> VideoSubscription::GetMaxResolution(
     rtc::ArrayView<const VideoResolution> resolutions) {
   if (resolutions.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   VideoResolution max_resolution;
@@ -282,7 +282,7 @@
   return *this;
 }
 
-absl::optional<VideoResolution> VideoSubscription::GetResolutionForPeer(
+std::optional<VideoResolution> VideoSubscription::GetResolutionForPeer(
     absl::string_view peer_name) const {
   auto it = peers_resolution_.find(std::string(peer_name));
   if (it == peers_resolution_.end()) {
diff --git a/api/test/pclf/media_configuration.h b/api/test/pclf/media_configuration.h
index aba8040..32b0d21 100644
--- a/api/test/pclf/media_configuration.h
+++ b/api/test/pclf/media_configuration.h
@@ -16,11 +16,11 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio_options.h"
 #include "api/media_stream_interface.h"
@@ -79,7 +79,7 @@
   bool generate_slides = false;
   // If present scrolling will be applied. Please read extra requirement on
   // `slides_yuv_file_names` for scrolling.
-  absl::optional<ScrollingParams> scrolling_params;
+  std::optional<ScrollingParams> scrolling_params;
   // Contains list of yuv files with slides.
   //
   // If empty, default set of slides will be used. In such case
@@ -130,8 +130,8 @@
 struct EmulatedSFUConfig {
   EmulatedSFUConfig() = default;
   explicit EmulatedSFUConfig(int target_layer_index);
-  EmulatedSFUConfig(absl::optional<int> target_layer_index,
-                    absl::optional<int> target_temporal_index);
+  EmulatedSFUConfig(std::optional<int> target_layer_index,
+                    std::optional<int> target_temporal_index);
 
   // Specifies simulcast or spatial index of the video stream to analyze.
   // There are 2 cases:
@@ -146,12 +146,12 @@
   // If not specified then all streams will be received and analyzed.
   // When set, it instructs the framework to create an emulated Selective
   // Forwarding Unit (SFU) that will propagate only the requested layers.
-  absl::optional<int> target_layer_index;
+  std::optional<int> target_layer_index;
   // Specifies the index of the maximum temporal unit to keep.
   // If not specified then all temporal layers will be received and analyzed.
   // When set, it instructs the framework to create an emulated Selective
   // Forwarding Unit (SFU) that will propagate only up to the requested layer.
-  absl::optional<int> target_temporal_index;
+  std::optional<int> target_temporal_index;
 };
 
 class VideoResolution {
@@ -252,16 +252,16 @@
   std::string GetInputDumpFileName(absl::string_view stream_label,
                                    const VideoResolution& resolution) const;
   // Returns file name for input frame ids dump if `export_frame_ids()` is
-  // true, absl::nullopt otherwise.
-  absl::optional<std::string> GetInputFrameIdsDumpFileName(
+  // true, std::nullopt otherwise.
+  std::optional<std::string> GetInputFrameIdsDumpFileName(
       absl::string_view stream_label,
       const VideoResolution& resolution) const;
   std::string GetOutputDumpFileName(absl::string_view stream_label,
                                     absl::string_view receiver,
                                     const VideoResolution& resolution) const;
   // Returns file name for output frame ids dump if `export_frame_ids()` is
-  // true, absl::nullopt otherwise.
-  absl::optional<std::string> GetOutputFrameIdsDumpFileName(
+  // true, std::nullopt otherwise.
+  std::optional<std::string> GetOutputFrameIdsDumpFileName(
       absl::string_view stream_label,
       absl::string_view receiver,
       const VideoResolution& resolution) const;
@@ -295,10 +295,10 @@
 
   // Have to be unique among all specified configs for all peers in the call.
   // Will be auto generated if omitted.
-  absl::optional<std::string> stream_label;
+  std::optional<std::string> stream_label;
   // Will be set for current video track. If equals to kText or kDetailed -
   // screencast in on.
-  absl::optional<VideoTrackInterface::ContentHint> content_hint;
+  std::optional<VideoTrackInterface::ContentHint> content_hint;
   // If presented video will be transfered in simulcast/SVC mode depending on
   // which encoder is used.
   //
@@ -307,9 +307,9 @@
   // simulcast tracks. For VP9 simulcast enables VP9 SVC mode and support RTX,
   // but only on non-lossy networks. See more in documentation to
   // VideoSimulcastConfig.
-  absl::optional<VideoSimulcastConfig> simulcast_config;
+  std::optional<VideoSimulcastConfig> simulcast_config;
   // Configuration for the emulated Selective Forward Unit (SFU).
-  absl::optional<EmulatedSFUConfig> emulated_sfu_config;
+  std::optional<EmulatedSFUConfig> emulated_sfu_config;
   // Encoding parameters for both singlecast and per simulcast layer.
   // If singlecast is used, if not empty, a single value can be provided.
   // If simulcast is used, if not empty, `encoding_params` size have to be
@@ -321,16 +321,16 @@
   // Count of temporal layers for video stream. This value will be set into
   // each RtpEncodingParameters of RtpParameters of corresponding
   // RtpSenderInterface for this video stream.
-  absl::optional<int> temporal_layers_count;
+  std::optional<int> temporal_layers_count;
   // If specified defines how input should be dumped. It is actually one of
   // the test's output file, which contains copy of what was captured during
   // the test for this video stream on sender side. It is useful when
   // generator is used as input.
-  absl::optional<VideoDumpOptions> input_dump_options;
+  std::optional<VideoDumpOptions> input_dump_options;
   // If specified defines how output should be dumped on the receiver side for
   // this stream. The produced files contain what was rendered for this video
   // stream on receiver side per each receiver.
-  absl::optional<VideoDumpOptions> output_dump_options;
+  std::optional<VideoDumpOptions> output_dump_options;
   // If set to true uses fixed frame rate while dumping output video to the
   // file. Requested `VideoSubscription::fps()` will be used as frame rate.
   bool output_dump_use_fixed_framerate = false;
@@ -339,11 +339,11 @@
   // If specified, determines a sync group to which this video stream belongs.
   // According to bugs.webrtc.org/4762 WebRTC supports synchronization only
   // for pair of single audio and single video stream.
-  absl::optional<std::string> sync_group;
+  std::optional<std::string> sync_group;
   // If specified, it will be set into RtpParameters of corresponding
   // RtpSenderInterface for this video stream.
   // Note that this setting takes precedence over `content_hint`.
-  absl::optional<DegradationPreference> degradation_preference;
+  std::optional<DegradationPreference> degradation_preference;
 };
 
 // Contains properties for audio in the call.
@@ -353,13 +353,13 @@
 
   // Have to be unique among all specified configs for all peers in the call.
   // Will be auto generated if omitted.
-  absl::optional<std::string> stream_label;
+  std::optional<std::string> stream_label;
   // If no file is specified an audio will be generated.
-  absl::optional<std::string> input_file_name;
+  std::optional<std::string> input_file_name;
   // If specified the input stream will be also copied to specified file.
-  absl::optional<std::string> input_dump_file_name;
+  std::optional<std::string> input_dump_file_name;
   // If specified the output stream will be copied to specified file.
-  absl::optional<std::string> output_dump_file_name;
+  std::optional<std::string> output_dump_file_name;
 
   // Audio options to use.
   cricket::AudioOptions audio_options;
@@ -368,7 +368,7 @@
   // If specified, determines a sync group to which this audio stream belongs.
   // According to bugs.webrtc.org/4762 WebRTC supports synchronization only
   // for pair of single audio and single video stream.
-  absl::optional<std::string> sync_group;
+  std::optional<std::string> sync_group;
 };
 
 struct VideoCodecConfig {
@@ -396,9 +396,9 @@
  public:
   // Returns the resolution constructed as maximum from all resolution
   // dimensions: width, height and fps.
-  static absl::optional<VideoResolution> GetMaxResolution(
+  static std::optional<VideoResolution> GetMaxResolution(
       rtc::ArrayView<const VideoConfig> video_configs);
-  static absl::optional<VideoResolution> GetMaxResolution(
+  static std::optional<VideoResolution> GetMaxResolution(
       rtc::ArrayView<const VideoResolution> resolutions);
 
   bool operator==(const VideoSubscription& other) const;
@@ -422,9 +422,9 @@
 
   // Returns resolution for specific sender. If no specific resolution was
   // set for this sender, then will return resolution used for all streams.
-  // If subscription doesn't subscribe to all streams, `absl::nullopt` will be
+  // If subscription doesn't subscribe to all streams, `std::nullopt` will be
   // returned.
-  absl::optional<VideoResolution> GetResolutionForPeer(
+  std::optional<VideoResolution> GetResolutionForPeer(
       absl::string_view peer_name) const;
 
   // Returns a maybe empty list of senders for which peer explicitly
@@ -434,7 +434,7 @@
   std::string ToString() const;
 
  private:
-  absl::optional<VideoResolution> default_resolution_ = absl::nullopt;
+  std::optional<VideoResolution> default_resolution_ = std::nullopt;
   std::map<std::string, VideoResolution> peers_resolution_;
 };
 
diff --git a/api/test/pclf/media_quality_test_params.h b/api/test/pclf/media_quality_test_params.h
index cf0a51e..56c4c1b 100644
--- a/api/test/pclf/media_quality_test_params.h
+++ b/api/test/pclf/media_quality_test_params.h
@@ -13,10 +13,10 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/async_dns_resolver.h"
 #include "api/audio/audio_mixer.h"
 #include "api/audio/audio_processing.h"
@@ -125,18 +125,18 @@
 // to set up peer connection.
 struct Params {
   // Peer name. If empty - default one will be set by the fixture.
-  absl::optional<std::string> name;
+  std::optional<std::string> name;
   // If `audio_config` is set audio stream will be configured
-  absl::optional<AudioConfig> audio_config;
+  std::optional<AudioConfig> audio_config;
   // Flags to set on `cricket::PortAllocator`. These flags will be added
   // to the default ones that are presented on the port allocator.
   uint32_t port_allocator_extra_flags = cricket::kDefaultPortAllocatorFlags;
   // If `rtc_event_log_path` is set, an RTCEventLog will be saved in that
   // location and it will be available for further analysis.
-  absl::optional<std::string> rtc_event_log_path;
+  std::optional<std::string> rtc_event_log_path;
   // If `aec_dump_path` is set, an AEC dump will be saved in that location and
   // it will be available for further analysis.
-  absl::optional<std::string> aec_dump_path;
+  std::optional<std::string> aec_dump_path;
 
   bool use_ulp_fec = false;
   bool use_flex_fec = false;
@@ -190,7 +190,7 @@
   // If specified echo emulation will be done, by mixing the render audio into
   // the capture signal. In such case input signal will be reduced by half to
   // avoid saturation or compression in the echo path simulation.
-  absl::optional<EchoEmulationConfig> echo_emulation_config;
+  std::optional<EchoEmulationConfig> echo_emulation_config;
 };
 
 }  // namespace webrtc_pc_e2e
diff --git a/api/test/pclf/peer_configurer.cc b/api/test/pclf/peer_configurer.cc
index 765ec2d..a19e250 100644
--- a/api/test/pclf/peer_configurer.cc
+++ b/api/test/pclf/peer_configurer.cc
@@ -12,12 +12,12 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/async_dns_resolver.h"
 #include "api/audio/audio_mixer.h"
 #include "api/audio/audio_processing.h"
@@ -122,7 +122,7 @@
 
 PeerConfigurer* PeerConfigurer::AddVideoConfig(VideoConfig config) {
   video_sources_.push_back(
-      CreateSquareFrameGenerator(config, /*type=*/absl::nullopt));
+      CreateSquareFrameGenerator(config, /*type=*/std::nullopt));
   configurable_params_->video_configs.push_back(std::move(config));
   return this;
 }
diff --git a/api/test/peerconnection_quality_test_fixture_unittest.cc b/api/test/peerconnection_quality_test_fixture_unittest.cc
index cd3dbb2..970fbf6 100644
--- a/api/test/peerconnection_quality_test_fixture_unittest.cc
+++ b/api/test/peerconnection_quality_test_fixture_unittest.cc
@@ -10,11 +10,11 @@
 
 #include <cstddef>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/test/pclf/media_configuration.h"
 #include "api/test/video/video_frame_writer.h"
 #include "api/video/video_frame.h"
@@ -60,7 +60,7 @@
 }
 
 TEST(PclfVideoSubscriptionTest, GetMaxResolutionForEmptyReturnsNullopt) {
-  absl::optional<VideoResolution> resolution =
+  std::optional<VideoResolution> resolution =
       VideoSubscription::GetMaxResolution(std::vector<VideoConfig>{});
   ASSERT_FALSE(resolution.has_value());
 }
@@ -70,7 +70,7 @@
   VideoConfig max_height(/*width=*/1, /*height=*/100, /*fps=*/1);
   VideoConfig max_fps(/*width=*/1, /*height=*/1, /*fps=*/10);
 
-  absl::optional<VideoResolution> resolution =
+  std::optional<VideoResolution> resolution =
       VideoSubscription::GetMaxResolution(
           std::vector<VideoConfig>{max_width, max_height, max_fps});
   ASSERT_TRUE(resolution.has_value());
diff --git a/api/test/simulated_network.h b/api/test/simulated_network.h
index 618fe71..245b8f0 100644
--- a/api/test/simulated_network.h
+++ b/api/test/simulated_network.h
@@ -15,10 +15,10 @@
 #include <stdint.h>
 
 #include <functional>
+#include <optional>
 #include <vector>
 
 #include "absl/functional/any_invocable.h"
-#include "absl/types/optional.h"
 #include "api/units/data_rate.h"
 
 namespace webrtc {
@@ -116,7 +116,7 @@
   // possible that no packet will be delivered by that time (e.g. in case of
   // random extra delay), in such case this method should be called again to get
   // the updated estimated delivery time.
-  virtual absl::optional<int64_t> NextDeliveryTimeUs() const = 0;
+  virtual std::optional<int64_t> NextDeliveryTimeUs() const = 0;
   // Registers a callback that should be triggered by an implementation if the
   // next NextDeliveryTimeUs() has changed between a call to NextDeliveryTimeUs
   // and DequeueDeliverablePackets.
diff --git a/api/test/video/BUILD.gn b/api/test/video/BUILD.gn
index 61af6b0..f1f8db6 100644
--- a/api/test/video/BUILD.gn
+++ b/api/test/video/BUILD.gn
@@ -46,6 +46,5 @@
     "../../../rtc_base/system:no_unique_address",
     "../../video:recordable_encoded_frame",
     "../../video:video_frame",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
diff --git a/api/test/video/test_video_track_source.cc b/api/test/video/test_video_track_source.cc
index fd7f18b..6eaf0b9 100644
--- a/api/test/video/test_video_track_source.cc
+++ b/api/test/video/test_video_track_source.cc
@@ -9,10 +9,10 @@
  */
 #include "api/test/video/test_video_track_source.h"
 
+#include <optional>
 #include <string>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/media_stream_interface.h"
 #include "api/sequence_checker.h"
 #include "api/video/video_frame.h"
@@ -25,7 +25,7 @@
 
 TestVideoTrackSource::TestVideoTrackSource(
     bool remote,
-    absl::optional<std::string> stream_label)
+    std::optional<std::string> stream_label)
     : stream_label_(std::move(stream_label)),
       state_(kInitializing),
       remote_(remote) {
diff --git a/api/test/video/test_video_track_source.h b/api/test/video/test_video_track_source.h
index 173bb64..95daccf 100644
--- a/api/test/video/test_video_track_source.h
+++ b/api/test/video/test_video_track_source.h
@@ -11,9 +11,9 @@
 #ifndef API_TEST_VIDEO_TEST_VIDEO_TRACK_SOURCE_H_
 #define API_TEST_VIDEO_TEST_VIDEO_TRACK_SOURCE_H_
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/media_stream_interface.h"
 #include "api/notifier.h"
 #include "api/sequence_checker.h"
@@ -32,7 +32,7 @@
  public:
   explicit TestVideoTrackSource(
       bool remote,
-      absl::optional<std::string> stream_label = absl::nullopt);
+      std::optional<std::string> stream_label = std::nullopt);
   ~TestVideoTrackSource() override = default;
 
   void SetState(SourceState new_state);
@@ -41,9 +41,7 @@
   bool remote() const override { return remote_; }
 
   bool is_screencast() const override { return false; }
-  absl::optional<bool> needs_denoising() const override {
-    return absl::nullopt;
-  }
+  std::optional<bool> needs_denoising() const override { return std::nullopt; }
 
   bool GetStats(Stats* stats) override { return false; }
 
@@ -74,17 +72,17 @@
 
   virtual void OnOutputFormatRequest(int width,
                                      int height,
-                                     const absl::optional<int>& max_fps) {}
+                                     const std::optional<int>& max_fps) {}
 
   // Returns stream label for this video source if present. Implementations
   // may override this method to increase debugability and testability.
-  virtual absl::optional<std::string> GetStreamLabel() { return stream_label_; }
+  virtual std::optional<std::string> GetStreamLabel() { return stream_label_; }
 
  protected:
   virtual rtc::VideoSourceInterface<VideoFrame>* source() = 0;
 
  private:
-  const absl::optional<std::string> stream_label_;
+  const std::optional<std::string> stream_label_;
   RTC_NO_UNIQUE_ADDRESS SequenceChecker worker_thread_checker_;
   RTC_NO_UNIQUE_ADDRESS SequenceChecker signaling_thread_checker_;
   SourceState state_ RTC_GUARDED_BY(&signaling_thread_checker_);
diff --git a/api/test/video_quality_analyzer_interface.h b/api/test/video_quality_analyzer_interface.h
index 6e69ede..8c9498f 100644
--- a/api/test/video_quality_analyzer_interface.h
+++ b/api/test/video_quality_analyzer_interface.h
@@ -12,10 +12,10 @@
 #define API_TEST_VIDEO_QUALITY_ANALYZER_INTERFACE_H_
 
 #include <cstdint>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/scoped_refptr.h"
 #include "api/stats/rtc_stats_report.h"
@@ -73,9 +73,9 @@
     std::string decoder_name = "unknown";
     // Decode time provided by decoder itself. If decoder doesn’t produce such
     // information can be omitted.
-    absl::optional<int32_t> decode_time_ms = absl::nullopt;
+    std::optional<int32_t> decode_time_ms = std::nullopt;
     // Decoder quantizer value.
-    absl::optional<uint8_t> qp = absl::nullopt;
+    std::optional<uint8_t> qp = std::nullopt;
   };
 
   ~VideoQualityAnalyzerInterface() override = default;
diff --git a/api/test/video_quality_test_fixture.h b/api/test/video_quality_test_fixture.h
index 0302e89..763dd7d 100644
--- a/api/test/video_quality_test_fixture.h
+++ b/api/test/video_quality_test_fixture.h
@@ -15,10 +15,10 @@
 #include <cstdint>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/fec_controller.h"
 #include "api/media_types.h"
 #include "api/network_state_predictor.h"
@@ -74,7 +74,7 @@
       bool sync_video = false;
       bool dtx = false;
       bool use_real_adm = false;
-      absl::optional<std::string> ana_config;
+      std::optional<std::string> ana_config;
     } audio;
     struct Screenshare {
       bool enabled = false;
@@ -95,7 +95,7 @@
     // `sender_network` and `receiver_network` in InjectionComponents are
     // non-null. May be nullopt even if `sender_network` and `receiver_network`
     // are null; in that case, a default config will be used.
-    absl::optional<BuiltInNetworkBehaviorConfig> config;
+    std::optional<BuiltInNetworkBehaviorConfig> config;
     struct SS {                          // Spatial scalability.
       std::vector<VideoStream> streams;  // If empty, one stream is assumed.
       size_t selected_stream = 0;
diff --git a/api/test/videocodec_test_fixture.h b/api/test/videocodec_test_fixture.h
index dd39c4f..42c3303 100644
--- a/api/test/videocodec_test_fixture.h
+++ b/api/test/videocodec_test_fixture.h
@@ -12,10 +12,10 @@
 #define API_TEST_VIDEOCODEC_TEST_FIXTURE_H_
 
 #include <cstddef>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/test/videocodec_test_stats.h"
 #include "api/video/encoded_image.h"
 #include "api/video/video_codec_type.h"
@@ -95,15 +95,15 @@
     std::string filename;
     // Dimensions of test clip. Falls back to (codec_settings.width/height) if
     // not set.
-    absl::optional<int> clip_width;
-    absl::optional<int> clip_height;
+    std::optional<int> clip_width;
+    std::optional<int> clip_height;
     // Framerate of input clip. Defaults to 30fps if not set.
-    absl::optional<int> clip_fps;
+    std::optional<int> clip_fps;
 
     // The resolution at which psnr/ssim comparisons should be made. Frames
     // will be scaled to this size if different.
-    absl::optional<int> reference_width;
-    absl::optional<int> reference_height;
+    std::optional<int> reference_width;
+    std::optional<int> reference_height;
 
     // File to process. This must be a video file in the YUV format.
     std::string filepath;
@@ -138,8 +138,8 @@
     // default `SdpVideoFormat` based on `codec_name`.
     // Encoder and decoder name (`SdpVideoFormat::name`) should be the same as
     // `codec_name`.
-    absl::optional<SdpVideoFormat> encoder_format;
-    absl::optional<SdpVideoFormat> decoder_format;
+    std::optional<SdpVideoFormat> encoder_format;
+    std::optional<SdpVideoFormat> decoder_format;
 
     // H.264 specific settings.
     struct H264CodecSettings {
diff --git a/api/transport/BUILD.gn b/api/transport/BUILD.gn
index 991a0d3..7d19c60 100644
--- a/api/transport/BUILD.gn
+++ b/api/transport/BUILD.gn
@@ -14,10 +14,7 @@
     "bitrate_settings.cc",
     "bitrate_settings.h",
   ]
-  deps = [
-    "../../rtc_base/system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
-  ]
+  deps = [ "../../rtc_base/system:rtc_export" ]
 }
 
 rtc_source_set("bandwidth_usage") {
@@ -54,7 +51,6 @@
     "../units:time_delta",
     "../units:timestamp",
     "//third_party/abseil-cpp/absl/base:core_headers",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -80,7 +76,6 @@
     "..:priority",
     "..:rtc_error",
     "../../rtc_base:copy_on_write_buffer",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/api/transport/bitrate_settings.h b/api/transport/bitrate_settings.h
index f0dcbb8..9bcd694 100644
--- a/api/transport/bitrate_settings.h
+++ b/api/transport/bitrate_settings.h
@@ -11,8 +11,8 @@
 #ifndef API_TRANSPORT_BITRATE_SETTINGS_H_
 #define API_TRANSPORT_BITRATE_SETTINGS_H_
 
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
@@ -27,9 +27,9 @@
   ~BitrateSettings();
   BitrateSettings(const BitrateSettings&);
   // 0 <= min <= start <= max should hold for set parameters.
-  absl::optional<int> min_bitrate_bps;
-  absl::optional<int> start_bitrate_bps;
-  absl::optional<int> max_bitrate_bps;
+  std::optional<int> min_bitrate_bps;
+  std::optional<int> start_bitrate_bps;
+  std::optional<int> max_bitrate_bps;
 };
 
 // TODO(srte): BitrateConstraints and BitrateSettings should be merged.
diff --git a/api/transport/data_channel_transport_interface.h b/api/transport/data_channel_transport_interface.h
index ad83544..ddf6147 100644
--- a/api/transport/data_channel_transport_interface.h
+++ b/api/transport/data_channel_transport_interface.h
@@ -13,8 +13,8 @@
 #define API_TRANSPORT_DATA_CHANNEL_TRANSPORT_INTERFACE_H_
 
 #include <cstddef>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/priority.h"
 #include "api/rtc_error.h"
 #include "rtc_base/copy_on_write_buffer.h"
@@ -49,14 +49,14 @@
   // Setting this value to zero disables retransmission.
   // Valid values are in the range [0-UINT16_MAX].
   // `max_rtx_count` and `max_rtx_ms` may not be set simultaneously.
-  absl::optional<int> max_rtx_count;
+  std::optional<int> max_rtx_count;
 
   // If set, the maximum number of milliseconds for which the transport
   // may retransmit this message before it is dropped.
   // Setting this value to zero disables retransmission.
   // Valid values are in the range [0-UINT16_MAX].
   // `max_rtx_count` and `max_rtx_ms` may not be set simultaneously.
-  absl::optional<int> max_rtx_ms;
+  std::optional<int> max_rtx_ms;
 };
 
 // Sink for callbacks related to a data channel.
diff --git a/api/transport/network_control.h b/api/transport/network_control.h
index de408a5..90cdebe 100644
--- a/api/transport/network_control.h
+++ b/api/transport/network_control.h
@@ -12,9 +12,9 @@
 #define API_TRANSPORT_NETWORK_CONTROL_H_
 
 #include <memory>
+#include <optional>
 
 #include "absl/base/attributes.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/field_trials_view.h"
 #include "api/transport/network_types.h"
@@ -118,7 +118,7 @@
 class NetworkStateEstimator {
  public:
   // Gets the current best estimate according to the estimator.
-  virtual absl::optional<NetworkStateEstimate> GetCurrentEstimate() = 0;
+  virtual std::optional<NetworkStateEstimate> GetCurrentEstimate() = 0;
   // Called with per packet feedback regarding receive time.
   // Used when the NetworkStateEstimator runs in the sending endpoint.
   virtual void OnTransportPacketsFeedback(const TransportPacketsFeedback&) = 0;
diff --git a/api/transport/network_types.h b/api/transport/network_types.h
index ebf09ef..57fa657 100644
--- a/api/transport/network_types.h
+++ b/api/transport/network_types.h
@@ -13,9 +13,9 @@
 #include <stdint.h>
 
 #include <cmath>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/units/data_rate.h"
 #include "api/units/data_size.h"
 #include "api/units/time_delta.h"
@@ -47,17 +47,17 @@
   StreamsConfig(const StreamsConfig&);
   ~StreamsConfig();
   Timestamp at_time = Timestamp::PlusInfinity();
-  absl::optional<bool> requests_alr_probing;
+  std::optional<bool> requests_alr_probing;
   // If `enable_repeated_initial_probing` is set to true, Probes are sent
   // periodically every 1s during the first 5s after the network becomes
   // available. The probes ignores max_total_allocated_bitrate.
-  absl::optional<bool> enable_repeated_initial_probing;
-  absl::optional<double> pacing_factor;
+  std::optional<bool> enable_repeated_initial_probing;
+  std::optional<double> pacing_factor;
 
   // TODO(srte): Use BitrateAllocationLimits here.
-  absl::optional<DataRate> min_total_allocated_bitrate;
-  absl::optional<DataRate> max_padding_rate;
-  absl::optional<DataRate> max_total_allocated_bitrate;
+  std::optional<DataRate> min_total_allocated_bitrate;
+  std::optional<DataRate> max_padding_rate;
+  std::optional<DataRate> max_total_allocated_bitrate;
 };
 
 struct RTC_EXPORT TargetRateConstraints {
@@ -65,11 +65,11 @@
   TargetRateConstraints(const TargetRateConstraints&);
   ~TargetRateConstraints();
   Timestamp at_time = Timestamp::PlusInfinity();
-  absl::optional<DataRate> min_data_rate;
-  absl::optional<DataRate> max_data_rate;
+  std::optional<DataRate> min_data_rate;
+  std::optional<DataRate> max_data_rate;
   // The initial bandwidth estimate to base target rate on. This should be used
   // as the basis for initial OnTargetTransferRate and OnPacerConfig callbacks.
-  absl::optional<DataRate> starting_rate;
+  std::optional<DataRate> starting_rate;
 };
 
 // Send side information
@@ -246,16 +246,16 @@
            !probe_cluster_configs.empty() || target_rate.has_value();
   }
 
-  absl::optional<DataSize> congestion_window;
-  absl::optional<PacerConfig> pacer_config;
+  std::optional<DataSize> congestion_window;
+  std::optional<PacerConfig> pacer_config;
   std::vector<ProbeClusterConfig> probe_cluster_configs;
-  absl::optional<TargetTransferRate> target_rate;
+  std::optional<TargetTransferRate> target_rate;
 };
 
 // Process control
 struct RTC_EXPORT ProcessInterval {
   Timestamp at_time = Timestamp::PlusInfinity();
-  absl::optional<DataSize> pacer_queue;
+  std::optional<DataSize> pacer_queue;
 };
 
 // Under development, subject to change without notice.
diff --git a/api/transport/rtp/BUILD.gn b/api/transport/rtp/BUILD.gn
index 3bcee82..c4c43fa 100644
--- a/api/transport/rtp/BUILD.gn
+++ b/api/transport/rtp/BUILD.gn
@@ -16,7 +16,6 @@
     "../../../api/units:time_delta",
     "../../../api/units:timestamp",
     "../../../rtc_base:checks",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -31,6 +30,5 @@
     "../../video:render_resolution",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
diff --git a/api/transport/rtp/dependency_descriptor.h b/api/transport/rtp/dependency_descriptor.h
index f546a0a..2ff5ed8 100644
--- a/api/transport/rtp/dependency_descriptor.h
+++ b/api/transport/rtp/dependency_descriptor.h
@@ -15,11 +15,11 @@
 
 #include <initializer_list>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "absl/container/inlined_vector.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/video/render_resolution.h"
 
 namespace webrtc {
@@ -109,8 +109,8 @@
   bool last_packet_in_frame = true;
   int frame_number = 0;
   FrameDependencyTemplate frame_dependencies;
-  absl::optional<RenderResolution> resolution;
-  absl::optional<uint32_t> active_decode_targets_bitmask;
+  std::optional<RenderResolution> resolution;
+  std::optional<uint32_t> active_decode_targets_bitmask;
   std::unique_ptr<FrameDependencyStructure> attached_structure;
 };
 
diff --git a/api/transport/rtp/rtp_source.h b/api/transport/rtp/rtp_source.h
index 9618973..4732044 100644
--- a/api/transport/rtp/rtp_source.h
+++ b/api/transport/rtp/rtp_source.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/rtp_headers.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -28,18 +29,18 @@
 class RtpSource {
  public:
   struct Extensions {
-    absl::optional<uint8_t> audio_level;
+    std::optional<uint8_t> audio_level;
 
     // Fields from the Absolute Capture Time header extension:
     // http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time
-    absl::optional<AbsoluteCaptureTime> absolute_capture_time;
+    std::optional<AbsoluteCaptureTime> absolute_capture_time;
 
     // Clock offset between the local clock and the capturer's clock.
     // Do not confuse with `AbsoluteCaptureTime::estimated_capture_clock_offset`
     // which instead represents the clock offset between a remote sender and the
     // capturer. The following holds:
     //   Capture's NTP Clock = Local NTP Clock + Local-Capture Clock Offset
-    absl::optional<TimeDelta> local_capture_clock_offset;
+    std::optional<TimeDelta> local_capture_clock_offset;
   };
 
   RtpSource() = delete;
@@ -67,21 +68,19 @@
   // The source can be either a contributing source or a synchronization source.
   RtpSourceType source_type() const { return source_type_; }
 
-  absl::optional<uint8_t> audio_level() const {
-    return extensions_.audio_level;
-  }
+  std::optional<uint8_t> audio_level() const { return extensions_.audio_level; }
 
-  void set_audio_level(const absl::optional<uint8_t>& level) {
+  void set_audio_level(const std::optional<uint8_t>& level) {
     extensions_.audio_level = level;
   }
 
   uint32_t rtp_timestamp() const { return rtp_timestamp_; }
 
-  absl::optional<AbsoluteCaptureTime> absolute_capture_time() const {
+  std::optional<AbsoluteCaptureTime> absolute_capture_time() const {
     return extensions_.absolute_capture_time;
   }
 
-  absl::optional<TimeDelta> local_capture_clock_offset() const {
+  std::optional<TimeDelta> local_capture_clock_offset() const {
     return extensions_.local_capture_clock_offset;
   }
 
diff --git a/api/transport/test/mock_network_control.h b/api/transport/test/mock_network_control.h
index e3a15b8..e672d2e 100644
--- a/api/transport/test/mock_network_control.h
+++ b/api/transport/test/mock_network_control.h
@@ -67,7 +67,7 @@
 
 class MockNetworkStateEstimator : public NetworkStateEstimator {
  public:
-  MOCK_METHOD(absl::optional<NetworkStateEstimate>,
+  MOCK_METHOD(std::optional<NetworkStateEstimate>,
               GetCurrentEstimate,
               (),
               (override));
diff --git a/api/video/BUILD.gn b/api/video/BUILD.gn
index 9351dea..866757e 100644
--- a/api/video/BUILD.gn
+++ b/api/video/BUILD.gn
@@ -35,7 +35,6 @@
     "../../rtc_base/system:rtc_export",
     "../units:data_rate",
     "../units:time_delta",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -75,7 +74,6 @@
     "../../rtc_base/system:rtc_export",
     "../units:time_delta",
     "../units:timestamp",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/libyuv",
   ]
 }
@@ -121,7 +119,6 @@
     "..:make_ref_counted",
     "..:scoped_refptr",
     "../units:timestamp",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -165,7 +162,6 @@
     "../../rtc_base:refcount",
     "../../rtc_base/system:rtc_export",
     "../units:timestamp",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -183,7 +179,6 @@
     "../../modules/video_coding:codec_globals_headers",
     "../../modules/video_coding:video_codec_interface",
     "../units:timestamp",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -213,7 +208,6 @@
     "../../rtc_base:rtc_numerics",
     "../transport/rtp:dependency_descriptor",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -235,7 +229,6 @@
     "../../rtc_base:checks",
     "../../test:test_support",
     "../transport/rtp:dependency_descriptor",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -257,7 +250,6 @@
     "../../rtc_base:safe_conversions",
     "../../rtc_base:stringutils",
     "../../rtc_base/system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -343,7 +335,6 @@
     "../../rtc_base/system:rtc_export",
     "../transport/rtp:dependency_descriptor",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -386,7 +377,6 @@
     "../../rtc_base:rtc_numerics",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -401,7 +391,6 @@
     "../../test:field_trial",
     "../../test:scoped_key_value_config",
     "../../test:test_support",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/api/video/color_space.cc b/api/video/color_space.cc
index 05c0135..99648a3 100644
--- a/api/video/color_space.cc
+++ b/api/video/color_space.cc
@@ -12,9 +12,9 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/video/hdr_metadata.h"
 #include "rtc_base/strings/string_builder.h"
 
@@ -101,8 +101,8 @@
       range_(range),
       chroma_siting_horizontal_(chroma_siting_horz),
       chroma_siting_vertical_(chroma_siting_vert),
-      hdr_metadata_(hdr_metadata ? absl::make_optional(*hdr_metadata)
-                                 : absl::nullopt) {}
+      hdr_metadata_(hdr_metadata ? std::make_optional(*hdr_metadata)
+                                 : std::nullopt) {}
 
 ColorSpace::PrimaryID ColorSpace::primaries() const {
   return primaries_;
@@ -263,7 +263,7 @@
 
 void ColorSpace::set_hdr_metadata(const HdrMetadata* hdr_metadata) {
   hdr_metadata_ =
-      hdr_metadata ? absl::make_optional(*hdr_metadata) : absl::nullopt;
+      hdr_metadata ? std::make_optional(*hdr_metadata) : std::nullopt;
 }
 
 }  // namespace webrtc
diff --git a/api/video/color_space.h b/api/video/color_space.h
index 31963a1..00f5cb9 100644
--- a/api/video/color_space.h
+++ b/api/video/color_space.h
@@ -13,9 +13,9 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/video/hdr_metadata.h"
 #include "rtc_base/system/rtc_export.h"
 
@@ -174,7 +174,7 @@
   RangeID range_ = RangeID::kInvalid;
   ChromaSiting chroma_siting_horizontal_ = ChromaSiting::kUnspecified;
   ChromaSiting chroma_siting_vertical_ = ChromaSiting::kUnspecified;
-  absl::optional<HdrMetadata> hdr_metadata_;
+  std::optional<HdrMetadata> hdr_metadata_;
 };
 
 }  // namespace webrtc
diff --git a/api/video/encoded_frame.cc b/api/video/encoded_frame.cc
index 023e233..8e90fa3 100644
--- a/api/video/encoded_frame.cc
+++ b/api/video/encoded_frame.cc
@@ -12,8 +12,8 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/units/timestamp.h"
 #include "api/video/video_codec_type.h"
@@ -24,16 +24,16 @@
 
 namespace webrtc {
 
-absl::optional<Timestamp> EncodedFrame::ReceivedTimestamp() const {
+std::optional<Timestamp> EncodedFrame::ReceivedTimestamp() const {
   return ReceivedTime() >= 0
-             ? absl::make_optional(Timestamp::Millis(ReceivedTime()))
-             : absl::nullopt;
+             ? std::make_optional(Timestamp::Millis(ReceivedTime()))
+             : std::nullopt;
 }
 
-absl::optional<Timestamp> EncodedFrame::RenderTimestamp() const {
+std::optional<Timestamp> EncodedFrame::RenderTimestamp() const {
   return RenderTimeMs() >= 0
-             ? absl::make_optional(Timestamp::Millis(RenderTimeMs()))
-             : absl::nullopt;
+             ? std::make_optional(Timestamp::Millis(RenderTimeMs()))
+             : std::nullopt;
 }
 
 bool EncodedFrame::delayed_by_retransmission() const {
diff --git a/api/video/encoded_frame.h b/api/video/encoded_frame.h
index 8905c36..0bb65cf 100644
--- a/api/video/encoded_frame.h
+++ b/api/video/encoded_frame.h
@@ -14,7 +14,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/timestamp.h"
 #include "api/video/encoded_image.h"
 #include "api/video/video_codec_type.h"
@@ -38,7 +39,7 @@
   virtual int64_t ReceivedTime() const { return -1; }
   // Returns a Timestamp from `ReceivedTime`, or nullopt if there is no receive
   // time.
-  absl::optional<webrtc::Timestamp> ReceivedTimestamp() const;
+  std::optional<webrtc::Timestamp> ReceivedTimestamp() const;
 
   // When this frame should be rendered.
   // TODO(bugs.webrtc.org/13756): Use Timestamp instead of int.
@@ -47,7 +48,7 @@
   int64_t RenderTimeMs() const { return _renderTimeMs; }
   // Returns a Timestamp from `RenderTime`, or nullopt if there is no
   // render time.
-  absl::optional<webrtc::Timestamp> RenderTimestamp() const;
+  std::optional<webrtc::Timestamp> RenderTimestamp() const;
 
   // This information is currently needed by the timing calculation class.
   // TODO(philipel): Remove this function when a new timing class has
diff --git a/api/video/encoded_image.cc b/api/video/encoded_image.cc
index a859250..3e6fa54 100644
--- a/api/video/encoded_image.cc
+++ b/api/video/encoded_image.cc
@@ -14,8 +14,8 @@
 
 #include <algorithm>
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/make_ref_counted.h"
 #include "api/scoped_refptr.h"
 #include "api/units/timestamp.h"
@@ -88,14 +88,14 @@
                               : Timestamp::MinusInfinity();
 }
 
-absl::optional<size_t> EncodedImage::SpatialLayerFrameSize(
+std::optional<size_t> EncodedImage::SpatialLayerFrameSize(
     int spatial_index) const {
   RTC_DCHECK_GE(spatial_index, 0);
   RTC_DCHECK_LE(spatial_index, spatial_index_.value_or(0));
 
   auto it = spatial_layer_frame_size_bytes_.find(spatial_index);
   if (it == spatial_layer_frame_size_bytes_.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return it->second;
diff --git a/api/video/encoded_image.h b/api/video/encoded_image.h
index ec4252e..a9147e1 100644
--- a/api/video/encoded_image.h
+++ b/api/video/encoded_image.h
@@ -15,9 +15,9 @@
 
 #include <cstddef>
 #include <map>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/ref_count.h"
 #include "api/rtp_packet_infos.h"
 #include "api/scoped_refptr.h"
@@ -97,33 +97,33 @@
 
   // Every simulcast layer (= encoding) has its own encoder and RTP stream.
   // There can be no dependencies between different simulcast layers.
-  absl::optional<int> SimulcastIndex() const { return simulcast_index_; }
-  void SetSimulcastIndex(absl::optional<int> simulcast_index) {
+  std::optional<int> SimulcastIndex() const { return simulcast_index_; }
+  void SetSimulcastIndex(std::optional<int> simulcast_index) {
     RTC_DCHECK_GE(simulcast_index.value_or(0), 0);
     RTC_DCHECK_LT(simulcast_index.value_or(0), kMaxSimulcastStreams);
     simulcast_index_ = simulcast_index;
   }
 
-  const absl::optional<Timestamp>& CaptureTimeIdentifier() const {
+  const std::optional<Timestamp>& CaptureTimeIdentifier() const {
     return capture_time_identifier_;
   }
   void SetCaptureTimeIdentifier(
-      const absl::optional<Timestamp>& capture_time_identifier) {
+      const std::optional<Timestamp>& capture_time_identifier) {
     capture_time_identifier_ = capture_time_identifier;
   }
 
   // Encoded images can have dependencies between spatial and/or temporal
   // layers, depending on the scalability mode used by the encoder. See diagrams
   // at https://w3c.github.io/webrtc-svc/#dependencydiagrams*.
-  absl::optional<int> SpatialIndex() const { return spatial_index_; }
-  void SetSpatialIndex(absl::optional<int> spatial_index) {
+  std::optional<int> SpatialIndex() const { return spatial_index_; }
+  void SetSpatialIndex(std::optional<int> spatial_index) {
     RTC_DCHECK_GE(spatial_index.value_or(0), 0);
     RTC_DCHECK_LT(spatial_index.value_or(0), kMaxSpatialLayers);
     spatial_index_ = spatial_index;
   }
 
-  absl::optional<int> TemporalIndex() const { return temporal_index_; }
-  void SetTemporalIndex(absl::optional<int> temporal_index) {
+  std::optional<int> TemporalIndex() const { return temporal_index_; }
+  void SetTemporalIndex(std::optional<int> temporal_index) {
     RTC_DCHECK_GE(temporal_index_.value_or(0), 0);
     RTC_DCHECK_LT(temporal_index_.value_or(0), kMaxTemporalStreams);
     temporal_index_ = temporal_index;
@@ -131,30 +131,30 @@
 
   // These methods can be used to set/get size of subframe with spatial index
   // `spatial_index` on encoded frames that consist of multiple spatial layers.
-  absl::optional<size_t> SpatialLayerFrameSize(int spatial_index) const;
+  std::optional<size_t> SpatialLayerFrameSize(int spatial_index) const;
   void SetSpatialLayerFrameSize(int spatial_index, size_t size_bytes);
 
   const webrtc::ColorSpace* ColorSpace() const {
     return color_space_ ? &*color_space_ : nullptr;
   }
-  void SetColorSpace(const absl::optional<webrtc::ColorSpace>& color_space) {
+  void SetColorSpace(const std::optional<webrtc::ColorSpace>& color_space) {
     color_space_ = color_space;
   }
 
-  absl::optional<VideoPlayoutDelay> PlayoutDelay() const {
+  std::optional<VideoPlayoutDelay> PlayoutDelay() const {
     return playout_delay_;
   }
 
-  void SetPlayoutDelay(absl::optional<VideoPlayoutDelay> playout_delay) {
+  void SetPlayoutDelay(std::optional<VideoPlayoutDelay> playout_delay) {
     playout_delay_ = playout_delay;
   }
 
   // These methods along with the private member video_frame_tracking_id_ are
   // meant for media quality testing purpose only.
-  absl::optional<uint16_t> VideoFrameTrackingId() const {
+  std::optional<uint16_t> VideoFrameTrackingId() const {
     return video_frame_tracking_id_;
   }
-  void SetVideoFrameTrackingId(absl::optional<uint16_t> tracking_id) {
+  void SetVideoFrameTrackingId(std::optional<uint16_t> tracking_id) {
     video_frame_tracking_id_ = tracking_id;
   }
 
@@ -255,20 +255,20 @@
 
   // When set, indicates that all future frames will be constrained with those
   // limits until the application indicates a change again.
-  absl::optional<VideoPlayoutDelay> playout_delay_;
+  std::optional<VideoPlayoutDelay> playout_delay_;
 
   rtc::scoped_refptr<EncodedImageBufferInterface> encoded_data_;
   size_t size_ = 0;  // Size of encoded frame data.
   uint32_t timestamp_rtp_ = 0;
-  absl::optional<int> simulcast_index_;
-  absl::optional<Timestamp> capture_time_identifier_;
-  absl::optional<int> spatial_index_;
-  absl::optional<int> temporal_index_;
+  std::optional<int> simulcast_index_;
+  std::optional<Timestamp> capture_time_identifier_;
+  std::optional<int> spatial_index_;
+  std::optional<int> temporal_index_;
   std::map<int, size_t> spatial_layer_frame_size_bytes_;
-  absl::optional<webrtc::ColorSpace> color_space_;
+  std::optional<webrtc::ColorSpace> color_space_;
   // This field is meant for media quality testing purpose only. When enabled it
   // carries the webrtc::VideoFrame id field from the sender to the receiver.
-  absl::optional<uint16_t> video_frame_tracking_id_;
+  std::optional<uint16_t> video_frame_tracking_id_;
   // Information about packets used to assemble this video frame. This is needed
   // by `SourceTracker` when the frame is delivered to the RTCRtpReceiver's
   // MediaStreamTrack, in order to implement getContributingSources(). See:
diff --git a/api/video/frame_buffer.cc b/api/video/frame_buffer.cc
index b99ab0c..fe9d4c3 100644
--- a/api/video/frame_buffer.cc
+++ b/api/video/frame_buffer.cc
@@ -15,11 +15,11 @@
 #include <cstdint>
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "absl/algorithm/container.h"
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/field_trials_view.h"
 #include "api/video/encoded_frame.h"
@@ -157,15 +157,15 @@
   FindNextAndLastDecodableTemporalUnit();
 }
 
-absl::optional<int64_t> FrameBuffer::LastContinuousFrameId() const {
+std::optional<int64_t> FrameBuffer::LastContinuousFrameId() const {
   return last_continuous_frame_id_;
 }
 
-absl::optional<int64_t> FrameBuffer::LastContinuousTemporalUnitFrameId() const {
+std::optional<int64_t> FrameBuffer::LastContinuousTemporalUnitFrameId() const {
   return last_continuous_temporal_unit_frame_id_;
 }
 
-absl::optional<FrameBuffer::DecodabilityInfo>
+std::optional<FrameBuffer::DecodabilityInfo>
 FrameBuffer::DecodableTemporalUnitsInfo() const {
   return decodable_temporal_units_info_;
 }
diff --git a/api/video/frame_buffer.h b/api/video/frame_buffer.h
index 7791770..e607a18 100644
--- a/api/video/frame_buffer.h
+++ b/api/video/frame_buffer.h
@@ -15,9 +15,9 @@
 #include <cstdint>
 #include <map>
 #include <memory>
+#include <optional>
 
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/video/encoded_frame.h"
 #include "modules/video_coding/utility/decoded_frames_history.h"
@@ -61,9 +61,9 @@
   // Drop all frames in the next decodable unit.
   void DropNextDecodableTemporalUnit();
 
-  absl::optional<int64_t> LastContinuousFrameId() const;
-  absl::optional<int64_t> LastContinuousTemporalUnitFrameId() const;
-  absl::optional<DecodabilityInfo> DecodableTemporalUnitsInfo() const;
+  std::optional<int64_t> LastContinuousFrameId() const;
+  std::optional<int64_t> LastContinuousTemporalUnitFrameId() const;
+  std::optional<DecodabilityInfo> DecodableTemporalUnitsInfo() const;
 
   int GetTotalNumberOfContinuousTemporalUnits() const;
   int GetTotalNumberOfDroppedFrames() const;
@@ -92,10 +92,10 @@
   const bool legacy_frame_id_jump_behavior_;
   const size_t max_size_;
   FrameMap frames_;
-  absl::optional<TemporalUnit> next_decodable_temporal_unit_;
-  absl::optional<DecodabilityInfo> decodable_temporal_units_info_;
-  absl::optional<int64_t> last_continuous_frame_id_;
-  absl::optional<int64_t> last_continuous_temporal_unit_frame_id_;
+  std::optional<TemporalUnit> next_decodable_temporal_unit_;
+  std::optional<DecodabilityInfo> decodable_temporal_units_info_;
+  std::optional<int64_t> last_continuous_frame_id_;
+  std::optional<int64_t> last_continuous_temporal_unit_frame_id_;
   video_coding::DecodedFramesHistory decoded_frame_history_;
 
   int num_continuous_temporal_units_ = 0;
diff --git a/api/video/frame_buffer_unittest.cc b/api/video/frame_buffer_unittest.cc
index 5d3341c..d97c7ec 100644
--- a/api/video/frame_buffer_unittest.cc
+++ b/api/video/frame_buffer_unittest.cc
@@ -9,9 +9,9 @@
  */
 #include "api/video/frame_buffer.h"
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "test/fake_encoded_frame.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
@@ -36,7 +36,7 @@
   // Ref must be less than the id of this frame.
   EXPECT_FALSE(buffer.InsertFrame(
       test::FakeFrameBuilder().Time(0).Id(0).Refs({0}).AsLast().Build()));
-  EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(absl::nullopt));
+  EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(std::nullopt));
 
   // Duplicate ids are also invalid.
   EXPECT_TRUE(buffer.InsertFrame(
@@ -50,13 +50,13 @@
   test::ScopedKeyValueConfig field_trials;
   FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
                      field_trials);
-  EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(absl::nullopt));
-  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
+  EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(std::nullopt));
+  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(std::nullopt));
 
   EXPECT_TRUE(
       buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).Build()));
   EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(1));
-  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
+  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(std::nullopt));
 
   EXPECT_TRUE(buffer.InsertFrame(
       test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).AsLast().Build()));
@@ -87,7 +87,7 @@
 
   EXPECT_TRUE(
       buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).Build()));
-  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
+  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(std::nullopt));
   EXPECT_TRUE(buffer.InsertFrame(
       test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).AsLast().Build()));
   EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(2));
@@ -104,7 +104,7 @@
       test::FakeFrameBuilder().Time(20).Id(3).Refs({1}).Build()));
   EXPECT_TRUE(buffer.InsertFrame(
       test::FakeFrameBuilder().Time(20).Id(4).Refs({2, 3}).AsLast().Build()));
-  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
+  EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(std::nullopt));
 
   EXPECT_TRUE(buffer.InsertFrame(
       test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).AsLast().Build()));
@@ -116,7 +116,7 @@
   FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
                      field_trials);
 
-  EXPECT_THAT(buffer.DecodableTemporalUnitsInfo(), Eq(absl::nullopt));
+  EXPECT_THAT(buffer.DecodableTemporalUnitsInfo(), Eq(std::nullopt));
   EXPECT_TRUE(buffer.InsertFrame(
       test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
   EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(10U));
diff --git a/api/video/recordable_encoded_frame.h b/api/video/recordable_encoded_frame.h
index 5b56561..a561d09 100644
--- a/api/video/recordable_encoded_frame.h
+++ b/api/video/recordable_encoded_frame.h
@@ -11,7 +11,8 @@
 #ifndef API_VIDEO_RECORDABLE_ENCODED_FRAME_H_
 #define API_VIDEO_RECORDABLE_ENCODED_FRAME_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/scoped_refptr.h"
 #include "api/units/timestamp.h"
 #include "api/video/color_space.h"
@@ -40,7 +41,7 @@
 
   // Optionally returns the colorspace of the encoded frame. This can differ
   // from the eventually decoded frame's colorspace.
-  virtual absl::optional<webrtc::ColorSpace> color_space() const = 0;
+  virtual std::optional<webrtc::ColorSpace> color_space() const = 0;
 
   // Returns the codec of the encoded frame
   virtual VideoCodecType codec() const = 0;
diff --git a/api/video/rtp_video_frame_assembler.cc b/api/video/rtp_video_frame_assembler.cc
index 4631824..5dcb8f3 100644
--- a/api/video/rtp_video_frame_assembler.cc
+++ b/api/video/rtp_video_frame_assembler.cc
@@ -12,11 +12,11 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/rtp_packet_infos.h"
 #include "api/scoped_refptr.h"
@@ -94,7 +94,7 @@
   std::unique_ptr<FrameDependencyStructure> video_structure_;
   SeqNumUnwrapper<uint16_t> rtp_sequence_number_unwrapper_;
   SeqNumUnwrapper<uint16_t> frame_id_unwrapper_;
-  absl::optional<int64_t> video_structure_frame_id_;
+  std::optional<int64_t> video_structure_frame_id_;
   std::unique_ptr<VideoRtpDepacketizer> depacketizer_;
   video_coding::PacketBuffer packet_buffer_;
   RtpFrameReferenceFinder reference_finder_;
@@ -112,10 +112,10 @@
     return UpdateWithPadding(rtp_packet.SequenceNumber());
   }
 
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload =
       depacketizer_->Parse(rtp_packet.PayloadBuffer());
 
-  if (parsed_payload == absl::nullopt) {
+  if (parsed_payload == std::nullopt) {
     return {};
   }
 
diff --git a/api/video/rtp_video_frame_assembler_unittests.cc b/api/video/rtp_video_frame_assembler_unittests.cc
index 0becb9f..1143f46 100644
--- a/api/video/rtp_video_frame_assembler_unittests.cc
+++ b/api/video/rtp_video_frame_assembler_unittests.cc
@@ -11,9 +11,9 @@
 #include <cstdint>
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/transport/rtp/dependency_descriptor.h"
 #include "api/video/encoded_frame.h"
@@ -86,10 +86,10 @@
   }
 
  private:
-  absl::optional<VideoCodecType> GetVideoCodecType() {
+  std::optional<VideoCodecType> GetVideoCodecType() {
     switch (format_) {
       case PayloadFormat::kRaw: {
-        return absl::nullopt;
+        return std::nullopt;
       }
       case PayloadFormat::kH264: {
         return kVideoCodecH264;
@@ -111,7 +111,7 @@
       }
     }
     RTC_DCHECK_NOTREACHED();
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   const RtpVideoFrameAssembler::PayloadFormat format_;
diff --git a/api/video/test/BUILD.gn b/api/video/test/BUILD.gn
index 4450a0a..3fbd7d3 100644
--- a/api/video/test/BUILD.gn
+++ b/api/video/test/BUILD.gn
@@ -29,7 +29,6 @@
     "../..:scoped_refptr",
     "../../../test:frame_utils",
     "../../../test:test_support",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/api/video/test/mock_recordable_encoded_frame.h b/api/video/test/mock_recordable_encoded_frame.h
index 2178932..086b17b 100644
--- a/api/video/test/mock_recordable_encoded_frame.h
+++ b/api/video/test/mock_recordable_encoded_frame.h
@@ -21,7 +21,7 @@
               encoded_buffer,
               (),
               (const, override));
-  MOCK_METHOD(absl::optional<webrtc::ColorSpace>,
+  MOCK_METHOD(std::optional<webrtc::ColorSpace>,
               color_space,
               (),
               (const, override));
diff --git a/api/video/test/video_bitrate_allocation_unittest.cc b/api/video/test/video_bitrate_allocation_unittest.cc
index 8e66d4b..f84fa69 100644
--- a/api/video/test/video_bitrate_allocation_unittest.cc
+++ b/api/video/test/video_bitrate_allocation_unittest.cc
@@ -10,9 +10,9 @@
 
 #include "api/video/video_bitrate_allocation.h"
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "test/gtest.h"
 
 namespace webrtc {
@@ -31,7 +31,7 @@
   layer1_bitrate.SetBitrate(0, 0, 40000);
   layer1_bitrate.SetBitrate(0, 1, 80000);
 
-  std::vector<absl::optional<VideoBitrateAllocation>> layer_allocations =
+  std::vector<std::optional<VideoBitrateAllocation>> layer_allocations =
       bitrate.GetSimulcastAllocations();
 
   EXPECT_EQ(layer0_bitrate, layer_allocations[0]);
@@ -54,7 +54,7 @@
   layer2_bitrate.SetBitrate(0, 0, 40000);
   layer2_bitrate.SetBitrate(0, 1, 80000);
 
-  std::vector<absl::optional<VideoBitrateAllocation>> layer_allocations =
+  std::vector<std::optional<VideoBitrateAllocation>> layer_allocations =
       bitrate.GetSimulcastAllocations();
 
   EXPECT_EQ(layer0_bitrate, layer_allocations[0]);
diff --git a/api/video/video_bitrate_allocation.cc b/api/video/video_bitrate_allocation.cc
index af5ce82..889dbd0 100644
--- a/api/video/video_bitrate_allocation.cc
+++ b/api/video/video_bitrate_allocation.cc
@@ -12,10 +12,10 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/video/video_codec_constants.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_conversions.h"
@@ -32,7 +32,7 @@
   RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
   RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
   int64_t new_bitrate_sum_bps = sum_;
-  absl::optional<uint32_t>& layer_bitrate =
+  std::optional<uint32_t>& layer_bitrate =
       bitrates_[spatial_index][temporal_index];
   if (layer_bitrate) {
     RTC_DCHECK_LE(*layer_bitrate, sum_);
@@ -112,11 +112,11 @@
   return temporal_rates;
 }
 
-std::vector<absl::optional<VideoBitrateAllocation>>
+std::vector<std::optional<VideoBitrateAllocation>>
 VideoBitrateAllocation::GetSimulcastAllocations() const {
-  std::vector<absl::optional<VideoBitrateAllocation>> bitrates;
+  std::vector<std::optional<VideoBitrateAllocation>> bitrates;
   for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
-    absl::optional<VideoBitrateAllocation> layer_bitrate;
+    std::optional<VideoBitrateAllocation> layer_bitrate;
     if (IsSpatialLayerUsed(si)) {
       layer_bitrate = VideoBitrateAllocation();
       for (int tl = 0; tl < kMaxTemporalStreams; ++tl) {
diff --git a/api/video/video_bitrate_allocation.h b/api/video/video_bitrate_allocation.h
index 4feffa2..63ac26a 100644
--- a/api/video/video_bitrate_allocation.h
+++ b/api/video/video_bitrate_allocation.h
@@ -15,10 +15,10 @@
 #include <stdint.h>
 
 #include <limits>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/video/video_codec_constants.h"
 #include "rtc_base/system/rtc_export.h"
 
@@ -64,7 +64,7 @@
   // Returns one VideoBitrateAllocation for each spatial layer. This is used to
   // configure simulcast streams. Note that the length of the returned vector is
   // always kMaxSpatialLayers, the optional is unset for unused layers.
-  std::vector<absl::optional<VideoBitrateAllocation>> GetSimulcastAllocations()
+  std::vector<std::optional<VideoBitrateAllocation>> GetSimulcastAllocations()
       const;
 
   uint32_t get_sum_bps() const { return sum_; }  // Sum of all bitrates.
@@ -87,7 +87,7 @@
 
  private:
   uint32_t sum_;
-  absl::optional<uint32_t> bitrates_[kMaxSpatialLayers][kMaxTemporalStreams];
+  std::optional<uint32_t> bitrates_[kMaxSpatialLayers][kMaxTemporalStreams];
   bool is_bw_limited_;
 };
 
diff --git a/api/video/video_frame.cc b/api/video/video_frame.cc
index cb40c89b..9e226f8 100644
--- a/api/video/video_frame.cc
+++ b/api/video/video_frame.cc
@@ -12,9 +12,9 @@
 
 #include <algorithm>
 #include <cstdint>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/rtp_packet_infos.h"
 #include "api/scoped_refptr.h"
 #include "api/units/timestamp.h"
@@ -196,13 +196,13 @@
 }
 
 VideoFrame::Builder& VideoFrame::Builder::set_capture_time_identifier(
-    const absl::optional<Timestamp>& capture_time_identifier) {
+    const std::optional<Timestamp>& capture_time_identifier) {
   capture_time_identifier_ = capture_time_identifier;
   return *this;
 }
 
 VideoFrame::Builder& VideoFrame::Builder::set_reference_time(
-    const absl::optional<Timestamp>& reference_time) {
+    const std::optional<Timestamp>& reference_time) {
   reference_time_ = reference_time;
   return *this;
 }
@@ -230,15 +230,14 @@
 }
 
 VideoFrame::Builder& VideoFrame::Builder::set_color_space(
-    const absl::optional<ColorSpace>& color_space) {
+    const std::optional<ColorSpace>& color_space) {
   color_space_ = color_space;
   return *this;
 }
 
 VideoFrame::Builder& VideoFrame::Builder::set_color_space(
     const ColorSpace* color_space) {
-  color_space_ =
-      color_space ? absl::make_optional(*color_space) : absl::nullopt;
+  color_space_ = color_space ? std::make_optional(*color_space) : std::nullopt;
   return *this;
 }
 
@@ -248,7 +247,7 @@
 }
 
 VideoFrame::Builder& VideoFrame::Builder::set_update_rect(
-    const absl::optional<VideoFrame::UpdateRect>& update_rect) {
+    const std::optional<VideoFrame::UpdateRect>& update_rect) {
   update_rect_ = update_rect;
   return *this;
 }
@@ -283,14 +282,14 @@
 VideoFrame::VideoFrame(uint16_t id,
                        const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
                        int64_t timestamp_us,
-                       const absl::optional<Timestamp>& capture_time_identifier,
-                       const absl::optional<Timestamp>& reference_time,
+                       const std::optional<Timestamp>& capture_time_identifier,
+                       const std::optional<Timestamp>& reference_time,
                        uint32_t timestamp_rtp,
                        int64_t ntp_time_ms,
                        VideoRotation rotation,
-                       const absl::optional<ColorSpace>& color_space,
+                       const std::optional<ColorSpace>& color_space,
                        const RenderParameters& render_parameters,
-                       const absl::optional<UpdateRect>& update_rect,
+                       const std::optional<UpdateRect>& update_rect,
                        RtpPacketInfos packet_infos)
     : id_(id),
       video_frame_buffer_(buffer),
diff --git a/api/video/video_frame.h b/api/video/video_frame.h
index ef01e5f..b1aa751 100644
--- a/api/video/video_frame.h
+++ b/api/video/video_frame.h
@@ -13,9 +13,9 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/rtp_packet_infos.h"
 #include "api/scoped_refptr.h"
 #include "api/units/time_delta.h"
@@ -84,7 +84,7 @@
 
   struct RTC_EXPORT RenderParameters {
     bool use_low_latency_rendering = false;
-    absl::optional<int32_t> max_composition_delay_in_frames;
+    std::optional<int32_t> max_composition_delay_in_frames;
 
     bool operator==(const RenderParameters& other) const {
       return other.use_low_latency_rendering == use_low_latency_rendering &&
@@ -109,32 +109,31 @@
     Builder& set_timestamp_ms(int64_t timestamp_ms);
     Builder& set_timestamp_us(int64_t timestamp_us);
     Builder& set_capture_time_identifier(
-        const absl::optional<Timestamp>& capture_time_identifier);
-    Builder& set_reference_time(
-        const absl::optional<Timestamp>& reference_time);
+        const std::optional<Timestamp>& capture_time_identifier);
+    Builder& set_reference_time(const std::optional<Timestamp>& reference_time);
     Builder& set_rtp_timestamp(uint32_t rtp_timestamp);
     // TODO(https://bugs.webrtc.org/13756): Deprecate and use set_rtp_timestamp.
     Builder& set_timestamp_rtp(uint32_t timestamp_rtp);
     Builder& set_ntp_time_ms(int64_t ntp_time_ms);
     Builder& set_rotation(VideoRotation rotation);
-    Builder& set_color_space(const absl::optional<ColorSpace>& color_space);
+    Builder& set_color_space(const std::optional<ColorSpace>& color_space);
     Builder& set_color_space(const ColorSpace* color_space);
     Builder& set_id(uint16_t id);
-    Builder& set_update_rect(const absl::optional<UpdateRect>& update_rect);
+    Builder& set_update_rect(const std::optional<UpdateRect>& update_rect);
     Builder& set_packet_infos(RtpPacketInfos packet_infos);
 
    private:
     uint16_t id_ = kNotSetId;
     rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer_;
     int64_t timestamp_us_ = 0;
-    absl::optional<Timestamp> capture_time_identifier_;
-    absl::optional<Timestamp> reference_time_;
+    std::optional<Timestamp> capture_time_identifier_;
+    std::optional<Timestamp> reference_time_;
     uint32_t timestamp_rtp_ = 0;
     int64_t ntp_time_ms_ = 0;
     VideoRotation rotation_ = kVideoRotation_0;
-    absl::optional<ColorSpace> color_space_;
+    std::optional<ColorSpace> color_space_;
     RenderParameters render_parameters_;
-    absl::optional<UpdateRect> update_rect_;
+    std::optional<UpdateRect> update_rect_;
     RtpPacketInfos packet_infos_;
   };
 
@@ -175,18 +174,18 @@
   int64_t timestamp_us() const { return timestamp_us_; }
   void set_timestamp_us(int64_t timestamp_us) { timestamp_us_ = timestamp_us; }
 
-  const absl::optional<Timestamp>& capture_time_identifier() const {
+  const std::optional<Timestamp>& capture_time_identifier() const {
     return capture_time_identifier_;
   }
   void set_capture_time_identifier(
-      const absl::optional<Timestamp>& capture_time_identifier) {
+      const std::optional<Timestamp>& capture_time_identifier) {
     capture_time_identifier_ = capture_time_identifier;
   }
 
-  const absl::optional<Timestamp>& reference_time() const {
+  const std::optional<Timestamp>& reference_time() const {
     return reference_time_;
   }
-  void set_reference_time(const absl::optional<Timestamp>& reference_time) {
+  void set_reference_time(const std::optional<Timestamp>& reference_time) {
     reference_time_ = reference_time;
   }
 
@@ -218,8 +217,8 @@
   void set_rotation(VideoRotation rotation) { rotation_ = rotation; }
 
   // Get color space when available.
-  const absl::optional<ColorSpace>& color_space() const { return color_space_; }
-  void set_color_space(const absl::optional<ColorSpace>& color_space) {
+  const std::optional<ColorSpace>& color_space() const { return color_space_; }
+  void set_color_space(const std::optional<ColorSpace>& color_space) {
     color_space_ = color_space;
   }
 
@@ -260,7 +259,7 @@
     update_rect_ = update_rect;
   }
 
-  void clear_update_rect() { update_rect_ = absl::nullopt; }
+  void clear_update_rect() { update_rect_ = std::nullopt; }
 
   // Get information about packets used to assemble this video frame. Might be
   // empty if the information isn't available.
@@ -269,7 +268,7 @@
     packet_infos_ = std::move(value);
   }
 
-  const absl::optional<ProcessingTime> processing_time() const {
+  const std::optional<ProcessingTime> processing_time() const {
     return processing_time_;
   }
   void set_processing_time(const ProcessingTime& processing_time) {
@@ -280,14 +279,14 @@
   VideoFrame(uint16_t id,
              const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
              int64_t timestamp_us,
-             const absl::optional<Timestamp>& capture_time_identifier,
-             const absl::optional<Timestamp>& reference_time,
+             const std::optional<Timestamp>& capture_time_identifier,
+             const std::optional<Timestamp>& reference_time,
              uint32_t timestamp_rtp,
              int64_t ntp_time_ms,
              VideoRotation rotation,
-             const absl::optional<ColorSpace>& color_space,
+             const std::optional<ColorSpace>& color_space,
              const RenderParameters& render_parameters,
-             const absl::optional<UpdateRect>& update_rect,
+             const std::optional<UpdateRect>& update_rect,
              RtpPacketInfos packet_infos);
 
   uint16_t id_;
@@ -296,21 +295,21 @@
   uint32_t timestamp_rtp_;
   int64_t ntp_time_ms_;
   int64_t timestamp_us_;
-  absl::optional<Timestamp> capture_time_identifier_;
+  std::optional<Timestamp> capture_time_identifier_;
   // Contains a monotonically increasing clock time and represents the time
   // when the frame was captured. Not all platforms provide the "true" sample
   // capture time in |reference_time| but might instead use a somewhat delayed
   // (by the time it took to capture the frame) version of it.
-  absl::optional<Timestamp> reference_time_;
+  std::optional<Timestamp> reference_time_;
   VideoRotation rotation_;
-  absl::optional<ColorSpace> color_space_;
+  std::optional<ColorSpace> color_space_;
   // Contains parameters that affect have the frame should be rendered.
   RenderParameters render_parameters_;
   // Updated since the last frame area. If present it means that the bounding
   // box of all the changes is within the rectangular area and is close to it.
   // If absent, it means that there's no information about the change at all and
   // update_rect() will return a rectangle corresponding to the entire frame.
-  absl::optional<UpdateRect> update_rect_;
+  std::optional<UpdateRect> update_rect_;
   // Information about packets used to assemble this video frame. This is needed
   // by `SourceTracker` when the frame is delivered to the RTCRtpReceiver's
   // MediaStreamTrack, in order to implement getContributingSources(). See:
@@ -320,7 +319,7 @@
   // timestamps when the frame is sent to the decoder and the decoded image
   // returned from the decoder.
   // Currently, not set for locally captured video frames.
-  absl::optional<ProcessingTime> processing_time_;
+  std::optional<ProcessingTime> processing_time_;
 };
 
 }  // namespace webrtc
diff --git a/api/video/video_frame_metadata.cc b/api/video/video_frame_metadata.cc
index ca14fae..dc92cdb 100644
--- a/api/video/video_frame_metadata.cc
+++ b/api/video/video_frame_metadata.cc
@@ -11,10 +11,10 @@
 #include "api/video/video_frame_metadata.h"
 
 #include <cstdint>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/transport/rtp/dependency_descriptor.h"
 #include "api/video/video_codec_type.h"
@@ -66,11 +66,11 @@
   content_type_ = content_type;
 }
 
-absl::optional<int64_t> VideoFrameMetadata::GetFrameId() const {
+std::optional<int64_t> VideoFrameMetadata::GetFrameId() const {
   return frame_id_;
 }
 
-void VideoFrameMetadata::SetFrameId(absl::optional<int64_t> frame_id) {
+void VideoFrameMetadata::SetFrameId(std::optional<int64_t> frame_id) {
   frame_id_ = frame_id;
 }
 
diff --git a/api/video/video_frame_metadata.h b/api/video/video_frame_metadata.h
index bf46387..4ec0e98 100644
--- a/api/video/video_frame_metadata.h
+++ b/api/video/video_frame_metadata.h
@@ -12,10 +12,10 @@
 #define API_VIDEO_VIDEO_FRAME_METADATA_H_
 
 #include <cstdint>
+#include <optional>
 #include <vector>
 
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/array_view.h"
 #include "api/transport/rtp/dependency_descriptor.h"
@@ -58,8 +58,8 @@
   VideoContentType GetContentType() const;
   void SetContentType(VideoContentType content_type);
 
-  absl::optional<int64_t> GetFrameId() const;
-  void SetFrameId(absl::optional<int64_t> frame_id);
+  std::optional<int64_t> GetFrameId() const;
+  void SetFrameId(std::optional<int64_t> frame_id);
 
   int GetSpatialIndex() const;
   void SetSpatialIndex(int spatial_index);
@@ -107,7 +107,7 @@
   VideoContentType content_type_ = VideoContentType::UNSPECIFIED;
 
   // Corresponding to GenericDescriptorInfo.
-  absl::optional<int64_t> frame_id_;
+  std::optional<int64_t> frame_id_;
   int spatial_index_ = 0;
   int temporal_index_ = 0;
   absl::InlinedVector<int64_t, 5> frame_dependencies_;
diff --git a/api/video/video_source_interface.h b/api/video/video_source_interface.h
index c636c2f..d85e56b 100644
--- a/api/video/video_source_interface.h
+++ b/api/video/video_source_interface.h
@@ -12,9 +12,9 @@
 #define API_VIDEO_VIDEO_SOURCE_INTERFACE_H_
 
 #include <limits>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/video/video_sink_interface.h"
 #include "rtc_base/system/rtc_export.h"
 
@@ -50,7 +50,7 @@
   // have improved after an earlier downgrade. The source should select the
   // closest resolution to this pixel count, but if max_pixel_count is set, it
   // still sets the absolute upper bound.
-  absl::optional<int> target_pixel_count;
+  std::optional<int> target_pixel_count;
   // Tells the source the maximum framerate the sink wants.
   int max_framerate_fps = std::numeric_limits<int>::max();
 
@@ -83,7 +83,7 @@
   std::vector<FrameSize> resolutions;
 
   // This is the resolution requested by the user using RtpEncodingParameters.
-  absl::optional<FrameSize> requested_resolution;
+  std::optional<FrameSize> requested_resolution;
 
   // `is_active` : Is this VideoSinkWants from an encoder that is encoding any
   // layer. IF YES, it will affect how the VideoAdapter will choose to
@@ -102,7 +102,7 @@
     // OnOutputFormatRequest to handle encode resolution.
     bool any_active_without_requested_resolution = false;
   };
-  absl::optional<Aggregates> aggregates;
+  std::optional<Aggregates> aggregates;
 };
 
 inline bool operator==(const VideoSinkWants::FrameSize& a,
diff --git a/api/video_codecs/BUILD.gn b/api/video_codecs/BUILD.gn
index 6990894..108e11c 100644
--- a/api/video_codecs/BUILD.gn
+++ b/api/video_codecs/BUILD.gn
@@ -35,7 +35,6 @@
     ":scalability_mode",
     "../../modules/video_coding/svc:scalability_mode_util",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -104,17 +103,13 @@
     "//third_party/abseil-cpp/absl/container:inlined_vector",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
 rtc_source_set("bitstream_parser_api") {
   visibility = [ "*" ]
   sources = [ "bitstream_parser.h" ]
-  deps = [
-    "..:array_view",
-    "//third_party/abseil-cpp/absl/types:optional",
-  ]
+  deps = [ "..:array_view" ]
 }
 
 rtc_library("builtin_video_decoder_factory") {
@@ -150,7 +145,6 @@
     "../../media:rtc_simulcast_encoder_adapter",
     "../../rtc_base/system:rtc_export",
     "../environment",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -166,7 +160,6 @@
     "../../modules/video_coding/svc:scalability_mode_util",
     "../environment",
     "//third_party/abseil-cpp/absl/algorithm:container",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -306,7 +299,6 @@
     "../../api/video_codecs:video_codecs_api",
     "../../rtc_base:rtc_numerics",
     "//third_party/abseil-cpp/absl/functional:any_invocable",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -321,7 +313,6 @@
     "../../api/video:resolution",
     "../../rtc_base:rtc_numerics",
     "../video:video_frame",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -354,7 +345,6 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/functional:any_invocable",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -374,7 +364,6 @@
     "../../test:fileutils",
     "../../test:test_support",
     "../../test:video_test_support",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -402,7 +391,6 @@
     "../video:video_frame",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/cleanup",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
     "//third_party/libaom",
   ]
@@ -435,7 +423,6 @@
     "../units:time_delta",
     "../units:timestamp",
     "../video:encoded_image",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -489,6 +476,5 @@
     "../video:video_frame_type",
     "../video:video_rtp_headers",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
diff --git a/api/video_codecs/av1_profile.cc b/api/video_codecs/av1_profile.cc
index 5181fe1..177ebf0 100644
--- a/api/video_codecs/av1_profile.cc
+++ b/api/video_codecs/av1_profile.cc
@@ -11,11 +11,11 @@
 #include "api/video_codecs/av1_profile.h"
 
 #include <map>
+#include <optional>
 #include <string>
 #include <utility>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/rtp_parameters.h"
 #include "media/base/media_constants.h"
 #include "rtc_base/string_to_number.h"
@@ -34,10 +34,10 @@
   return "0";
 }
 
-absl::optional<AV1Profile> StringToAV1Profile(absl::string_view str) {
-  const absl::optional<int> i = rtc::StringToNumber<int>(str);
+std::optional<AV1Profile> StringToAV1Profile(absl::string_view str) {
+  const std::optional<int> i = rtc::StringToNumber<int>(str);
   if (!i.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
   switch (i.value()) {
     case 0:
@@ -47,11 +47,11 @@
     case 2:
       return AV1Profile::kProfile2;
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
-absl::optional<AV1Profile> ParseSdpForAV1Profile(
+std::optional<AV1Profile> ParseSdpForAV1Profile(
     const CodecParameterMap& params) {
   const auto profile_it = params.find(cricket::kAv1FmtpProfile);
   if (profile_it == params.end())
@@ -62,8 +62,8 @@
 
 bool AV1IsSameProfile(const CodecParameterMap& params1,
                       const CodecParameterMap& params2) {
-  const absl::optional<AV1Profile> profile = ParseSdpForAV1Profile(params1);
-  const absl::optional<AV1Profile> other_profile =
+  const std::optional<AV1Profile> profile = ParseSdpForAV1Profile(params1);
+  const std::optional<AV1Profile> other_profile =
       ParseSdpForAV1Profile(params2);
   return profile && other_profile && profile == other_profile;
 }
diff --git a/api/video_codecs/av1_profile.h b/api/video_codecs/av1_profile.h
index fde4633..a96285d 100644
--- a/api/video_codecs/av1_profile.h
+++ b/api/video_codecs/av1_profile.h
@@ -11,9 +11,9 @@
 #ifndef API_VIDEO_CODECS_AV1_PROFILE_H_
 #define API_VIDEO_CODECS_AV1_PROFILE_H_
 
+#include <optional>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/rtp_parameters.h"
 #include "rtc_base/system/rtc_export.h"
 
@@ -34,13 +34,13 @@
 
 // Helper function which converts a std::string to AV1Profile. Returns null if
 // |profile| is not a valid profile string.
-absl::optional<AV1Profile> StringToAV1Profile(absl::string_view profile);
+std::optional<AV1Profile> StringToAV1Profile(absl::string_view profile);
 
 // Parses an SDP key-value map of format parameters to retrive an AV1 profile.
 // Returns an AV1Profile if one has been specified, `kProfile0` if no profile is
 // specified and an empty value if the profile key is present but contains an
 // invalid value.
-RTC_EXPORT absl::optional<AV1Profile> ParseSdpForAV1Profile(
+RTC_EXPORT std::optional<AV1Profile> ParseSdpForAV1Profile(
     const CodecParameterMap& params);
 
 // Returns true if the parameters have the same AV1 profile or neither contains
diff --git a/api/video_codecs/bitstream_parser.h b/api/video_codecs/bitstream_parser.h
index 86ce192..282b105 100644
--- a/api/video_codecs/bitstream_parser.h
+++ b/api/video_codecs/bitstream_parser.h
@@ -14,7 +14,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/array_view.h"
 
 namespace webrtc {
@@ -28,8 +29,8 @@
   virtual void ParseBitstream(rtc::ArrayView<const uint8_t> bitstream) = 0;
 
   // Get the last extracted QP value from the parsed bitstream. If no QP
-  // value could be parsed, returns absl::nullopt.
-  virtual absl::optional<int> GetLastSliceQp() const = 0;
+  // value could be parsed, returns std::nullopt.
+  virtual std::optional<int> GetLastSliceQp() const = 0;
 };
 
 }  // namespace webrtc
diff --git a/api/video_codecs/builtin_video_encoder_factory.cc b/api/video_codecs/builtin_video_encoder_factory.cc
index bbd5222..bd4bad6 100644
--- a/api/video_codecs/builtin_video_encoder_factory.cc
+++ b/api/video_codecs/builtin_video_encoder_factory.cc
@@ -11,10 +11,10 @@
 #include "api/video_codecs/builtin_video_encoder_factory.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/video_codecs/sdp_video_format.h"
 #include "api/video_codecs/video_encoder.h"
@@ -54,7 +54,7 @@
 
   CodecSupport QueryCodecSupport(
       const SdpVideoFormat& format,
-      absl::optional<std::string> scalability_mode) const override {
+      std::optional<std::string> scalability_mode) const override {
     return internal_encoder_factory_->QueryCodecSupport(format,
                                                         scalability_mode);
   }
diff --git a/api/video_codecs/h264_profile_level_id.cc b/api/video_codecs/h264_profile_level_id.cc
index 09f7fa5..9a2dca9 100644
--- a/api/video_codecs/h264_profile_level_id.cc
+++ b/api/video_codecs/h264_profile_level_id.cc
@@ -14,9 +14,9 @@
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/rtp_parameters.h"
 #include "rtc_base/arraysize.h"
 
@@ -103,13 +103,13 @@
 
 }  // anonymous namespace
 
-absl::optional<H264ProfileLevelId> ParseH264ProfileLevelId(const char* str) {
+std::optional<H264ProfileLevelId> ParseH264ProfileLevelId(const char* str) {
   // The string should consist of 3 bytes in hexadecimal format.
   if (strlen(str) != 6u)
-    return absl::nullopt;
+    return std::nullopt;
   const uint32_t profile_level_id_numeric = strtol(str, nullptr, 16);
   if (profile_level_id_numeric == 0)
-    return absl::nullopt;
+    return std::nullopt;
 
   // Separate into three bytes.
   const uint8_t level_idc =
@@ -147,7 +147,7 @@
       break;
     default:
       // Unrecognized level_idc.
-      return absl::nullopt;
+      return std::nullopt;
   }
 
   // Parse profile_idc/profile_iop into a Profile enum.
@@ -159,11 +159,11 @@
   }
 
   // Unrecognized profile_idc/profile_iop combination.
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<H264Level> H264SupportedLevel(int max_frame_pixel_count,
-                                             float max_fps) {
+std::optional<H264Level> H264SupportedLevel(int max_frame_pixel_count,
+                                            float max_fps) {
   static const int kPixelsPerMacroblock = 16 * 16;
 
   for (int i = arraysize(kLevelConstraints) - 1; i >= 0; --i) {
@@ -177,10 +177,10 @@
   }
 
   // No level supported.
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<H264ProfileLevelId> ParseSdpForH264ProfileLevelId(
+std::optional<H264ProfileLevelId> ParseSdpForH264ProfileLevelId(
     const CodecParameterMap& params) {
   // TODO(magjed): The default should really be kProfileBaseline and kLevel1
   // according to the spec: https://tools.ietf.org/html/rfc6184#section-8.1. In
@@ -198,7 +198,7 @@
              : ParseH264ProfileLevelId(profile_level_id_it->second.c_str());
 }
 
-absl::optional<std::string> H264ProfileLevelIdToString(
+std::optional<std::string> H264ProfileLevelIdToString(
     const H264ProfileLevelId& profile_level_id) {
   // Handle special case level == 1b.
   if (profile_level_id.level == H264Level::kLevel1_b) {
@@ -211,7 +211,7 @@
         return {"4d100b"};
       // Level 1b is not allowed for other profiles.
       default:
-        return absl::nullopt;
+        return std::nullopt;
     }
   }
 
@@ -237,7 +237,7 @@
       break;
     // Unrecognized profile.
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 
   char str[7];
@@ -248,9 +248,9 @@
 
 bool H264IsSameProfile(const CodecParameterMap& params1,
                        const CodecParameterMap& params2) {
-  const absl::optional<H264ProfileLevelId> profile_level_id =
+  const std::optional<H264ProfileLevelId> profile_level_id =
       ParseSdpForH264ProfileLevelId(params1);
-  const absl::optional<H264ProfileLevelId> other_profile_level_id =
+  const std::optional<H264ProfileLevelId> other_profile_level_id =
       ParseSdpForH264ProfileLevelId(params2);
   // Compare H264 profiles, but not levels.
   return profile_level_id && other_profile_level_id &&
diff --git a/api/video_codecs/h264_profile_level_id.h b/api/video_codecs/h264_profile_level_id.h
index ca8c1d5..593b8e9 100644
--- a/api/video_codecs/h264_profile_level_id.h
+++ b/api/video_codecs/h264_profile_level_id.h
@@ -11,9 +11,9 @@
 #ifndef API_VIDEO_CODECS_H264_PROFILE_LEVEL_ID_H_
 #define API_VIDEO_CODECS_H264_PROFILE_LEVEL_ID_H_
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/rtp_parameters.h"
 #include "rtc_base/system/rtc_export.h"
 
@@ -60,26 +60,26 @@
 // Parse profile level id that is represented as a string of 3 hex bytes.
 // Nothing will be returned if the string is not a recognized H264
 // profile level id.
-absl::optional<H264ProfileLevelId> ParseH264ProfileLevelId(const char* str);
+std::optional<H264ProfileLevelId> ParseH264ProfileLevelId(const char* str);
 
 // Parse profile level id that is represented as a string of 3 hex bytes
 // contained in an SDP key-value map. A default profile level id will be
 // returned if the profile-level-id key is missing. Nothing will be returned if
 // the key is present but the string is invalid.
-RTC_EXPORT absl::optional<H264ProfileLevelId> ParseSdpForH264ProfileLevelId(
+RTC_EXPORT std::optional<H264ProfileLevelId> ParseSdpForH264ProfileLevelId(
     const CodecParameterMap& params);
 
 // Given that a decoder supports up to a given frame size (in pixels) at up to a
 // given number of frames per second, return the highest H.264 level where it
 // can guarantee that it will be able to support all valid encoded streams that
 // are within that level.
-RTC_EXPORT absl::optional<H264Level> H264SupportedLevel(
+RTC_EXPORT std::optional<H264Level> H264SupportedLevel(
     int max_frame_pixel_count,
     float max_fps);
 
 // Returns canonical string representation as three hex bytes of the profile
 // level id, or returns nothing for invalid profile level ids.
-RTC_EXPORT absl::optional<std::string> H264ProfileLevelIdToString(
+RTC_EXPORT std::optional<std::string> H264ProfileLevelIdToString(
     const H264ProfileLevelId& profile_level_id);
 
 // Returns true if the parameters have the same H264 profile (Baseline, High,
diff --git a/api/video_codecs/h265_profile_tier_level.cc b/api/video_codecs/h265_profile_tier_level.cc
index 3a25843..89eb553 100644
--- a/api/video_codecs/h265_profile_tier_level.cc
+++ b/api/video_codecs/h265_profile_tier_level.cc
@@ -10,9 +10,9 @@
 
 #include "api/video_codecs/h265_profile_tier_level.h"
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/rtp_parameters.h"
 #include "api/video/resolution.h"
 #include "rtc_base/arraysize.h"
@@ -65,10 +65,10 @@
 }  // anonymous namespace
 
 // Annex A of https://www.itu.int/rec/T-REC-H.265 (08/21), section A.3.
-absl::optional<H265Profile> StringToH265Profile(const std::string& profile) {
-  absl::optional<int> i = rtc::StringToNumber<int>(profile);
+std::optional<H265Profile> StringToH265Profile(const std::string& profile) {
+  std::optional<int> i = rtc::StringToNumber<int>(profile);
   if (!i.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   switch (i.value()) {
@@ -95,16 +95,16 @@
     case 11:
       return H265Profile::kProfileHighThroughputScreenContentCoding;
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
 // Annex A of https://www.itu.int/rec/T-REC-H.265 (08/21), section A.4,
 // tiers and levels.
-absl::optional<H265Tier> StringToH265Tier(const std::string& tier) {
-  absl::optional<int> i = rtc::StringToNumber<int>(tier);
+std::optional<H265Tier> StringToH265Tier(const std::string& tier) {
+  std::optional<int> i = rtc::StringToNumber<int>(tier);
   if (!i.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   switch (i.value()) {
@@ -113,14 +113,14 @@
     case 1:
       return H265Tier::kTier1;
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
-absl::optional<H265Level> StringToH265Level(const std::string& level) {
-  const absl::optional<int> i = rtc::StringToNumber<int>(level);
+std::optional<H265Level> StringToH265Level(const std::string& level) {
+  const std::optional<int> i = rtc::StringToNumber<int>(level);
   if (!i.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
   switch (i.value()) {
     case 30:
@@ -150,7 +150,7 @@
     case 186:
       return H265Level::kLevel6_2;
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
@@ -221,44 +221,44 @@
   }
 }
 
-absl::optional<H265ProfileTierLevel> ParseSdpForH265ProfileTierLevel(
+std::optional<H265ProfileTierLevel> ParseSdpForH265ProfileTierLevel(
     const CodecParameterMap& params) {
   static const H265ProfileTierLevel kDefaultProfileTierLevel(
       H265Profile::kProfileMain, H265Tier::kTier0, H265Level::kLevel3_1);
   bool profile_tier_level_specified = false;
 
-  absl::optional<H265Profile> profile;
+  std::optional<H265Profile> profile;
   const auto profile_it = params.find(kH265FmtpProfile);
   if (profile_it != params.end()) {
     profile_tier_level_specified = true;
     const std::string& profile_str = profile_it->second;
     profile = StringToH265Profile(profile_str);
     if (!profile) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   } else {
     profile = H265Profile::kProfileMain;
   }
-  absl::optional<H265Tier> tier;
+  std::optional<H265Tier> tier;
   const auto tier_it = params.find(kH265FmtpTier);
   if (tier_it != params.end()) {
     profile_tier_level_specified = true;
     const std::string& tier_str = tier_it->second;
     tier = StringToH265Tier(tier_str);
     if (!tier) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   } else {
     tier = H265Tier::kTier0;
   }
-  absl::optional<H265Level> level;
+  std::optional<H265Level> level;
   const auto level_it = params.find(kH265FmtpLevel);
   if (level_it != params.end()) {
     profile_tier_level_specified = true;
     const std::string& level_str = level_it->second;
     level = StringToH265Level(level_str);
     if (!level) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   } else {
     level = H265Level::kLevel3_1;
@@ -266,7 +266,7 @@
 
   // Spec Table A.9, level 1 to level 3.1 does not allow high tiers.
   if (level <= H265Level::kLevel3_1 && tier == H265Tier::kTier1) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return !profile_tier_level_specified
@@ -277,16 +277,16 @@
 
 bool H265IsSameProfileTierLevel(const CodecParameterMap& params1,
                                 const CodecParameterMap& params2) {
-  const absl::optional<H265ProfileTierLevel> ptl1 =
+  const std::optional<H265ProfileTierLevel> ptl1 =
       ParseSdpForH265ProfileTierLevel(params1);
-  const absl::optional<H265ProfileTierLevel> ptl2 =
+  const std::optional<H265ProfileTierLevel> ptl2 =
       ParseSdpForH265ProfileTierLevel(params2);
   return ptl1 && ptl2 && ptl1->profile == ptl2->profile &&
          ptl1->tier == ptl2->tier && ptl1->level == ptl2->level;
 }
 
-absl::optional<H265Level> GetSupportedH265Level(const Resolution& resolution,
-                                                float max_fps) {
+std::optional<H265Level> GetSupportedH265Level(const Resolution& resolution,
+                                               float max_fps) {
   int aligned_width =
       (resolution.width + kMinCbSizeYMax - 1) & ~(kMinCbSizeYMax - 1);
   int aligned_height =
@@ -303,7 +303,7 @@
       return level_constraint.level;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace webrtc
diff --git a/api/video_codecs/h265_profile_tier_level.h b/api/video_codecs/h265_profile_tier_level.h
index 91e64b7..d954055 100644
--- a/api/video_codecs/h265_profile_tier_level.h
+++ b/api/video_codecs/h265_profile_tier_level.h
@@ -11,9 +11,9 @@
 #ifndef API_VIDEO_CODECS_H265_PROFILE_TIER_LEVEL_H_
 #define API_VIDEO_CODECS_H265_PROFILE_TIER_LEVEL_H_
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/rtp_parameters.h"
 #include "api/video/resolution.h"
 #include "rtc_base/system/rtc_export.h"
@@ -80,21 +80,20 @@
 RTC_EXPORT std::string H265LevelToString(H265Level level);
 
 // Helper function to get H265Profile from profile string.
-RTC_EXPORT absl::optional<H265Profile> StringToH265Profile(
+RTC_EXPORT std::optional<H265Profile> StringToH265Profile(
     const std::string& profile);
 
 // Helper function to get H265Tier from tier string.
-RTC_EXPORT absl::optional<H265Tier> StringToH265Tier(const std::string& tier);
+RTC_EXPORT std::optional<H265Tier> StringToH265Tier(const std::string& tier);
 
 // Helper function to get H265Level from level string.
-RTC_EXPORT absl::optional<H265Level> StringToH265Level(
-    const std::string& level);
+RTC_EXPORT std::optional<H265Level> StringToH265Level(const std::string& level);
 
 // Given that a decoder supports up to a give frame size(in pixels) at up to a
 // given number of frames per second, return the highest H.265 level where it
 // can guranatee that it will be able to support all valid encoded streams that
 // are within that level.
-RTC_EXPORT absl::optional<H265Level> GetSupportedH265Level(
+RTC_EXPORT std::optional<H265Level> GetSupportedH265Level(
     const Resolution& resolution,
     float max_fps);
 
@@ -105,7 +104,7 @@
 // level defaults to "kLevel3_1" if no level-id is specified.
 // Returns empty value if any of the profile/tier/level key is present but
 // contains an invalid value.
-RTC_EXPORT absl::optional<H265ProfileTierLevel> ParseSdpForH265ProfileTierLevel(
+RTC_EXPORT std::optional<H265ProfileTierLevel> ParseSdpForH265ProfileTierLevel(
     const CodecParameterMap& params);
 
 // Returns true if the parameters have the same H265 profile or neither contains
diff --git a/api/video_codecs/libaom_av1_encoder_factory.cc b/api/video_codecs/libaom_av1_encoder_factory.cc
index 16555c5..968120e 100644
--- a/api/video_codecs/libaom_av1_encoder_factory.cc
+++ b/api/video_codecs/libaom_av1_encoder_factory.cc
@@ -16,13 +16,13 @@
 #include <cstring>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "absl/cleanup/cleanup.h"
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/array_view.h"
 #include "api/scoped_refptr.h"
@@ -82,8 +82,8 @@
 constexpr std::array<Rational, 7> kSupportedScalingFactors = {
     {{8, 1}, {4, 1}, {2, 1}, {1, 1}, {1, 2}, {1, 4}, {1, 8}}};
 
-absl::optional<Rational> GetScalingFactor(const Resolution& from,
-                                          const Resolution& to) {
+std::optional<Rational> GetScalingFactor(const Resolution& from,
+                                         const Resolution& to) {
   auto it = absl::c_find_if(kSupportedScalingFactors, [&](const Rational& r) {
     return (from.width * r.numerator / r.denominator) == to.width &&
            (from.height * r.numerator / r.denominator) == to.height;
@@ -114,10 +114,10 @@
   aom_codec_ctx_t ctx_;
   aom_codec_enc_cfg_t cfg_;
 
-  absl::optional<VideoCodecMode> current_content_type_;
-  std::array<absl::optional<int>, kMaxSpatialLayersWtf> current_effort_level_;
+  std::optional<VideoCodecMode> current_content_type_;
+  std::array<std::optional<int>, kMaxSpatialLayersWtf> current_effort_level_;
   int max_number_of_threads_;
-  std::array<absl::optional<Resolution>, 8> last_resolution_in_buffer_;
+  std::array<std::optional<Resolution>, 8> last_resolution_in_buffer_;
 };
 
 template <typename T>
@@ -273,7 +273,7 @@
     const VideoEncoderInterface::TemporalUnitSettings& tu_settings,
     const std::vector<VideoEncoderInterface::FrameEncodeSettings>&
         frame_settings,
-    const std::array<absl::optional<Resolution>, 8>& last_resolution_in_buffer,
+    const std::array<std::optional<Resolution>, 8>& last_resolution_in_buffer,
     aom_rc_mode rc_mode) {
   if (frame_settings.empty()) {
     RTC_LOG(LS_ERROR) << "No frame settings provided.";
@@ -343,7 +343,7 @@
 
       // Figure out which frame resolution a certain buffer will hold when the
       // frame described by `settings` is encoded.
-      absl::optional<Resolution> referenced_resolution;
+      std::optional<Resolution> referenced_resolution;
       bool keyframe_on_previous_layer = false;
 
       // Will some other frame in this temporal unit update the buffer?
@@ -560,7 +560,7 @@
 
   for (const VideoEncoderInterface::FrameEncodeSettings& settings :
        frame_settings) {
-    absl::optional<Rational> scaling_factor = GetScalingFactor(
+    std::optional<Rational> scaling_factor = GetScalingFactor(
         {frame_buffer.width(), frame_buffer.height()}, settings.resolution);
     RTC_CHECK(scaling_factor);
     svc_params.scaling_factor_num[settings.spatial_id] =
diff --git a/api/video_codecs/libaom_av1_encoder_factory_test.cc b/api/video_codecs/libaom_av1_encoder_factory_test.cc
index ba4623c..0d87a8c 100644
--- a/api/video_codecs/libaom_av1_encoder_factory_test.cc
+++ b/api/video_codecs/libaom_av1_encoder_factory_test.cc
@@ -13,12 +13,12 @@
 #include <cstdint>
 #include <cstdio>
 #include <memory>
+#include <optional>
 #include <ostream>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/array_view.h"
 #include "api/scoped_refptr.h"
@@ -741,7 +741,7 @@
                                          .performance.min_max_effort_level;
   // Cbr rc{.duration = TimeDelta::Millis(100),
   //       .target_bitrate = DataRate::KilobitsPerSec(100)};
-  absl::optional<double> psnr_last;
+  std::optional<double> psnr_last;
   Av1Decoder dec;
 
   for (int i = effort_range.first; i <= effort_range.second; ++i) {
diff --git a/api/video_codecs/scalability_mode_helper.cc b/api/video_codecs/scalability_mode_helper.cc
index 238bc22..83b7bd4 100644
--- a/api/video_codecs/scalability_mode_helper.cc
+++ b/api/video_codecs/scalability_mode_helper.cc
@@ -10,34 +10,35 @@
 
 #include "api/video_codecs/scalability_mode_helper.h"
 
+#include <optional>
+
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/video_codecs/scalability_mode.h"
 #include "modules/video_coding/svc/scalability_mode_util.h"
 
 namespace webrtc {
 
-absl::optional<int> ScalabilityModeStringToNumSpatialLayers(
+std::optional<int> ScalabilityModeStringToNumSpatialLayers(
     absl::string_view scalability_mode_string) {
-  absl::optional<ScalabilityMode> scalability_mode =
+  std::optional<ScalabilityMode> scalability_mode =
       ScalabilityModeFromString(scalability_mode_string);
   if (!scalability_mode.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ScalabilityModeToNumSpatialLayers(*scalability_mode);
 }
 
-absl::optional<int> ScalabilityModeStringToNumTemporalLayers(
+std::optional<int> ScalabilityModeStringToNumTemporalLayers(
     absl::string_view scalability_mode_string) {
-  absl::optional<ScalabilityMode> scalability_mode =
+  std::optional<ScalabilityMode> scalability_mode =
       ScalabilityModeFromString(scalability_mode_string);
   if (!scalability_mode.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ScalabilityModeToNumTemporalLayers(*scalability_mode);
 }
 
-absl::optional<ScalabilityMode> ScalabilityModeStringToEnum(
+std::optional<ScalabilityMode> ScalabilityModeStringToEnum(
     absl::string_view scalability_mode_string) {
   return ScalabilityModeFromString(scalability_mode_string);
 }
diff --git a/api/video_codecs/scalability_mode_helper.h b/api/video_codecs/scalability_mode_helper.h
index 21dcfc2..d48d45b 100644
--- a/api/video_codecs/scalability_mode_helper.h
+++ b/api/video_codecs/scalability_mode_helper.h
@@ -11,25 +11,26 @@
 #ifndef API_VIDEO_CODECS_SCALABILITY_MODE_HELPER_H_
 #define API_VIDEO_CODECS_SCALABILITY_MODE_HELPER_H_
 
+#include <optional>
+
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/video_codecs/scalability_mode.h"
 
 namespace webrtc {
 
 // Returns the number of spatial layers from the `scalability_mode_string`
 // or nullopt if the given mode is unknown.
-absl::optional<int> ScalabilityModeStringToNumSpatialLayers(
+std::optional<int> ScalabilityModeStringToNumSpatialLayers(
     absl::string_view scalability_mode_string);
 
 // Returns the number of temporal layers from the `scalability_mode_string`
 // or nullopt if the given mode is unknown.
-absl::optional<int> ScalabilityModeStringToNumTemporalLayers(
+std::optional<int> ScalabilityModeStringToNumTemporalLayers(
     absl::string_view scalability_mode_string);
 
 // Convert the `scalability_mode_string` to the scalability mode enum value
 // or nullopt if the given mode is unknown.
-absl::optional<ScalabilityMode> ScalabilityModeStringToEnum(
+std::optional<ScalabilityMode> ScalabilityModeStringToEnum(
     absl::string_view scalability_mode_string);
 
 }  // namespace webrtc
diff --git a/api/video_codecs/sdp_video_format.cc b/api/video_codecs/sdp_video_format.cc
index c0838bd..f287d63 100644
--- a/api/video_codecs/sdp_video_format.cc
+++ b/api/video_codecs/sdp_video_format.cc
@@ -10,11 +10,11 @@
 
 #include "api/video_codecs/sdp_video_format.h"
 
+#include <optional>
 #include <string>
 
 #include "absl/container/inlined_vector.h"
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/rtp_parameters.h"
 #include "api/video/video_codec_type.h"
@@ -259,10 +259,10 @@
                          {cricket::kAv1FmtpTier, "0"}});
 }
 
-absl::optional<SdpVideoFormat> FuzzyMatchSdpVideoFormat(
+std::optional<SdpVideoFormat> FuzzyMatchSdpVideoFormat(
     rtc::ArrayView<const SdpVideoFormat> supported_formats,
     const SdpVideoFormat& format) {
-  absl::optional<SdpVideoFormat> res;
+  std::optional<SdpVideoFormat> res;
   int best_parameter_match = 0;
   for (const auto& supported_format : supported_formats) {
     if (absl::EqualsIgnoreCase(supported_format.name, format.name)) {
diff --git a/api/video_codecs/sdp_video_format.h b/api/video_codecs/sdp_video_format.h
index e7da486..7c8de66 100644
--- a/api/video_codecs/sdp_video_format.h
+++ b/api/video_codecs/sdp_video_format.h
@@ -12,10 +12,10 @@
 #define API_VIDEO_CODECS_SDP_VIDEO_FORMAT_H_
 
 #include <map>
+#include <optional>
 #include <string>
 
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/rtp_parameters.h"
 #include "api/video_codecs/scalability_mode.h"
@@ -86,7 +86,7 @@
 // SdpVideoFormat, which makes instances that should compare equal to not match
 // anymore. Until we stop misusing SdpVideoFormats provide this convenience
 // function to perform fuzzy matching.
-absl::optional<SdpVideoFormat> FuzzyMatchSdpVideoFormat(
+std::optional<SdpVideoFormat> FuzzyMatchSdpVideoFormat(
     rtc::ArrayView<const SdpVideoFormat> supported_formats,
     const SdpVideoFormat& format);
 
diff --git a/api/video_codecs/simple_encoder_wrapper.cc b/api/video_codecs/simple_encoder_wrapper.cc
index 06ca5af..ae5282d 100644
--- a/api/video_codecs/simple_encoder_wrapper.cc
+++ b/api/video_codecs/simple_encoder_wrapper.cc
@@ -14,13 +14,13 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/array_view.h"
 #include "api/scoped_refptr.h"
@@ -121,7 +121,7 @@
     return nullptr;
   }
 
-  absl::optional<ScalabilityMode> sm =
+  std::optional<ScalabilityMode> sm =
       ScalabilityModeStringToEnum(scalability_mode);
   if (!sm) {
     return nullptr;
diff --git a/api/video_codecs/simple_encoder_wrapper.h b/api/video_codecs/simple_encoder_wrapper.h
index fd7ca7f..7baefb9 100644
--- a/api/video_codecs/simple_encoder_wrapper.h
+++ b/api/video_codecs/simple_encoder_wrapper.h
@@ -14,11 +14,11 @@
 #include <cstdint>
 #include <functional>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
 #include "api/transport/rtp/dependency_descriptor.h"
 #include "api/units/timestamp.h"
@@ -36,7 +36,7 @@
     std::vector<uint8_t> bitstream_data;
     FrameType frame_type;
     GenericFrameInfo generic_frame_info;
-    absl::optional<FrameDependencyStructure> dependency_structure;
+    std::optional<FrameDependencyStructure> dependency_structure;
   };
 
   using EncodeResultCallback = std::function<void(const EncodeResult& result)>;
diff --git a/api/video_codecs/simple_encoder_wrapper_unittests.cc b/api/video_codecs/simple_encoder_wrapper_unittests.cc
index 14a48f7..c5d9bae 100644
--- a/api/video_codecs/simple_encoder_wrapper_unittests.cc
+++ b/api/video_codecs/simple_encoder_wrapper_unittests.cc
@@ -9,9 +9,9 @@
  */
 
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/video/i420_buffer.h"  // IWYU pragma: keep
 #include "api/video_codecs/libaom_av1_encoder_factory.h"
 #include "api/video_codecs/simple_encoder_wrapper.h"
@@ -155,7 +155,7 @@
       [&](const SimpleEncoderWrapper::EncodeResult& result) {
         ++num_callbacks;
         ASSERT_THAT(result.oh_no, Eq(false));
-        EXPECT_THAT(result.dependency_structure, Ne(absl::nullopt));
+        EXPECT_THAT(result.dependency_structure, Ne(std::nullopt));
         EXPECT_THAT(result.bitstream_data, Not(IsEmpty()));
         EXPECT_THAT(result.frame_type, Eq(FrameType::kKeyframe));
         EXPECT_THAT(result.generic_frame_info.spatial_id, Eq(0));
@@ -167,7 +167,7 @@
       [&](const SimpleEncoderWrapper::EncodeResult& result) {
         ++num_callbacks;
         ASSERT_THAT(result.oh_no, Eq(false));
-        EXPECT_THAT(result.dependency_structure, Eq(absl::nullopt));
+        EXPECT_THAT(result.dependency_structure, Eq(std::nullopt));
         EXPECT_THAT(result.bitstream_data, Not(IsEmpty()));
         EXPECT_THAT(result.frame_type, Eq(FrameType::kDeltaFrame));
         EXPECT_THAT(result.generic_frame_info.spatial_id, Eq(0));
@@ -200,13 +200,13 @@
         ASSERT_THAT(result.oh_no, Eq(false));
         if (result.generic_frame_info.spatial_id == 0) {
           ++num_callbacks;
-          EXPECT_THAT(result.dependency_structure, Ne(absl::nullopt));
+          EXPECT_THAT(result.dependency_structure, Ne(std::nullopt));
           EXPECT_THAT(result.bitstream_data, Not(IsEmpty()));
           EXPECT_THAT(result.frame_type, Eq(FrameType::kKeyframe));
           EXPECT_THAT(result.generic_frame_info.temporal_id, Eq(0));
         } else if (result.generic_frame_info.spatial_id == 1) {
           ++num_callbacks;
-          EXPECT_THAT(result.dependency_structure, Eq(absl::nullopt));
+          EXPECT_THAT(result.dependency_structure, Eq(std::nullopt));
           EXPECT_THAT(result.bitstream_data, Not(IsEmpty()));
           EXPECT_THAT(result.frame_type, Eq(FrameType::kDeltaFrame));
           EXPECT_THAT(result.generic_frame_info.temporal_id, Eq(0));
@@ -219,13 +219,13 @@
         ASSERT_THAT(result.oh_no, Eq(false));
         if (result.generic_frame_info.spatial_id == 0) {
           ++num_callbacks;
-          EXPECT_THAT(result.dependency_structure, Eq(absl::nullopt));
+          EXPECT_THAT(result.dependency_structure, Eq(std::nullopt));
           EXPECT_THAT(result.bitstream_data, Not(IsEmpty()));
           EXPECT_THAT(result.frame_type, Eq(FrameType::kDeltaFrame));
           EXPECT_THAT(result.generic_frame_info.temporal_id, Eq(1));
         } else if (result.generic_frame_info.spatial_id == 1) {
           ++num_callbacks;
-          EXPECT_THAT(result.dependency_structure, Eq(absl::nullopt));
+          EXPECT_THAT(result.dependency_structure, Eq(std::nullopt));
           EXPECT_THAT(result.bitstream_data, Not(IsEmpty()));
           EXPECT_THAT(result.frame_type, Eq(FrameType::kDeltaFrame));
           EXPECT_THAT(result.generic_frame_info.temporal_id, Eq(1));
diff --git a/api/video_codecs/simulcast_stream.cc b/api/video_codecs/simulcast_stream.cc
index 9ecf746..cda5826 100644
--- a/api/video_codecs/simulcast_stream.cc
+++ b/api/video_codecs/simulcast_stream.cc
@@ -10,7 +10,8 @@
 
 #include "api/video_codecs/simulcast_stream.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/video_codecs/scalability_mode.h"
 #include "rtc_base/checks.h"
 
@@ -25,14 +26,14 @@
   numberOfTemporalLayers = n;
 }
 
-absl::optional<ScalabilityMode> SimulcastStream::GetScalabilityMode() const {
+std::optional<ScalabilityMode> SimulcastStream::GetScalabilityMode() const {
   static const ScalabilityMode scalability_modes[3] = {
       ScalabilityMode::kL1T1,
       ScalabilityMode::kL1T2,
       ScalabilityMode::kL1T3,
   };
   if (numberOfTemporalLayers < 1 || numberOfTemporalLayers > 3) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return scalability_modes[numberOfTemporalLayers - 1];
 }
diff --git a/api/video_codecs/simulcast_stream.h b/api/video_codecs/simulcast_stream.h
index 50ec21e..4dbee5b 100644
--- a/api/video_codecs/simulcast_stream.h
+++ b/api/video_codecs/simulcast_stream.h
@@ -11,7 +11,8 @@
 #ifndef API_VIDEO_CODECS_SIMULCAST_STREAM_H_
 #define API_VIDEO_CODECS_SIMULCAST_STREAM_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/video_codecs/scalability_mode.h"
 #include "rtc_base/system/rtc_export.h"
 
@@ -23,7 +24,7 @@
   // Temporary utility methods for transition from numberOfTemporalLayers
   // setting to ScalabilityMode.
   unsigned char GetNumberOfTemporalLayers() const;
-  absl::optional<ScalabilityMode> GetScalabilityMode() const;
+  std::optional<ScalabilityMode> GetScalabilityMode() const;
   void SetNumberOfTemporalLayers(unsigned char n);
 
   bool operator==(const SimulcastStream& other) const;
diff --git a/api/video_codecs/test/BUILD.gn b/api/video_codecs/test/BUILD.gn
index 95c0975..6b8fe75 100644
--- a/api/video_codecs/test/BUILD.gn
+++ b/api/video_codecs/test/BUILD.gn
@@ -55,7 +55,6 @@
       "../../video:video_frame_type",
       "../../video:video_rtp_headers",
       "//testing/gtest",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -76,7 +75,6 @@
       "../../environment",
       "../../environment:environment_factory",
       "//testing/gtest",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
diff --git a/api/video_codecs/test/h264_profile_level_id_unittest.cc b/api/video_codecs/test/h264_profile_level_id_unittest.cc
index 374c3d5..044765b 100644
--- a/api/video_codecs/test/h264_profile_level_id_unittest.cc
+++ b/api/video_codecs/test/h264_profile_level_id_unittest.cc
@@ -11,8 +11,8 @@
 #include "api/video_codecs/h264_profile_level_id.h"
 
 #include <map>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/rtp_parameters.h"
 #include "test/gtest.h"
 
@@ -144,7 +144,7 @@
 }
 
 TEST(H264ProfileLevelId, TestParseSdpProfileLevelIdEmpty) {
-  const absl::optional<H264ProfileLevelId> profile_level_id =
+  const std::optional<H264ProfileLevelId> profile_level_id =
       ParseSdpForH264ProfileLevelId(CodecParameterMap());
   EXPECT_TRUE(profile_level_id);
   EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
@@ -155,7 +155,7 @@
 TEST(H264ProfileLevelId, TestParseSdpProfileLevelIdConstrainedHigh) {
   CodecParameterMap params;
   params["profile-level-id"] = "640c2a";
-  const absl::optional<H264ProfileLevelId> profile_level_id =
+  const std::optional<H264ProfileLevelId> profile_level_id =
       ParseSdpForH264ProfileLevelId(params);
   EXPECT_TRUE(profile_level_id);
   EXPECT_EQ(H264Profile::kProfileConstrainedHigh, profile_level_id->profile);
diff --git a/api/video_codecs/test/h265_profile_tier_level_unittest.cc b/api/video_codecs/test/h265_profile_tier_level_unittest.cc
index 8fcabe8..e9095e2 100644
--- a/api/video_codecs/test/h265_profile_tier_level_unittest.cc
+++ b/api/video_codecs/test/h265_profile_tier_level_unittest.cc
@@ -10,9 +10,9 @@
 
 #include "api/video_codecs/h265_profile_tier_level.h"
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/rtp_parameters.h"
 #include "api/video/resolution.h"
 #include "test/gtest.h"
@@ -109,7 +109,7 @@
 }
 
 TEST(H265ProfileTierLevel, TestParseSdpProfileTierLevelAllEmpty) {
-  const absl::optional<H265ProfileTierLevel> profile_tier_level =
+  const std::optional<H265ProfileTierLevel> profile_tier_level =
       ParseSdpForH265ProfileTierLevel(CodecParameterMap());
   EXPECT_TRUE(profile_tier_level);
   EXPECT_EQ(H265Profile::kProfileMain, profile_tier_level->profile);
@@ -121,7 +121,7 @@
   CodecParameterMap params;
   params["profile-id"] = "1";
   params["tier-flag"] = "0";
-  absl::optional<H265ProfileTierLevel> profile_tier_level =
+  std::optional<H265ProfileTierLevel> profile_tier_level =
       ParseSdpForH265ProfileTierLevel(params);
   EXPECT_TRUE(profile_tier_level);
   EXPECT_EQ(H265Profile::kProfileMain, profile_tier_level->profile);
@@ -152,7 +152,7 @@
   params["profile-id"] = "1";
   params["tier-flag"] = "1";
   params["level-id"] = "93";
-  absl::optional<H265ProfileTierLevel> profile_tier_level =
+  std::optional<H265ProfileTierLevel> profile_tier_level =
       ParseSdpForH265ProfileTierLevel(params);
   EXPECT_FALSE(profile_tier_level);
   params.clear();
@@ -176,7 +176,7 @@
   params["profile-id"] = "1";
   params["tier-flag"] = "0";
   params["level-id"] = "93";
-  absl::optional<H265ProfileTierLevel> profile_tier_level =
+  std::optional<H265ProfileTierLevel> profile_tier_level =
       ParseSdpForH265ProfileTierLevel(params);
   EXPECT_TRUE(profile_tier_level);
   EXPECT_EQ("1", H265ProfileToString(profile_tier_level->profile));
@@ -288,12 +288,12 @@
   // Test with 64x64 at 30fps
   r.width = 64;
   r.height = 64;
-  EXPECT_EQ(GetSupportedH265Level(r, 30), absl::nullopt);
+  EXPECT_EQ(GetSupportedH265Level(r, 30), std::nullopt);
 
   // Test with extremly large width or height at 15fps
   r.width = 16928;
   r.height = 64;
-  EXPECT_EQ(GetSupportedH265Level(r, 15), absl::nullopt);
+  EXPECT_EQ(GetSupportedH265Level(r, 15), std::nullopt);
 }
 
 }  // namespace webrtc
diff --git a/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc b/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc
index 331f633..8736484 100644
--- a/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc
+++ b/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc
@@ -13,9 +13,9 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
 #include "api/video/encoded_image.h"
@@ -190,8 +190,8 @@
       return -1;
     }
     void Decoded(webrtc::VideoFrame& decodedImage,
-                 absl::optional<int32_t> decode_time_ms,
-                 absl::optional<uint8_t> qp) override {
+                 std::optional<int32_t> decode_time_ms,
+                 std::optional<uint8_t> qp) override {
       RTC_DCHECK_NOTREACHED();
     }
   } callback;
diff --git a/api/video_codecs/test/video_encoder_factory_template_tests.cc b/api/video_codecs/test/video_encoder_factory_template_tests.cc
index 8b1bf62..cf254ce 100644
--- a/api/video_codecs/test/video_encoder_factory_template_tests.cc
+++ b/api/video_codecs/test/video_encoder_factory_template_tests.cc
@@ -9,9 +9,9 @@
  */
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
 #include "api/test/mock_video_encoder.h"
@@ -90,13 +90,13 @@
 
 TEST(VideoEncoderFactoryTemplate, OneTemplateAdapterCodecSupport) {
   VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter> factory;
-  EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, absl::nullopt),
+  EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, std::nullopt),
               Field(&CodecSupport::is_supported, true));
   EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "L1T2"),
               Field(&CodecSupport::is_supported, true));
   EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "S3T3"),
               Field(&CodecSupport::is_supported, false));
-  EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat("FooX"), absl::nullopt),
+  EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat("FooX"), std::nullopt),
               Field(&CodecSupport::is_supported, false));
 }
 
@@ -125,15 +125,15 @@
   VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter,
                               BarEncoderTemplateAdapter>
       factory;
-  EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, absl::nullopt),
+  EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, std::nullopt),
               Field(&CodecSupport::is_supported, true));
   EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "L1T2"),
               Field(&CodecSupport::is_supported, true));
   EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "S3T3"),
               Field(&CodecSupport::is_supported, false));
-  EXPECT_THAT(factory.QueryCodecSupport(kBarLowSdp, absl::nullopt),
+  EXPECT_THAT(factory.QueryCodecSupport(kBarLowSdp, std::nullopt),
               Field(&CodecSupport::is_supported, true));
-  EXPECT_THAT(factory.QueryCodecSupport(kBarHighSdp, absl::nullopt),
+  EXPECT_THAT(factory.QueryCodecSupport(kBarHighSdp, std::nullopt),
               Field(&CodecSupport::is_supported, true));
   EXPECT_THAT(factory.QueryCodecSupport(kBarLowSdp, "S2T1"),
               Field(&CodecSupport::is_supported, true));
diff --git a/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc b/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc
index a63e8ba..11f234d 100644
--- a/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc
+++ b/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc
@@ -14,11 +14,11 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
 #include "api/fec_controller_override.h"
@@ -164,7 +164,7 @@
     bool supports_native_handle_ = false;
     bool is_qp_trusted_ = false;
     std::string implementation_name_ = "fake-encoder";
-    absl::optional<VideoFrame> last_video_frame_;
+    std::optional<VideoFrame> last_video_frame_;
   };
 
   void InitEncode();
diff --git a/api/video_codecs/video_codec.cc b/api/video_codecs/video_codec.cc
index 0cd6b37..8ee5b1f 100644
--- a/api/video_codecs/video_codec.cc
+++ b/api/video_codecs/video_codec.cc
@@ -12,10 +12,10 @@
 
 #include <string.h>
 
+#include <optional>
 #include <string>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/video/video_codec_type.h"
 #include "api/video_codecs/scalability_mode.h"
 #include "api/video_codecs/simulcast_stream.h"
@@ -86,7 +86,7 @@
      << (mode == VideoCodecMode::kRealtimeVideo ? "RealtimeVideo"
                                                 : "Screensharing");
   if (IsSinglecast()) {
-    absl::optional<ScalabilityMode> scalability_mode = GetScalabilityMode();
+    std::optional<ScalabilityMode> scalability_mode = GetScalabilityMode();
     if (scalability_mode.has_value()) {
       ss << ", Singlecast: {" << width << "x" << height << " "
          << ScalabilityModeToString(*scalability_mode)
@@ -96,7 +96,7 @@
     ss << ", Simulcast: {";
     for (size_t i = 0; i < numberOfSimulcastStreams; ++i) {
       const SimulcastStream stream = simulcastStream[i];
-      absl::optional<ScalabilityMode> scalability_mode =
+      std::optional<ScalabilityMode> scalability_mode =
           stream.GetScalabilityMode();
       if (scalability_mode.has_value()) {
         ss << "[" << stream.width << "x" << stream.height << " "
diff --git a/api/video_codecs/video_codec.h b/api/video_codecs/video_codec.h
index 8872eae..7824d7f 100644
--- a/api/video_codecs/video_codec.h
+++ b/api/video_codecs/video_codec.h
@@ -14,9 +14,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/video/video_codec_constants.h"
 #include "api/video/video_codec_type.h"
 #include "api/video_codecs/scalability_mode.h"
@@ -127,13 +127,13 @@
 
   // Scalability mode as described in
   // https://www.w3.org/TR/webrtc-svc/#scalabilitymodes*
-  absl::optional<ScalabilityMode> GetScalabilityMode() const {
+  std::optional<ScalabilityMode> GetScalabilityMode() const {
     return scalability_mode_;
   }
   void SetScalabilityMode(ScalabilityMode scalability_mode) {
     scalability_mode_ = scalability_mode;
   }
-  void UnsetScalabilityMode() { scalability_mode_ = absl::nullopt; }
+  void UnsetScalabilityMode() { scalability_mode_ = std::nullopt; }
 
   VideoCodecComplexity GetVideoEncoderComplexity() const;
   void SetVideoEncoderComplexity(VideoCodecComplexity complexity_setting);
@@ -215,7 +215,7 @@
   // TODO(hta): Consider replacing the union with a pointer type.
   // This will allow removing the VideoCodec* types from this file.
   VideoCodecUnion codec_specific_;
-  absl::optional<ScalabilityMode> scalability_mode_;
+  std::optional<ScalabilityMode> scalability_mode_;
   // 'complexity_' indicates the CPU capability of the client. It's used to
   // determine encoder CPU complexity (e.g., cpu_used for VP8, VP9. and AV1).
   VideoCodecComplexity complexity_;
diff --git a/api/video_codecs/video_decoder.cc b/api/video_codecs/video_decoder.cc
index b6a7493..d60636c 100644
--- a/api/video_codecs/video_decoder.cc
+++ b/api/video_codecs/video_decoder.cc
@@ -11,9 +11,9 @@
 #include "api/video_codecs/video_decoder.h"
 
 #include <cstdint>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/video/video_frame.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/strings/string_builder.h"
@@ -27,8 +27,8 @@
 }
 
 void DecodedImageCallback::Decoded(VideoFrame& decodedImage,
-                                   absl::optional<int32_t> decode_time_ms,
-                                   absl::optional<uint8_t> qp) {
+                                   std::optional<int32_t> decode_time_ms,
+                                   std::optional<uint8_t> qp) {
   Decoded(decodedImage, decode_time_ms.value_or(-1));
 }
 
diff --git a/api/video_codecs/video_decoder.h b/api/video_codecs/video_decoder.h
index a951f7f..934e224 100644
--- a/api/video_codecs/video_decoder.h
+++ b/api/video_codecs/video_decoder.h
@@ -12,9 +12,9 @@
 #define API_VIDEO_CODECS_VIDEO_DECODER_H_
 
 #include <cstdint>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/video/encoded_image.h"
 #include "api/video/render_resolution.h"
 #include "api/video/video_codec_type.h"
@@ -37,8 +37,8 @@
   // TODO(sakal): Remove other implementations when upstream projects have been
   // updated.
   virtual void Decoded(VideoFrame& decodedImage,
-                       absl::optional<int32_t> decode_time_ms,
-                       absl::optional<uint8_t> qp);
+                       std::optional<int32_t> decode_time_ms,
+                       std::optional<uint8_t> qp);
 };
 
 class RTC_EXPORT VideoDecoder {
@@ -66,8 +66,8 @@
     // decoder. If value isn't present some codec-default value will be used. If
     // value is present and decoder doesn't have buffer pool the value will be
     // ignored.
-    absl::optional<int> buffer_pool_size() const;
-    void set_buffer_pool_size(absl::optional<int> value);
+    std::optional<int> buffer_pool_size() const;
+    void set_buffer_pool_size(std::optional<int> value);
 
     // When valid, user of the VideoDecoder interface shouldn't `Decode`
     // encoded images with render resolution larger than width and height
@@ -85,7 +85,7 @@
     void set_codec_type(VideoCodecType value) { codec_type_ = value; }
 
    private:
-    absl::optional<int> buffer_pool_size_;
+    std::optional<int> buffer_pool_size_;
     RenderResolution max_resolution_;
     int number_of_cores_ = 1;
     VideoCodecType codec_type_ = kVideoCodecGeneric;
@@ -123,12 +123,12 @@
   virtual const char* ImplementationName() const;
 };
 
-inline absl::optional<int> VideoDecoder::Settings::buffer_pool_size() const {
+inline std::optional<int> VideoDecoder::Settings::buffer_pool_size() const {
   return buffer_pool_size_;
 }
 
 inline void VideoDecoder::Settings::set_buffer_pool_size(
-    absl::optional<int> value) {
+    std::optional<int> value) {
   buffer_pool_size_ = value;
 }
 
diff --git a/api/video_codecs/video_encoder.cc b/api/video_codecs/video_encoder.cc
index 11d6821..c3b5f3a 100644
--- a/api/video_codecs/video_encoder.cc
+++ b/api/video_codecs/video_encoder.cc
@@ -14,12 +14,12 @@
 
 #include <algorithm>
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <vector>
 
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 #include "api/fec_controller_override.h"
 #include "api/units/data_rate.h"
 #include "api/video/video_bitrate_allocation.h"
@@ -240,7 +240,7 @@
   return true;
 }
 
-absl::optional<VideoEncoder::ResolutionBitrateLimits>
+std::optional<VideoEncoder::ResolutionBitrateLimits>
 VideoEncoder::EncoderInfo::GetEncoderBitrateLimitsForResolution(
     int frame_size_pixels) const {
   std::vector<ResolutionBitrateLimits> bitrate_limits =
@@ -269,11 +269,11 @@
     }
 
     if (bitrate_limits[i].frame_size_pixels >= frame_size_pixels) {
-      return absl::optional<ResolutionBitrateLimits>(bitrate_limits[i]);
+      return std::optional<ResolutionBitrateLimits>(bitrate_limits[i]);
     }
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 VideoEncoder::RateControlParameters::RateControlParameters()
diff --git a/api/video_codecs/video_encoder.h b/api/video_codecs/video_encoder.h
index 77564ea..aadf452 100644
--- a/api/video_codecs/video_encoder.h
+++ b/api/video_codecs/video_encoder.h
@@ -14,11 +14,11 @@
 #include <cstddef>
 #include <cstdint>
 #include <limits>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 #include "api/fec_controller_override.h"
 #include "api/units/data_rate.h"
 #include "api/video/encoded_image.h"
@@ -102,7 +102,7 @@
     struct KOff {};
 
    public:
-    // TODO(bugs.webrtc.org/9078): Since absl::optional should be trivially copy
+    // TODO(bugs.webrtc.org/9078): Since std::optional should be trivially copy
     // constructible, this magic value can likely be replaced by a constexpr
     // ScalingSettings value.
     static constexpr KOff kOff = {};
@@ -113,7 +113,7 @@
     ScalingSettings(KOff);  // NOLINT(runtime/explicit)
     ~ScalingSettings();
 
-    absl::optional<QpThresholds> thresholds;
+    std::optional<QpThresholds> thresholds;
 
     // We will never ask for a resolution lower than this.
     // TODO(kthelgason): Lower this limit when better testing
@@ -242,8 +242,8 @@
 
     // Obtains the limits from `resolution_bitrate_limits` that best matches the
     // `frame_size_pixels`.
-    absl::optional<ResolutionBitrateLimits>
-    GetEncoderBitrateLimitsForResolution(int frame_size_pixels) const;
+    std::optional<ResolutionBitrateLimits> GetEncoderBitrateLimitsForResolution(
+        int frame_size_pixels) const;
 
     // If true, this encoder has internal support for generating simulcast
     // streams. Otherwise, an adapter class will be needed.
@@ -260,12 +260,12 @@
 
     // Indicates whether or not QP value encoder writes into frame/slice/tile
     // header can be interpreted as average frame/slice/tile QP.
-    absl::optional<bool> is_qp_trusted;
+    std::optional<bool> is_qp_trusted;
 
     // The minimum QP that the encoder is expected to use with the current
     // configuration. This may be used to determine if the encoder has reached
     // its target video quality for static screenshare content.
-    absl::optional<int> min_qp;
+    std::optional<int> min_qp;
   };
 
   struct RTC_EXPORT RateControlParameters {
@@ -307,7 +307,7 @@
     // all decodable.
     // `false` if some dependencies were undecodable, `true` if all dependencies
     // were decodable, and `nullopt` if the dependencies are unknown.
-    absl::optional<bool> dependencies_of_last_received_decodable;
+    std::optional<bool> dependencies_of_last_received_decodable;
     // Describes whether the received frame was decodable.
     // `false` if some dependency was undecodable or if some packet belonging
     // to the last received frame was missed.
@@ -315,7 +315,7 @@
     // to the last received frame were received.
     // `nullopt` if no packet belonging to the last frame was missed, but the
     // last packet in the frame was not yet received.
-    absl::optional<bool> last_received_decodable;
+    std::optional<bool> last_received_decodable;
   };
 
   // Negotiated capabilities which the VideoEncoder may expect the other
@@ -339,7 +339,7 @@
     size_t max_payload_size;
     // Experimental API - currently only supported by LibvpxVp8Encoder and
     // the OpenH264 encoder. If set, limits the number of encoder threads.
-    absl::optional<int> encoder_thread_limit;
+    std::optional<int> encoder_thread_limit;
   };
 
   static VideoCodecVP8 GetDefaultVp8Settings();
diff --git a/api/video_codecs/video_encoder_factory.h b/api/video_codecs/video_encoder_factory.h
index d6e7ff9..cb00f92 100644
--- a/api/video_codecs/video_encoder_factory.h
+++ b/api/video_codecs/video_encoder_factory.h
@@ -12,10 +12,10 @@
 #define API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/units/data_rate.h"
 #include "api/video/render_resolution.h"
@@ -48,19 +48,19 @@
 
     // Called every time the available bitrate is updated. Should return a
     // non-empty if an encoder switch should be performed.
-    virtual absl::optional<SdpVideoFormat> OnAvailableBitrate(
+    virtual std::optional<SdpVideoFormat> OnAvailableBitrate(
         const DataRate& rate) = 0;
 
     // Called every time the encoder input resolution change. Should return a
     // non-empty if an encoder switch should be performed.
-    virtual absl::optional<SdpVideoFormat> OnResolutionChange(
+    virtual std::optional<SdpVideoFormat> OnResolutionChange(
         const RenderResolution& resolution) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     // Called if the currently used encoder reports itself as broken. Should
     // return a non-empty if an encoder switch should be performed.
-    virtual absl::optional<SdpVideoFormat> OnEncoderBroken() = 0;
+    virtual std::optional<SdpVideoFormat> OnEncoderBroken() = 0;
   };
 
   // Returns a list of supported video formats in order of preference, to use
@@ -84,7 +84,7 @@
   // subject to change without notice.
   virtual CodecSupport QueryCodecSupport(
       const SdpVideoFormat& format,
-      absl::optional<std::string> scalability_mode) const {
+      std::optional<std::string> scalability_mode) const {
     // Default implementation, query for supported formats and check if the
     // specified format is supported. Returns false if scalability_mode is
     // specified.
diff --git a/api/video_codecs/video_encoder_factory_template.h b/api/video_codecs/video_encoder_factory_template.h
index 599c12a..a185d0a 100644
--- a/api/video_codecs/video_encoder_factory_template.h
+++ b/api/video_codecs/video_encoder_factory_template.h
@@ -12,11 +12,11 @@
 #define API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/environment/environment.h"
 #include "api/video_codecs/scalability_mode.h"
@@ -63,14 +63,14 @@
     // recognize the parameter. The not so valid reason is that we have started
     // adding parameters completely unrelated to the SDP to the SdpVideoFormat.
     // TODO: bugs.webrtc.org/13868 - Remove FuzzyMatchSdpVideoFormat
-    absl::optional<SdpVideoFormat> matched =
+    std::optional<SdpVideoFormat> matched =
         FuzzyMatchSdpVideoFormat(GetSupportedFormats(), format);
     return CreateInternal<Ts...>(env, matched.value_or(format));
   }
 
   CodecSupport QueryCodecSupport(
       const SdpVideoFormat& format,
-      absl::optional<std::string> scalability_mode) const override {
+      std::optional<std::string> scalability_mode) const override {
     return QueryCodecSupportInternal<Ts...>(format, scalability_mode);
   }
 
@@ -87,11 +87,11 @@
 
   template <typename V>
   bool IsScalabilityModeSupported(
-      const absl::optional<std::string>& scalability_mode_string) const {
+      const std::optional<std::string>& scalability_mode_string) const {
     if (!scalability_mode_string.has_value()) {
       return true;
     }
-    absl::optional<ScalabilityMode> scalability_mode =
+    std::optional<ScalabilityMode> scalability_mode =
         ScalabilityModeFromString(*scalability_mode_string);
     return scalability_mode.has_value() &&
            V::IsScalabilityModeSupported(*scalability_mode);
@@ -131,7 +131,7 @@
   template <typename V, typename... Vs>
   CodecSupport QueryCodecSupportInternal(
       const SdpVideoFormat& format,
-      const absl::optional<std::string>& scalability_mode) const {
+      const std::optional<std::string>& scalability_mode) const {
     if (IsFormatInList(format, V::SupportedFormats())) {
       return {.is_supported = IsScalabilityModeSupported<V>(scalability_mode)};
     }
diff --git a/api/video_codecs/video_encoder_interface.h b/api/video_codecs/video_encoder_interface.h
index dc64e18..37e44a3 100644
--- a/api/video_codecs/video_encoder_interface.h
+++ b/api/video_codecs/video_encoder_interface.h
@@ -13,9 +13,9 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/array_view.h"
 #include "api/scoped_refptr.h"
@@ -69,7 +69,7 @@
     int spatial_id = 0;
     Resolution resolution;
     std::vector<int> reference_buffers;
-    absl::optional<int> update_buffer;
+    std::optional<int> update_buffer;
     int effort_level = 0;
 
     std::unique_ptr<FrameOutput> frame_output;
diff --git a/api/video_codecs/video_encoder_software_fallback_wrapper.cc b/api/video_codecs/video_encoder_software_fallback_wrapper.cc
index 2993e16..c3e9ad9 100644
--- a/api/video_codecs/video_encoder_software_fallback_wrapper.cc
+++ b/api/video_codecs/video_encoder_software_fallback_wrapper.cc
@@ -14,12 +14,12 @@
 
 #include <cstdio>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/fec_controller_override.h"
 #include "api/field_trials_view.h"
@@ -83,7 +83,7 @@
 const char kVp8ForceFallbackEncoderFieldTrial[] =
     "WebRTC-VP8-Forced-Fallback-Encoder-v2";
 
-absl::optional<ForcedFallbackParams> ParseFallbackParamsFromFieldTrials(
+std::optional<ForcedFallbackParams> ParseFallbackParamsFromFieldTrials(
     const FieldTrialsView& field_trials,
     const VideoEncoder& main_encoder) {
   // Ignore WebRTC-VP8-Forced-Fallback-Encoder-v2 if
@@ -101,7 +101,7 @@
   const std::string field_trial =
       field_trials.Lookup(kVp8ForceFallbackEncoderFieldTrial);
   if (!absl::StartsWith(field_trial, "Enabled")) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   int max_pixels_lower_bound =
@@ -115,23 +115,23 @@
              &params.max_pixels, &min_bps) != 3) {
     RTC_LOG(LS_WARNING)
         << "Invalid number of forced fallback parameters provided.";
-    return absl::nullopt;
+    return std::nullopt;
   } else if (params.min_pixels <= 0 ||
              params.max_pixels < max_pixels_lower_bound ||
              params.max_pixels < params.min_pixels || min_bps <= 0) {
     RTC_LOG(LS_WARNING) << "Invalid forced fallback parameter value provided.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   params.vp8_specific_resolution_switch = true;
   return params;
 }
 
-absl::optional<ForcedFallbackParams> GetForcedFallbackParams(
+std::optional<ForcedFallbackParams> GetForcedFallbackParams(
     const FieldTrialsView& field_trials,
     bool prefer_temporal_support,
     const VideoEncoder& main_encoder) {
-  absl::optional<ForcedFallbackParams> params =
+  std::optional<ForcedFallbackParams> params =
       ParseFallbackParamsFromFieldTrials(field_trials, main_encoder);
   if (prefer_temporal_support) {
     if (!params.has_value()) {
@@ -203,15 +203,15 @@
   // Settings used in the last InitEncode call and used if a dynamic fallback to
   // software is required.
   VideoCodec codec_settings_;
-  absl::optional<VideoEncoder::Settings> encoder_settings_;
+  std::optional<VideoEncoder::Settings> encoder_settings_;
 
   // The last rate control settings, if set.
-  absl::optional<RateControlParameters> rate_control_parameters_;
+  std::optional<RateControlParameters> rate_control_parameters_;
 
   // The last channel parameters set.
-  absl::optional<float> packet_loss_;
-  absl::optional<int64_t> rtt_;
-  absl::optional<LossNotification> loss_notification_;
+  std::optional<float> packet_loss_;
+  std::optional<int64_t> rtt_;
+  std::optional<LossNotification> loss_notification_;
 
   enum class EncoderState {
     kUninitialized,
@@ -226,7 +226,7 @@
 
   EncodedImageCallback* callback_;
 
-  const absl::optional<ForcedFallbackParams> fallback_params_;
+  const std::optional<ForcedFallbackParams> fallback_params_;
   int32_t EncodeWithMainEncoder(const VideoFrame& frame,
                                 const std::vector<VideoFrameType>* frame_types);
 };
@@ -327,7 +327,7 @@
   codec_settings_ = *codec_settings;
   encoder_settings_ = settings;
   // Clear stored rate/channel parameters.
-  rate_control_parameters_ = absl::nullopt;
+  rate_control_parameters_ = std::nullopt;
 
   RTC_DCHECK_EQ(encoder_state_, EncoderState::kUninitialized)
       << "InitEncode() should never be called on an active instance!";
diff --git a/api/video_codecs/vp8_frame_buffer_controller.h b/api/video_codecs/vp8_frame_buffer_controller.h
index f9f0e5f..b5dd2c0 100644
--- a/api/video_codecs/vp8_frame_buffer_controller.h
+++ b/api/video_codecs/vp8_frame_buffer_controller.h
@@ -15,9 +15,9 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/fec_controller_override.h"
 #include "api/video_codecs/video_codec.h"
 #include "api/video_codecs/video_encoder.h"
@@ -82,16 +82,16 @@
     std::array<uint32_t, kMaxPeriodicity> ts_layer_id;
   };
 
-  absl::optional<TemporalLayerConfig> temporal_layer_config;
+  std::optional<TemporalLayerConfig> temporal_layer_config;
 
   // Target bitrate, in bps.
-  absl::optional<uint32_t> rc_target_bitrate;
+  std::optional<uint32_t> rc_target_bitrate;
 
   // Clamp QP to max. Use 0 to disable clamping.
-  absl::optional<uint32_t> rc_max_quantizer;
+  std::optional<uint32_t> rc_max_quantizer;
 
   // Error resilience mode.
-  absl::optional<uint32_t> g_error_resilient;
+  std::optional<uint32_t> g_error_resilient;
 
   // If set to true, all previous configuration overrides should be reset.
   bool reset_previous_configuration_overrides = false;
diff --git a/api/video_codecs/vp9_profile.cc b/api/video_codecs/vp9_profile.cc
index ba694b0..a00849d 100644
--- a/api/video_codecs/vp9_profile.cc
+++ b/api/video_codecs/vp9_profile.cc
@@ -11,10 +11,10 @@
 #include "api/video_codecs/vp9_profile.h"
 
 #include <map>
+#include <optional>
 #include <string>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/rtp_parameters.h"
 #include "rtc_base/string_to_number.h"
 
@@ -37,10 +37,10 @@
   return "0";
 }
 
-absl::optional<VP9Profile> StringToVP9Profile(const std::string& str) {
-  const absl::optional<int> i = rtc::StringToNumber<int>(str);
+std::optional<VP9Profile> StringToVP9Profile(const std::string& str) {
+  const std::optional<int> i = rtc::StringToNumber<int>(str);
   if (!i.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
   switch (i.value()) {
     case 0:
@@ -52,11 +52,11 @@
     case 3:
       return VP9Profile::kProfile3;
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
-absl::optional<VP9Profile> ParseSdpForVP9Profile(
+std::optional<VP9Profile> ParseSdpForVP9Profile(
     const CodecParameterMap& params) {
   const auto profile_it = params.find(kVP9FmtpProfileId);
   if (profile_it == params.end())
@@ -67,8 +67,8 @@
 
 bool VP9IsSameProfile(const CodecParameterMap& params1,
                       const CodecParameterMap& params2) {
-  const absl::optional<VP9Profile> profile = ParseSdpForVP9Profile(params1);
-  const absl::optional<VP9Profile> other_profile =
+  const std::optional<VP9Profile> profile = ParseSdpForVP9Profile(params1);
+  const std::optional<VP9Profile> other_profile =
       ParseSdpForVP9Profile(params2);
   return profile && other_profile && profile == other_profile;
 }
diff --git a/api/video_codecs/vp9_profile.h b/api/video_codecs/vp9_profile.h
index 59b665f..94ac01c 100644
--- a/api/video_codecs/vp9_profile.h
+++ b/api/video_codecs/vp9_profile.h
@@ -11,9 +11,9 @@
 #ifndef API_VIDEO_CODECS_VP9_PROFILE_H_
 #define API_VIDEO_CODECS_VP9_PROFILE_H_
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/rtp_parameters.h"
 #include "rtc_base/system/rtc_export.h"
 
@@ -35,13 +35,13 @@
 
 // Helper functions to convert std::string to VP9Profile. Returns null if given
 // an invalid profile string.
-absl::optional<VP9Profile> StringToVP9Profile(const std::string& str);
+std::optional<VP9Profile> StringToVP9Profile(const std::string& str);
 
 // Parse profile that is represented as a string of single digit contained in an
 // SDP key-value map. A default profile(kProfile0) will be returned if the
 // profile key is missing. Nothing will be returned if the key is present but
 // the string is invalid.
-RTC_EXPORT absl::optional<VP9Profile> ParseSdpForVP9Profile(
+RTC_EXPORT std::optional<VP9Profile> ParseSdpForVP9Profile(
     const CodecParameterMap& params);
 
 // Returns true if the parameters have the same VP9 profile, or neither contains
diff --git a/api/video_track_source_constraints.h b/api/video_track_source_constraints.h
index 55e5396..97b20f0 100644
--- a/api/video_track_source_constraints.h
+++ b/api/video_track_source_constraints.h
@@ -16,15 +16,15 @@
 #ifndef API_VIDEO_TRACK_SOURCE_CONSTRAINTS_H_
 #define API_VIDEO_TRACK_SOURCE_CONSTRAINTS_H_
 
-#include "absl/types/optional.h"
+#include <optional>
 
 namespace webrtc {
 
 // This struct definition describes constraints on the video source that may be
 // set with VideoTrackSourceInterface::ProcessConstraints.
 struct VideoTrackSourceConstraints {
-  absl::optional<double> min_fps;
-  absl::optional<double> max_fps;
+  std::optional<double> min_fps;
+  std::optional<double> max_fps;
 };
 
 }  // namespace webrtc
diff --git a/api/voip/BUILD.gn b/api/voip/BUILD.gn
index aa17191..4c0806c 100644
--- a/api/voip/BUILD.gn
+++ b/api/voip/BUILD.gn
@@ -24,7 +24,6 @@
     "../audio_codecs:audio_codecs_api",
     "../neteq:neteq_api",
     "//third_party/abseil-cpp/absl/base:core_headers",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -59,7 +58,6 @@
       "..:array_view",
       "../../test:test_support",
       "../audio_codecs:audio_codecs_api",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
diff --git a/api/voip/test/mock_voip_engine.h b/api/voip/test/mock_voip_engine.h
index 38b857d..9994388 100644
--- a/api/voip/test/mock_voip_engine.h
+++ b/api/voip/test/mock_voip_engine.h
@@ -13,8 +13,8 @@
 
 #include <cstdint>
 #include <map>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio_codecs/audio_format.h"
 #include "api/voip/voip_base.h"
@@ -32,7 +32,7 @@
  public:
   MOCK_METHOD(ChannelId,
               CreateChannel,
-              (Transport*, absl::optional<uint32_t>),
+              (Transport*, std::optional<uint32_t>),
               (override));
   MOCK_METHOD(VoipResult, ReleaseChannel, (ChannelId), (override));
   MOCK_METHOD(VoipResult, StartSend, (ChannelId), (override));
diff --git a/api/voip/voip_base.h b/api/voip/voip_base.h
index d5ff91b..f7f4432 100644
--- a/api/voip/voip_base.h
+++ b/api/voip/voip_base.h
@@ -12,9 +12,9 @@
 #define API_VOIP_VOIP_BASE_H_
 
 #include <cstdint>
+#include <optional>
 
 #include "absl/base/attributes.h"
-#include "absl/types/optional.h"
 
 namespace webrtc {
 
@@ -67,7 +67,7 @@
   // Returns a ChannelId created for caller to handle subsequent Channel
   // operations.
   virtual ChannelId CreateChannel(Transport* transport,
-                                  absl::optional<uint32_t> local_ssrc) = 0;
+                                  std::optional<uint32_t> local_ssrc) = 0;
 
   // Releases `channel_id` that no longer has any use.
   // Returns following VoipResult;
diff --git a/api/voip/voip_statistics.h b/api/voip/voip_statistics.h
index 430349b..8b994d1 100644
--- a/api/voip/voip_statistics.h
+++ b/api/voip/voip_statistics.h
@@ -12,8 +12,8 @@
 #define API_VOIP_VOIP_STATISTICS_H_
 
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/neteq/neteq.h"
 #include "api/voip/voip_base.h"
 
@@ -42,7 +42,7 @@
   double fraction_lost = 0.0;
 
   // https://w3c.github.io/webrtc-stats/#dom-rtcremoteinboundrtpstreamstats-roundtriptime
-  absl::optional<double> round_trip_time;
+  std::optional<double> round_trip_time;
 
   // Last time (not RTP timestamp) when RTCP report received in milliseconds.
   int64_t last_report_received_timestamp_ms;
@@ -69,9 +69,9 @@
 
   // SSRC from remote media endpoint as indicated either by RTP header in RFC
   // 3550 [5.1] or RTCP SSRC of sender in RFC 3550 [6.4.1].
-  absl::optional<uint32_t> remote_ssrc;
+  std::optional<uint32_t> remote_ssrc;
 
-  absl::optional<RemoteRtcpStatistics> remote_rtcp;
+  std::optional<RemoteRtcpStatistics> remote_rtcp;
 };
 
 // VoipStatistics interface provides the interfaces for querying metrics around
diff --git a/audio/BUILD.gn b/audio/BUILD.gn
index e75ca3e..cb83e98 100644
--- a/audio/BUILD.gn
+++ b/audio/BUILD.gn
@@ -116,7 +116,6 @@
     "//third_party/abseil-cpp/absl/functional:any_invocable",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 if (rtc_include_tests) {
@@ -226,7 +225,6 @@
       "utility:utility_tests",
       "//testing/gtest",
       "//third_party/abseil-cpp/absl/memory",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
diff --git a/audio/audio_receive_stream.cc b/audio/audio_receive_stream.cc
index d494b63..44c95f3 100644
--- a/audio/audio_receive_stream.cc
+++ b/audio/audio_receive_stream.cc
@@ -406,7 +406,7 @@
   return remote_ssrc();
 }
 
-absl::optional<Syncable::Info> AudioReceiveStreamImpl::GetInfo() const {
+std::optional<Syncable::Info> AudioReceiveStreamImpl::GetInfo() const {
   // TODO(bugs.webrtc.org/11993): This is called via RtpStreamsSynchronizer,
   // expect to be called on the network thread.
   RTC_DCHECK_RUN_ON(&worker_thread_checker_);
diff --git a/audio/audio_receive_stream.h b/audio/audio_receive_stream.h
index 8c094a4..4eac8a7 100644
--- a/audio/audio_receive_stream.h
+++ b/audio/audio_receive_stream.h
@@ -109,7 +109,7 @@
 
   // Syncable
   uint32_t id() const override;
-  absl::optional<Syncable::Info> GetInfo() const override;
+  std::optional<Syncable::Info> GetInfo() const override;
   bool GetPlayoutRtpTimestamp(uint32_t* rtp_timestamp,
                               int64_t* time_ms) const override;
   void SetEstimatedPlayoutNtpTimestampMs(int64_t ntp_timestamp_ms,
diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc
index fc194c9..6e5bd18 100644
--- a/audio/audio_send_stream.cc
+++ b/audio/audio_send_stream.cc
@@ -49,8 +49,8 @@
                                 const AudioSendStream::Config* old_config) {
   using SendCodecSpec = AudioSendStream::Config::SendCodecSpec;
   // Only update if any of the things we log have changed.
-  auto payload_types_equal = [](const absl::optional<SendCodecSpec>& a,
-                                const absl::optional<SendCodecSpec>& b) {
+  auto payload_types_equal = [](const std::optional<SendCodecSpec>& a,
+                                const std::optional<SendCodecSpec>& b) {
     if (a.has_value() && b.has_value()) {
       return a->format.name == b->format.name &&
              a->payload_type == b->payload_type;
@@ -106,7 +106,7 @@
     RtpTransportControllerSendInterface* rtp_transport,
     BitrateAllocatorInterface* bitrate_allocator,
     RtcpRttStats* rtcp_rtt_stats,
-    const absl::optional<RtpState>& suspended_rtp_state)
+    const std::optional<RtpState>& suspended_rtp_state)
     : AudioSendStream(env,
                       config,
                       audio_state,
@@ -130,7 +130,7 @@
     const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
     RtpTransportControllerSendInterface* rtp_transport,
     BitrateAllocatorInterface* bitrate_allocator,
-    const absl::optional<RtpState>& suspended_rtp_state,
+    const std::optional<RtpState>& suspended_rtp_state,
     std::unique_ptr<voe::ChannelSendInterface> channel_send)
     : env_(env),
       allocate_audio_without_feedback_(
@@ -479,7 +479,7 @@
   // Pick a target bitrate between the constraints. Overrules the allocator if
   // it 1) allocated a bitrate of zero to disable the stream or 2) allocated a
   // higher than max to allow for e.g. extra FEC.
-  absl::optional<TargetAudioBitrateConstraints> constraints =
+  std::optional<TargetAudioBitrateConstraints> constraints =
       GetMinMaxBitrateConstraints();
   if (constraints) {
     update.target_bitrate.Clamp(constraints->min, constraints->max);
@@ -491,7 +491,7 @@
   return 0;
 }
 
-absl::optional<DataRate> AudioSendStream::GetUsedRate() const {
+std::optional<DataRate> AudioSendStream::GetUsedRate() const {
   return channel_send_->GetUsedRate();
 }
 
@@ -657,7 +657,7 @@
     return SetupSendCodec(new_config);
   }
 
-  const absl::optional<int>& new_target_bitrate_bps =
+  const std::optional<int>& new_target_bitrate_bps =
       new_config.send_codec_spec->target_bitrate_bps;
   // If a bitrate has been specified for the codec, use it over the
   // codec's default.
@@ -823,14 +823,14 @@
   bitrate_allocator_->RemoveObserver(this);
 }
 
-absl::optional<AudioSendStream::TargetAudioBitrateConstraints>
+std::optional<AudioSendStream::TargetAudioBitrateConstraints>
 AudioSendStream::GetMinMaxBitrateConstraints() const {
   if (config_.min_bitrate_bps < 0 || config_.max_bitrate_bps < 0) {
     RTC_LOG(LS_WARNING) << "Config is invalid: min_bitrate_bps="
                         << config_.min_bitrate_bps
                         << "; max_bitrate_bps=" << config_.max_bitrate_bps
                         << "; both expected greater or equal to 0";
-    return absl::nullopt;
+    return std::nullopt;
   }
   TargetAudioBitrateConstraints constraints{
       DataRate::BitsPerSec(config_.min_bitrate_bps),
@@ -853,7 +853,7 @@
   if (constraints.max < constraints.min) {
     RTC_LOG(LS_WARNING) << "TargetAudioBitrateConstraints::max is less than "
                         << "TargetAudioBitrateConstraints::min";
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (use_legacy_overhead_calculation_) {
     // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
@@ -866,7 +866,7 @@
   } else {
     if (!frame_length_range_.has_value()) {
       RTC_LOG(LS_WARNING) << "frame_length_range_ is not set";
-      return absl::nullopt;
+      return std::nullopt;
     }
     const DataSize overhead_per_packet = DataSize::Bytes(overhead_per_packet_);
     constraints.min += overhead_per_packet / frame_length_range_->second;
diff --git a/audio/audio_send_stream.h b/audio/audio_send_stream.h
index 3845e8d..62a5537 100644
--- a/audio/audio_send_stream.h
+++ b/audio/audio_send_stream.h
@@ -38,13 +38,13 @@
   static constexpr char kKey[] = "WebRTC-Audio-Allocation";
   // Field Trial configured bitrates to use as overrides over default/user
   // configured bitrate range when audio bitrate allocation is enabled.
-  absl::optional<DataRate> min_bitrate;
-  absl::optional<DataRate> max_bitrate;
+  std::optional<DataRate> min_bitrate;
+  std::optional<DataRate> max_bitrate;
   DataRate priority_bitrate = DataRate::Zero();
   // By default the priority_bitrate is compensated for packet overhead.
   // Use this flag to configure a raw value instead.
-  absl::optional<DataRate> priority_bitrate_raw;
-  absl::optional<double> bitrate_priority;
+  std::optional<DataRate> priority_bitrate_raw;
+  std::optional<double> bitrate_priority;
 
   std::unique_ptr<StructParametersParser> Parser();
   explicit AudioAllocationConfig(const FieldTrialsView& field_trials);
@@ -61,14 +61,14 @@
                   RtpTransportControllerSendInterface* rtp_transport,
                   BitrateAllocatorInterface* bitrate_allocator,
                   RtcpRttStats* rtcp_rtt_stats,
-                  const absl::optional<RtpState>& suspended_rtp_state);
+                  const std::optional<RtpState>& suspended_rtp_state);
   // For unit tests, which need to supply a mock ChannelSend.
   AudioSendStream(const Environment& env,
                   const webrtc::AudioSendStream::Config& config,
                   const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
                   RtpTransportControllerSendInterface* rtp_transport,
                   BitrateAllocatorInterface* bitrate_allocator,
-                  const absl::optional<RtpState>& suspended_rtp_state,
+                  const std::optional<RtpState>& suspended_rtp_state,
                   std::unique_ptr<voe::ChannelSendInterface> channel_send);
 
   AudioSendStream() = delete;
@@ -97,7 +97,7 @@
 
   // Implements BitrateAllocatorObserver.
   uint32_t OnBitrateUpdated(BitrateAllocationUpdate update) override;
-  absl::optional<DataRate> GetUsedRate() const override;
+  std::optional<DataRate> GetUsedRate() const override;
 
   void SetTransportOverhead(int transport_overhead_per_packet_bytes);
 
@@ -141,7 +141,7 @@
 
   // Returns bitrate constraints, maybe including overhead when enabled by
   // field trial.
-  absl::optional<TargetAudioBitrateConstraints> GetMinMaxBitrateConstraints()
+  std::optional<TargetAudioBitrateConstraints> GetMinMaxBitrateConstraints()
       const RTC_RUN_ON(worker_thread_checker_);
 
   // Sets per-packet overhead on encoded (for ANA) based on current known values
@@ -181,7 +181,7 @@
   RtpTransportControllerSendInterface* const rtp_transport_;
 
   RtpRtcpInterface* const rtp_rtcp_module_;
-  absl::optional<RtpState> const suspended_rtp_state_;
+  std::optional<RtpState> const suspended_rtp_state_;
 
   // RFC 5285: Each distinct extension MUST have a unique ID. The value 0 is
   // reserved for padding and MUST NOT be used as a local identifier.
@@ -207,9 +207,9 @@
 
   bool registered_with_allocator_ RTC_GUARDED_BY(worker_thread_checker_) =
       false;
-  absl::optional<std::pair<TimeDelta, TimeDelta>> frame_length_range_
+  std::optional<std::pair<TimeDelta, TimeDelta>> frame_length_range_
       RTC_GUARDED_BY(worker_thread_checker_);
-  absl::optional<std::pair<DataRate, DataRate>> bitrate_range_
+  std::optional<std::pair<DataRate, DataRate>> bitrate_range_
       RTC_GUARDED_BY(worker_thread_checker_);
 };
 }  // namespace internal
diff --git a/audio/audio_send_stream_unittest.cc b/audio/audio_send_stream_unittest.cc
index 6aa95c7..7198a61 100644
--- a/audio/audio_send_stream_unittest.cc
+++ b/audio/audio_send_stream_unittest.cc
@@ -128,13 +128,13 @@
           std::begin(kCodecSpecs), std::end(kCodecSpecs))));
   ON_CALL(*factory, QueryAudioEncoder)
       .WillByDefault(
-          [](const SdpAudioFormat& format) -> absl::optional<AudioCodecInfo> {
+          [](const SdpAudioFormat& format) -> std::optional<AudioCodecInfo> {
             for (const auto& spec : kCodecSpecs) {
               if (format == spec.format) {
                 return spec.info;
               }
             }
-            return absl::nullopt;
+            return std::nullopt;
           });
   ON_CALL(*factory, Create).WillByDefault(WithArg<1>(&SetupAudioEncoderMock));
   return factory;
@@ -183,7 +183,7 @@
         CreateEnvironment(&field_trials, time_controller_.GetClock(),
                           time_controller_.GetTaskQueueFactory()),
         stream_config_, audio_state_, &rtp_transport_, &bitrate_allocator_,
-        absl::nullopt,
+        std::nullopt,
         std::unique_ptr<voe::ChannelSendInterface>(channel_send_));
   }
 
diff --git a/audio/audio_transport_impl.cc b/audio/audio_transport_impl.cc
index b9d8332..09509cd 100644
--- a/audio/audio_transport_impl.cc
+++ b/audio/audio_transport_impl.cc
@@ -118,7 +118,7 @@
   return RecordedDataIsAvailable(
       audio_data, number_of_frames, bytes_per_sample, number_of_channels,
       sample_rate, audio_delay_milliseconds, clock_drift, volume, key_pressed,
-      new_mic_volume, /*estimated_capture_time_ns=*/absl::nullopt);
+      new_mic_volume, /*estimated_capture_time_ns=*/std::nullopt);
 }
 
 // Not used in Chromium. Process captured audio and distribute to all sending
@@ -134,7 +134,7 @@
     uint32_t /*volume*/,
     bool key_pressed,
     uint32_t& /*new_mic_volume*/,
-    absl::optional<int64_t>
+    std::optional<int64_t>
         estimated_capture_time_ns) {  // NOLINT: to avoid changing APIs
   RTC_DCHECK(audio_data);
   RTC_DCHECK_GE(number_of_channels, 1);
diff --git a/audio/audio_transport_impl.h b/audio/audio_transport_impl.h
index 3012cc2..8eac8ef 100644
--- a/audio/audio_transport_impl.h
+++ b/audio/audio_transport_impl.h
@@ -63,7 +63,7 @@
       uint32_t currentMicLevel,
       bool keyPressed,
       uint32_t& newMicLevel,
-      absl::optional<int64_t> estimated_capture_time_ns) override;
+      std::optional<int64_t> estimated_capture_time_ns) override;
 
   int32_t NeedMorePlayData(size_t nSamples,
                            size_t nBytesPerSample,
diff --git a/audio/channel_receive.cc b/audio/channel_receive.cc
index e403cfa..7fcdf66 100644
--- a/audio/channel_receive.cc
+++ b/audio/channel_receive.cc
@@ -70,7 +70,7 @@
 acm2::AcmReceiver::Config AcmConfig(
     NetEqFactory* neteq_factory,
     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
-    absl::optional<AudioCodecPairId> codec_pair_id,
+    std::optional<AudioCodecPairId> codec_pair_id,
     size_t jitter_buffer_max_packets,
     bool jitter_buffer_fast_playout,
     int jitter_buffer_min_delay_ms) {
@@ -102,7 +102,7 @@
       int jitter_buffer_min_delay_ms,
       bool enable_non_sender_rtt,
       rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
-      absl::optional<AudioCodecPairId> codec_pair_id,
+      std::optional<AudioCodecPairId> codec_pair_id,
       rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor,
       const webrtc::CryptoOptions& crypto_options,
       rtc::scoped_refptr<FrameTransformerInterface> frame_transformer);
@@ -118,7 +118,7 @@
   void StopPlayout() override;
 
   // Codecs
-  absl::optional<std::pair<int, SdpAudioFormat>> GetReceiveCodec()
+  std::optional<std::pair<int, SdpAudioFormat>> GetReceiveCodec()
       const override;
 
   void ReceivedRTCPPacket(const uint8_t* data, size_t length) override;
@@ -146,7 +146,7 @@
                               int64_t* time_ms) const override;
   void SetEstimatedPlayoutNtpTimestampMs(int64_t ntp_timestamp_ms,
                                          int64_t time_ms) override;
-  absl::optional<int64_t> GetCurrentEstimatedPlayoutNtpTimestampMs(
+  std::optional<int64_t> GetCurrentEstimatedPlayoutNtpTimestampMs(
       int64_t now_ms) const override;
 
   // Audio quality.
@@ -154,7 +154,7 @@
   int GetBaseMinimumPlayoutDelayMs() const override;
 
   // Produces the transport-related timestamps; current_delay_ms is left unset.
-  absl::optional<Syncable::Info> GetSyncInfo() const override;
+  std::optional<Syncable::Info> GetSyncInfo() const override;
 
   void RegisterReceiverCongestionControlObjects(
       PacketRouter* packet_router) override;
@@ -244,9 +244,9 @@
 
   // Info for GetSyncInfo is updated on network or worker thread, and queried on
   // the worker thread.
-  absl::optional<uint32_t> last_received_rtp_timestamp_
+  std::optional<uint32_t> last_received_rtp_timestamp_
       RTC_GUARDED_BY(&worker_thread_checker_);
-  absl::optional<int64_t> last_received_rtp_system_time_ms_
+  std::optional<int64_t> last_received_rtp_system_time_ms_
       RTC_GUARDED_BY(&worker_thread_checker_);
 
   // The AcmReceiver is thread safe, using its own lock.
@@ -257,15 +257,15 @@
   RemoteNtpTimeEstimator ntp_estimator_ RTC_GUARDED_BY(ts_stats_lock_);
 
   // Timestamp of the audio pulled from NetEq.
-  absl::optional<uint32_t> jitter_buffer_playout_timestamp_;
+  std::optional<uint32_t> jitter_buffer_playout_timestamp_;
 
   uint32_t playout_timestamp_rtp_ RTC_GUARDED_BY(worker_thread_checker_);
-  absl::optional<int64_t> playout_timestamp_rtp_time_ms_
+  std::optional<int64_t> playout_timestamp_rtp_time_ms_
       RTC_GUARDED_BY(worker_thread_checker_);
   uint32_t playout_delay_ms_ RTC_GUARDED_BY(worker_thread_checker_);
-  absl::optional<int64_t> playout_timestamp_ntp_
+  std::optional<int64_t> playout_timestamp_ntp_
       RTC_GUARDED_BY(worker_thread_checker_);
-  absl::optional<int64_t> playout_timestamp_ntp_time_ms_
+  std::optional<int64_t> playout_timestamp_ntp_time_ms_
       RTC_GUARDED_BY(worker_thread_checker_);
 
   mutable Mutex ts_stats_lock_;
@@ -530,7 +530,7 @@
     int jitter_buffer_min_delay_ms,
     bool enable_non_sender_rtt,
     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
-    absl::optional<AudioCodecPairId> codec_pair_id,
+    std::optional<AudioCodecPairId> codec_pair_id,
     rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor,
     const webrtc::CryptoOptions& crypto_options,
     rtc::scoped_refptr<FrameTransformerInterface> frame_transformer)
@@ -609,7 +609,7 @@
   acm_receiver_.FlushBuffers();
 }
 
-absl::optional<std::pair<int, SdpAudioFormat>> ChannelReceive::GetReceiveCodec()
+std::optional<std::pair<int, SdpAudioFormat>> ChannelReceive::GetReceiveCodec()
     const {
   RTC_DCHECK_RUN_ON(&worker_thread_checker_);
   return acm_receiver_.LastDecoder();
@@ -736,13 +736,13 @@
   // Deliver RTCP packet to RTP/RTCP module for parsing
   rtp_rtcp_->IncomingRtcpPacket(rtc::MakeArrayView(data, length));
 
-  absl::optional<TimeDelta> rtt = rtp_rtcp_->LastRtt();
+  std::optional<TimeDelta> rtt = rtp_rtcp_->LastRtt();
   if (!rtt.has_value()) {
     // Waiting for valid RTT.
     return;
   }
 
-  absl::optional<RtpRtcpInterface::SenderReportStats> last_sr =
+  std::optional<RtpRtcpInterface::SenderReportStats> last_sr =
       rtp_rtcp_->GetSenderReportStats();
   if (!last_sr.has_value()) {
     // Waiting for RTCP.
@@ -753,7 +753,7 @@
     MutexLock lock(&ts_stats_lock_);
     ntp_estimator_.UpdateRtcpTimestamp(*rtt, last_sr->last_remote_timestamp,
                                        last_sr->last_remote_rtp_timestamp);
-    absl::optional<int64_t> remote_to_local_clock_offset =
+    std::optional<int64_t> remote_to_local_clock_offset =
         ntp_estimator_.EstimateRemoteToLocalClockOffset();
     if (remote_to_local_clock_offset.has_value()) {
       capture_clock_offset_updater_.SetRemoteToLocalClockOffset(
@@ -829,7 +829,7 @@
     stats.payload_bytes_received = 0;
     stats.header_and_padding_bytes_received = 0;
     stats.packetsReceived = 0;
-    stats.last_packet_received = absl::nullopt;
+    stats.last_packet_received = std::nullopt;
   }
 
   {
@@ -843,7 +843,7 @@
     stats.capture_start_ntp_time_ms_ = capture_start_ntp_time_ms_;
   }
 
-  absl::optional<RtpRtcpInterface::SenderReportStats> rtcp_sr_stats =
+  std::optional<RtpRtcpInterface::SenderReportStats> rtcp_sr_stats =
       rtp_rtcp_->GetSenderReportStats();
   if (rtcp_sr_stats.has_value()) {
     stats.last_sender_report_timestamp_ms =
@@ -856,7 +856,7 @@
     stats.sender_reports_reports_count = rtcp_sr_stats->reports_count;
   }
 
-  absl::optional<RtpRtcpInterface::NonSenderRttStats> non_sender_rtt_stats =
+  std::optional<RtpRtcpInterface::NonSenderRttStats> non_sender_rtt_stats =
       rtp_rtcp_->GetNonSenderRttStats();
   if (non_sender_rtt_stats.has_value()) {
     stats.round_trip_time = non_sender_rtt_stats->round_trip_time;
@@ -1007,11 +1007,11 @@
   playout_timestamp_ntp_time_ms_ = time_ms;
 }
 
-absl::optional<int64_t>
-ChannelReceive::GetCurrentEstimatedPlayoutNtpTimestampMs(int64_t now_ms) const {
+std::optional<int64_t> ChannelReceive::GetCurrentEstimatedPlayoutNtpTimestampMs(
+    int64_t now_ms) const {
   RTC_DCHECK_RUN_ON(&worker_thread_checker_);
   if (!playout_timestamp_ntp_ || !playout_timestamp_ntp_time_ms_)
-    return absl::nullopt;
+    return std::nullopt;
 
   int64_t elapsed_ms = now_ms - *playout_timestamp_ntp_time_ms_;
   return *playout_timestamp_ntp_ + elapsed_ms;
@@ -1027,23 +1027,23 @@
   return acm_receiver_.GetBaseMinimumDelayMs();
 }
 
-absl::optional<Syncable::Info> ChannelReceive::GetSyncInfo() const {
+std::optional<Syncable::Info> ChannelReceive::GetSyncInfo() const {
   // TODO(bugs.webrtc.org/11993): This should run on the network thread.
   // We get here via RtpStreamsSynchronizer. Once that's done, many of
   // these locks aren't needed.
   RTC_DCHECK_RUN_ON(&worker_thread_checker_);
   Syncable::Info info;
-  absl::optional<RtpRtcpInterface::SenderReportStats> last_sr =
+  std::optional<RtpRtcpInterface::SenderReportStats> last_sr =
       rtp_rtcp_->GetSenderReportStats();
   if (!last_sr.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   info.capture_time_ntp_secs = last_sr->last_remote_timestamp.seconds();
   info.capture_time_ntp_frac = last_sr->last_remote_timestamp.fractions();
   info.capture_time_source_clock = last_sr->last_remote_rtp_timestamp;
 
   if (!last_received_rtp_timestamp_ || !last_received_rtp_system_time_ms_) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   info.latest_received_capture_timestamp = *last_received_rtp_timestamp_;
   info.latest_receive_time_ms = *last_received_rtp_system_time_ms_;
@@ -1116,7 +1116,7 @@
     int jitter_buffer_min_delay_ms,
     bool enable_non_sender_rtt,
     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
-    absl::optional<AudioCodecPairId> codec_pair_id,
+    std::optional<AudioCodecPairId> codec_pair_id,
     rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor,
     const webrtc::CryptoOptions& crypto_options,
     rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {
diff --git a/audio/channel_receive.h b/audio/channel_receive.h
index 0e73eac..0a11573 100644
--- a/audio/channel_receive.h
+++ b/audio/channel_receive.h
@@ -13,10 +13,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_mixer.h"
 #include "api/audio_codecs/audio_decoder_factory.h"
 #include "api/call/audio_sink.h"
@@ -62,17 +62,17 @@
   // The timestamp at which the last packet was received, i.e. the time of the
   // local clock when it was received - not the RTP timestamp of that packet.
   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-lastpacketreceivedtimestamp
-  absl::optional<Timestamp> last_packet_received;
+  std::optional<Timestamp> last_packet_received;
   // Remote outbound stats derived by the received RTCP sender reports.
   // Note that the timestamps below correspond to the time elapsed since the
   // Unix epoch.
   // https://w3c.github.io/webrtc-stats/#remoteoutboundrtpstats-dict*
-  absl::optional<int64_t> last_sender_report_timestamp_ms;
-  absl::optional<int64_t> last_sender_report_remote_timestamp_ms;
+  std::optional<int64_t> last_sender_report_timestamp_ms;
+  std::optional<int64_t> last_sender_report_remote_timestamp_ms;
   uint64_t sender_reports_packets_sent = 0;
   uint64_t sender_reports_bytes_sent = 0;
   uint64_t sender_reports_reports_count = 0;
-  absl::optional<TimeDelta> round_trip_time;
+  std::optional<TimeDelta> round_trip_time;
   TimeDelta total_round_trip_time = TimeDelta::Zero();
   int round_trip_time_measurements;
 };
@@ -97,7 +97,7 @@
   virtual void StopPlayout() = 0;
 
   // Payload type and format of last received RTP packet, if any.
-  virtual absl::optional<std::pair<int, SdpAudioFormat>> GetReceiveCodec()
+  virtual std::optional<std::pair<int, SdpAudioFormat>> GetReceiveCodec()
       const = 0;
 
   virtual void ReceivedRTCPPacket(const uint8_t* data, size_t length) = 0;
@@ -121,7 +121,7 @@
                                       int64_t* time_ms) const = 0;
   virtual void SetEstimatedPlayoutNtpTimestampMs(int64_t ntp_timestamp_ms,
                                                  int64_t time_ms) = 0;
-  virtual absl::optional<int64_t> GetCurrentEstimatedPlayoutNtpTimestampMs(
+  virtual std::optional<int64_t> GetCurrentEstimatedPlayoutNtpTimestampMs(
       int64_t now_ms) const = 0;
 
   // Audio quality.
@@ -131,7 +131,7 @@
   virtual int GetBaseMinimumPlayoutDelayMs() const = 0;
 
   // Produces the transport-related timestamps; current_delay_ms is left unset.
-  virtual absl::optional<Syncable::Info> GetSyncInfo() const = 0;
+  virtual std::optional<Syncable::Info> GetSyncInfo() const = 0;
 
   virtual void RegisterReceiverCongestionControlObjects(
       PacketRouter* packet_router) = 0;
@@ -182,7 +182,7 @@
     int jitter_buffer_min_delay_ms,
     bool enable_non_sender_rtt,
     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
-    absl::optional<AudioCodecPairId> codec_pair_id,
+    std::optional<AudioCodecPairId> codec_pair_id,
     rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor,
     const webrtc::CryptoOptions& crypto_options,
     rtc::scoped_refptr<FrameTransformerInterface> frame_transformer);
diff --git a/audio/channel_receive_frame_transformer_delegate.cc b/audio/channel_receive_frame_transformer_delegate.cc
index 795f46f..d82925a 100644
--- a/audio/channel_receive_frame_transformer_delegate.cc
+++ b/audio/channel_receive_frame_transformer_delegate.cc
@@ -12,10 +12,10 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/frame_transformer_interface.h"
 #include "api/rtp_headers.h"
@@ -62,14 +62,14 @@
   Direction GetDirection() const override { return Direction::kReceiver; }
 
   std::string GetMimeType() const override { return codec_mime_type_; }
-  const absl::optional<uint16_t> SequenceNumber() const override {
+  const std::optional<uint16_t> SequenceNumber() const override {
     return header_.sequenceNumber;
   }
 
-  absl::optional<uint64_t> AbsoluteCaptureTimestamp() const override {
+  std::optional<uint64_t> AbsoluteCaptureTimestamp() const override {
     // This could be extracted from received header extensions + extrapolation,
     // if required in future, eg for being able to re-send received frames.
-    return absl::nullopt;
+    return std::nullopt;
   }
   const RTPHeader& Header() const { return header_; }
 
@@ -83,17 +83,17 @@
                : FrameType::kAudioFrameCN;
   }
 
-  absl::optional<uint8_t> AudioLevel() const override {
+  std::optional<uint8_t> AudioLevel() const override {
     if (header_.extension.audio_level()) {
       return header_.extension.audio_level()->level();
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  absl::optional<Timestamp> ReceiveTime() const override {
+  std::optional<Timestamp> ReceiveTime() const override {
     return receive_time_ == Timestamp::MinusInfinity()
-               ? absl::nullopt
-               : absl::optional<Timestamp>(receive_time_);
+               ? std::nullopt
+               : std::optional<Timestamp>(receive_time_);
   }
 
  private:
diff --git a/audio/channel_receive_unittest.cc b/audio/channel_receive_unittest.cc
index 5bc2222..ef9647d 100644
--- a/audio/channel_receive_unittest.cc
+++ b/audio/channel_receive_unittest.cc
@@ -67,7 +67,7 @@
         /* jitter_buffer_fast_playout= */ false,
         /* jitter_buffer_min_delay_ms= */ 0,
         /* enable_non_sender_rtt= */ false, audio_decoder_factory_,
-        /* codec_pair_id= */ absl::nullopt,
+        /* codec_pair_id= */ std::nullopt,
         /* frame_decryptor_interface= */ nullptr, crypto_options,
         /* frame_transformer= */ nullptr);
     channel->SetReceiveCodecs(
diff --git a/audio/channel_send.cc b/audio/channel_send.cc
index 18081e3..d1683b7 100644
--- a/audio/channel_send.cc
+++ b/audio/channel_send.cc
@@ -66,7 +66,7 @@
   void Reset() {
     rate_last_frame_ = DataRate::BitsPerSec(0);
     next_frame_duration_ = TimeDelta::Millis(0);
-    report_rate_ = absl::nullopt;
+    report_rate_ = std::nullopt;
   }
 
   // A new frame is formed when bytesize is nonzero.
@@ -89,13 +89,13 @@
     next_frame_duration_ = TimeDelta::Millis(0);
   }
 
-  absl::optional<DataRate> GetUsedRate() const { return report_rate_; }
+  std::optional<DataRate> GetUsedRate() const { return report_rate_; }
 
  private:
   TimeDelta next_frame_duration_ = TimeDelta::Millis(0);
   DataSize packet_overhead_ = DataSize::Bytes(72);
   DataRate rate_last_frame_ = DataRate::BitsPerSec(0);
-  absl::optional<DataRate> report_rate_;
+  std::optional<DataRate> report_rate_;
 };
 
 class ChannelSend : public ChannelSendInterface,
@@ -194,7 +194,7 @@
   void OnReportBlockDataUpdated(ReportBlockData report_block) override;
 
   // Reports actual bitrate used (vs allocated).
-  absl::optional<DataRate> GetUsedRate() const override {
+  std::optional<DataRate> GetUsedRate() const override {
     MutexLock lock(&bitrate_accountant_mutex_);
     return bitrate_accountant_.GetUsedRate();
   }
@@ -221,7 +221,7 @@
                        rtc::ArrayView<const uint8_t> payload,
                        int64_t absolute_capture_timestamp_ms,
                        rtc::ArrayView<const uint32_t> csrcs,
-                       absl::optional<uint8_t> audio_level_dbov)
+                       std::optional<uint8_t> audio_level_dbov)
       RTC_RUN_ON(encoder_queue_checker_);
 
   void OnReceivedRtt(int64_t rtt_ms);
@@ -254,7 +254,7 @@
 
   // This is just an offset, RTP module will add its own random offset.
   uint32_t timestamp_ RTC_GUARDED_BY(audio_thread_race_checker_) = 0;
-  absl::optional<int64_t> last_capture_timestamp_ms_
+  std::optional<int64_t> last_capture_timestamp_ms_
       RTC_GUARDED_BY(audio_thread_race_checker_);
 
   RmsLevel rms_level_ RTC_GUARDED_BY(encoder_queue_checker_);
@@ -352,7 +352,7 @@
   RTC_DCHECK_RUN_ON(&encoder_queue_checker_);
   rtc::ArrayView<const uint8_t> payload(payloadData, payloadSize);
 
-  absl::optional<uint8_t> audio_level_dbov;
+  std::optional<uint8_t> audio_level_dbov;
   if (include_audio_level_indication_.load()) {
     // Take the averaged audio levels from rms_level_ and reset it before
     // invoking any async transformer.
@@ -383,7 +383,7 @@
                                   rtc::ArrayView<const uint8_t> payload,
                                   int64_t absolute_capture_timestamp_ms,
                                   rtc::ArrayView<const uint32_t> csrcs,
-                                  absl::optional<uint8_t> audio_level_dbov) {
+                                  std::optional<uint8_t> audio_level_dbov) {
   // E2EE Custom Audio Frame Encryption (This is optional).
   // Keep this buffer around for the lifetime of the send call.
   rtc::Buffer encrypted_audio_payload;
@@ -942,7 +942,7 @@
              rtc::ArrayView<const uint8_t> payload,
              int64_t absolute_capture_timestamp_ms,
              rtc::ArrayView<const uint32_t> csrcs,
-             absl::optional<uint8_t> audio_level_dbov) {
+             std::optional<uint8_t> audio_level_dbov) {
         RTC_DCHECK_RUN_ON(&encoder_queue_checker_);
         return SendRtpAudio(
             frameType, payloadType,
diff --git a/audio/channel_send.h b/audio/channel_send.h
index 6082c0e..02215e4 100644
--- a/audio/channel_send.h
+++ b/audio/channel_send.h
@@ -112,7 +112,7 @@
           frame_transformer) = 0;
 
   // Returns payload bitrate actually used.
-  virtual absl::optional<DataRate> GetUsedRate() const = 0;
+  virtual std::optional<DataRate> GetUsedRate() const = 0;
 
   // Registers per packet byte overhead.
   virtual void RegisterPacketOverhead(int packet_byte_overhead) = 0;
diff --git a/audio/channel_send_frame_transformer_delegate.cc b/audio/channel_send_frame_transformer_delegate.cc
index 64adef9..dacbfcd 100644
--- a/audio/channel_send_frame_transformer_delegate.cc
+++ b/audio/channel_send_frame_transformer_delegate.cc
@@ -56,12 +56,12 @@
       uint32_t rtp_timestamp_with_offset,
       const uint8_t* payload_data,
       size_t payload_size,
-      absl::optional<uint64_t> absolute_capture_timestamp_ms,
+      std::optional<uint64_t> absolute_capture_timestamp_ms,
       uint32_t ssrc,
       std::vector<uint32_t> csrcs,
       const std::string& codec_mime_type,
-      absl::optional<uint16_t> sequence_number,
-      absl::optional<uint8_t> audio_level_dbov)
+      std::optional<uint16_t> sequence_number,
+      std::optional<uint8_t> audio_level_dbov)
       : TransformableAudioFrameInterface(Passkey()),
         frame_type_(frame_type),
         payload_type_(payload_type),
@@ -93,7 +93,7 @@
     return csrcs_;
   }
 
-  const absl::optional<uint16_t> SequenceNumber() const override {
+  const std::optional<uint16_t> SequenceNumber() const override {
     return sequence_number_;
   }
 
@@ -101,29 +101,27 @@
     rtp_timestamp_with_offset_ = rtp_timestamp_with_offset;
   }
 
-  absl::optional<uint64_t> AbsoluteCaptureTimestamp() const override {
+  std::optional<uint64_t> AbsoluteCaptureTimestamp() const override {
     return absolute_capture_timestamp_ms_;
   }
 
-  absl::optional<uint8_t> AudioLevel() const override {
+  std::optional<uint8_t> AudioLevel() const override {
     return audio_level_dbov_;
   }
 
-  absl::optional<Timestamp> ReceiveTime() const override {
-    return absl::nullopt;
-  }
+  std::optional<Timestamp> ReceiveTime() const override { return std::nullopt; }
 
  private:
   AudioFrameType frame_type_;
   uint8_t payload_type_;
   uint32_t rtp_timestamp_with_offset_;
   rtc::Buffer payload_;
-  absl::optional<uint64_t> absolute_capture_timestamp_ms_;
+  std::optional<uint64_t> absolute_capture_timestamp_ms_;
   uint32_t ssrc_;
   std::vector<uint32_t> csrcs_;
   std::string codec_mime_type_;
-  absl::optional<uint16_t> sequence_number_;
-  absl::optional<uint8_t> audio_level_dbov_;
+  std::optional<uint16_t> sequence_number_;
+  std::optional<uint8_t> audio_level_dbov_;
 };
 
 ChannelSendFrameTransformerDelegate::ChannelSendFrameTransformerDelegate(
@@ -156,7 +154,7 @@
     int64_t absolute_capture_timestamp_ms,
     uint32_t ssrc,
     const std::string& codec_mimetype,
-    absl::optional<uint8_t> audio_level_dbov) {
+    std::optional<uint8_t> audio_level_dbov) {
   {
     MutexLock lock(&send_lock_);
     if (short_circuit_) {
@@ -172,7 +170,7 @@
           frame_type, payload_type, rtp_timestamp, payload_data, payload_size,
           absolute_capture_timestamp_ms, ssrc,
           /*csrcs=*/std::vector<uint32_t>(), codec_mimetype,
-          /*sequence_number=*/absl::nullopt, audio_level_dbov));
+          /*sequence_number=*/std::nullopt, audio_level_dbov));
 }
 
 void ChannelSendFrameTransformerDelegate::OnTransformedFrame(
diff --git a/audio/channel_send_frame_transformer_delegate.h b/audio/channel_send_frame_transformer_delegate.h
index 5573052..628c403 100644
--- a/audio/channel_send_frame_transformer_delegate.h
+++ b/audio/channel_send_frame_transformer_delegate.h
@@ -37,7 +37,7 @@
                             rtc::ArrayView<const uint8_t> payload,
                             int64_t absolute_capture_timestamp_ms,
                             rtc::ArrayView<const uint32_t> csrcs,
-                            absl::optional<uint8_t> audio_level_dbov)>;
+                            std::optional<uint8_t> audio_level_dbov)>;
   ChannelSendFrameTransformerDelegate(
       SendFrameCallback send_frame_callback,
       rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,
@@ -62,7 +62,7 @@
                  int64_t absolute_capture_timestamp_ms,
                  uint32_t ssrc,
                  const std::string& codec_mime_type,
-                 absl::optional<uint8_t> audio_level_dbov);
+                 std::optional<uint8_t> audio_level_dbov);
 
   // Implements TransformedFrameCallback. Can be called on any thread.
   void OnTransformedFrame(
diff --git a/audio/channel_send_frame_transformer_delegate_unittest.cc b/audio/channel_send_frame_transformer_delegate_unittest.cc
index 0ed8677..a4ee9ff 100644
--- a/audio/channel_send_frame_transformer_delegate_unittest.cc
+++ b/audio/channel_send_frame_transformer_delegate_unittest.cc
@@ -12,11 +12,11 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/memory/memory.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/frame_transformer_interface.h"
 #include "api/make_ref_counted.h"
@@ -54,14 +54,14 @@
                rtc::ArrayView<const uint8_t> payload,
                int64_t absolute_capture_timestamp_ms,
                rtc::ArrayView<const uint32_t> csrcs,
-               absl::optional<uint8_t> audio_level_dbov));
+               std::optional<uint8_t> audio_level_dbov));
 
   ChannelSendFrameTransformerDelegate::SendFrameCallback callback() {
     return [this](AudioFrameType frameType, uint8_t payloadType,
                   uint32_t rtp_timestamp, rtc::ArrayView<const uint8_t> payload,
                   int64_t absolute_capture_timestamp_ms,
                   rtc::ArrayView<const uint32_t> csrcs,
-                  absl::optional<uint8_t> audio_level_dbov) {
+                  std::optional<uint8_t> audio_level_dbov) {
       return SendFrame(frameType, payloadType, rtp_timestamp, payload,
                        absolute_capture_timestamp_ms, csrcs, audio_level_dbov);
     };
@@ -70,7 +70,7 @@
 
 std::unique_ptr<TransformableAudioFrameInterface> CreateMockReceiverFrame(
     const std::vector<uint32_t>& csrcs,
-    absl::optional<uint8_t> audio_level_dbov) {
+    std::optional<uint8_t> audio_level_dbov) {
   std::unique_ptr<MockTransformableAudioFrame> mock_frame =
       std::make_unique<NiceMock<MockTransformableAudioFrame>>();
   rtc::ArrayView<const uint8_t> payload(mock_data);
@@ -190,12 +190,12 @@
   ON_CALL(*mock_frame_transformer, Transform)
       .WillByDefault([&](std::unique_ptr<TransformableFrameInterface> frame) {
         callback->OnTransformedFrame(CreateMockReceiverFrame(
-            csrcs, absl::optional<uint8_t>(audio_level_dbov)));
+            csrcs, std::optional<uint8_t>(audio_level_dbov)));
       });
   delegate->Transform(AudioFrameType::kEmptyFrame, 0, 0, mock_data,
                       sizeof(mock_data), 0,
                       /*ssrc=*/0, /*mimeType=*/"audio/opus",
-                      /*audio_level_dbov=*/absl::nullopt);
+                      /*audio_level_dbov=*/std::nullopt);
   channel_queue.WaitForPreviouslyPostedTasks();
 }
 
@@ -236,7 +236,7 @@
   const uint8_t data[] = {1, 2, 3, 4};
   delegate->Transform(AudioFrameType::kEmptyFrame, 0, 0, data, sizeof(data), 0,
                       /*ssrc=*/0, /*mimeType=*/"audio/opus",
-                      /*audio_level_dbov=*/absl::nullopt);
+                      /*audio_level_dbov=*/std::nullopt);
 }
 
 TEST(ChannelSendFrameTransformerDelegateTest,
@@ -258,7 +258,7 @@
 TEST(ChannelSendFrameTransformerDelegateTest, CloningReceiverFrameWithCsrcs) {
   std::unique_ptr<TransformableAudioFrameInterface> frame =
       CreateMockReceiverFrame(/*csrcs=*/{123, 234, 345},
-                              absl::optional<uint8_t>(72));
+                              std::optional<uint8_t>(72));
   std::unique_ptr<TransformableAudioFrameInterface> cloned_frame =
       CloneSenderAudioFrame(frame.get());
 
diff --git a/audio/channel_send_unittest.cc b/audio/channel_send_unittest.cc
index 3535a99..ac82fbd 100644
--- a/audio/channel_send_unittest.cc
+++ b/audio/channel_send_unittest.cc
@@ -164,7 +164,7 @@
       .WillOnce(SaveArg<0>(&callback));
   EXPECT_CALL(*mock_frame_transformer, UnregisterTransformedFrameCallback);
 
-  absl::optional<uint32_t> sent_timestamp;
+  std::optional<uint32_t> sent_timestamp;
   auto send_rtp = [&](rtc::ArrayView<const uint8_t> data,
                       const PacketOptions& options) {
     RtpPacketReceived packet;
@@ -311,7 +311,7 @@
 TEST_F(ChannelSendTest, NoUsedRateInitially) {
   channel_->StartSend();
   auto used_rate = channel_->GetUsedRate();
-  EXPECT_EQ(used_rate, absl::nullopt);
+  EXPECT_EQ(used_rate, std::nullopt);
 }
 
 // Ensure that GetUsedRate returns value with one coded frame.
diff --git a/audio/mock_voe_channel_proxy.h b/audio/mock_voe_channel_proxy.h
index 607070a..1a62f02 100644
--- a/audio/mock_voe_channel_proxy.h
+++ b/audio/mock_voe_channel_proxy.h
@@ -75,18 +75,18 @@
               SetEstimatedPlayoutNtpTimestampMs,
               (int64_t ntp_timestamp_ms, int64_t time_ms),
               (override));
-  MOCK_METHOD(absl::optional<int64_t>,
+  MOCK_METHOD(std::optional<int64_t>,
               GetCurrentEstimatedPlayoutNtpTimestampMs,
               (int64_t now_ms),
               (const, override));
-  MOCK_METHOD(absl::optional<Syncable::Info>,
+  MOCK_METHOD(std::optional<Syncable::Info>,
               GetSyncInfo,
               (),
               (const, override));
   MOCK_METHOD(bool, SetMinimumPlayoutDelay, (int delay_ms), (override));
   MOCK_METHOD(bool, SetBaseMinimumPlayoutDelayMs, (int delay_ms), (override));
   MOCK_METHOD(int, GetBaseMinimumPlayoutDelayMs, (), (const, override));
-  MOCK_METHOD((absl::optional<std::pair<int, SdpAudioFormat>>),
+  MOCK_METHOD((std::optional<std::pair<int, SdpAudioFormat>>),
               GetReceiveCodec,
               (),
               (const, override));
@@ -182,7 +182,7 @@
       SetEncoderToPacketizerFrameTransformer,
       (rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer),
       (override));
-  MOCK_METHOD(absl::optional<DataRate>, GetUsedRate, (), (const, override));
+  MOCK_METHOD(std::optional<DataRate>, GetUsedRate, (), (const, override));
   MOCK_METHOD(void,
               RegisterPacketOverhead,
               (int packet_byte_overhead),
diff --git a/audio/voip/BUILD.gn b/audio/voip/BUILD.gn
index a49e336..42fc665 100644
--- a/audio/voip/BUILD.gn
+++ b/audio/voip/BUILD.gn
@@ -75,7 +75,6 @@
     "../../rtc_base:timeutils",
     "../../rtc_base/synchronization:mutex",
     "../utility:audio_frame_operations",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/audio/voip/audio_channel.h b/audio/voip/audio_channel.h
index d2452fd..5489109 100644
--- a/audio/voip/audio_channel.h
+++ b/audio/voip/audio_channel.h
@@ -59,7 +59,7 @@
                   std::unique_ptr<AudioEncoder> encoder) {
     egress_->SetEncoder(payload_type, encoder_format, std::move(encoder));
   }
-  absl::optional<SdpAudioFormat> GetEncoderFormat() const {
+  std::optional<SdpAudioFormat> GetEncoderFormat() const {
     return egress_->GetEncoderFormat();
   }
   void RegisterTelephoneEventType(int rtp_payload_type, int sample_rate_hz) {
diff --git a/audio/voip/audio_egress.h b/audio/voip/audio_egress.h
index aaaea08..7955fed 100644
--- a/audio/voip/audio_egress.h
+++ b/audio/voip/audio_egress.h
@@ -74,7 +74,7 @@
 
   // Retrieve current encoder format info. This returns encoder format set
   // by SetEncoder() and if encoder is not set, this will return nullopt.
-  absl::optional<SdpAudioFormat> GetEncoderFormat() const {
+  std::optional<SdpAudioFormat> GetEncoderFormat() const {
     MutexLock lock(&lock_);
     return encoder_format_;
   }
@@ -119,7 +119,7 @@
   mutable Mutex lock_;
 
   // Current encoder format selected by caller.
-  absl::optional<SdpAudioFormat> encoder_format_ RTC_GUARDED_BY(lock_);
+  std::optional<SdpAudioFormat> encoder_format_ RTC_GUARDED_BY(lock_);
 
   // Synchronization is handled internally by RtpRtcp.
   RtpRtcpInterface* const rtp_rtcp_;
diff --git a/audio/voip/audio_ingress.cc b/audio/voip/audio_ingress.cc
index 9809c6b..50332c1 100644
--- a/audio/voip/audio_ingress.cc
+++ b/audio/voip/audio_ingress.cc
@@ -103,7 +103,7 @@
     }
     // For clock rate, default to the playout sampling rate if we haven't
     // received any packets yet.
-    absl::optional<std::pair<int, SdpAudioFormat>> decoder =
+    std::optional<std::pair<int, SdpAudioFormat>> decoder =
         acm_receiver_.LastDecoder();
     int clock_rate = decoder ? decoder->second.clockrate_hz
                              : acm_receiver_.last_output_sample_rate_hz();
@@ -215,13 +215,13 @@
   // Deliver RTCP packet to RTP/RTCP module for parsing and processing.
   rtp_rtcp_->IncomingRtcpPacket(rtcp_packet);
 
-  absl::optional<TimeDelta> rtt = rtp_rtcp_->LastRtt();
+  std::optional<TimeDelta> rtt = rtp_rtcp_->LastRtt();
   if (!rtt.has_value()) {
     // Waiting for valid RTT.
     return;
   }
 
-  absl::optional<RtpRtcpInterface::SenderReportStats> last_sr =
+  std::optional<RtpRtcpInterface::SenderReportStats> last_sr =
       rtp_rtcp_->GetSenderReportStats();
   if (!last_sr.has_value()) {
     // Waiting for RTCP.
@@ -240,7 +240,7 @@
 
   // Get clockrate for current decoder ahead of jitter calculation.
   uint32_t clockrate_hz = 0;
-  absl::optional<std::pair<int, SdpAudioFormat>> decoder =
+  std::optional<std::pair<int, SdpAudioFormat>> decoder =
       acm_receiver_.LastDecoder();
   if (decoder) {
     clockrate_hz = decoder->second.clockrate_hz;
diff --git a/audio/voip/audio_ingress.h b/audio/voip/audio_ingress.h
index daa21cb..9651871 100644
--- a/audio/voip/audio_ingress.h
+++ b/audio/voip/audio_ingress.h
@@ -15,9 +15,9 @@
 #include <atomic>
 #include <map>
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/audio_mixer.h"
 #include "api/environment/environment.h"
diff --git a/audio/voip/test/audio_channel_unittest.cc b/audio/voip/test/audio_channel_unittest.cc
index 0d4c05f..90407a7 100644
--- a/audio/voip/test/audio_channel_unittest.cc
+++ b/audio/voip/test/audio_channel_unittest.cc
@@ -163,7 +163,7 @@
   audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
   audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
 
-  absl::optional<IngressStatistics> ingress_stats =
+  std::optional<IngressStatistics> ingress_stats =
       audio_channel_->GetIngressStatistics();
   EXPECT_TRUE(ingress_stats);
   EXPECT_EQ(ingress_stats->neteq_stats.total_samples_received, 160ULL);
@@ -254,7 +254,7 @@
   // in loop_rtcp above.
   audio_channel_->SendRTCPReportForTesting(kRtcpSr);
 
-  absl::optional<ChannelStatistics> channel_stats =
+  std::optional<ChannelStatistics> channel_stats =
       audio_channel_->GetChannelStatistics();
   EXPECT_TRUE(channel_stats);
 
@@ -336,7 +336,7 @@
   send_recv_rtcp(audio_channel_, ac_2);
   send_recv_rtcp(ac_2, audio_channel_);
 
-  absl::optional<ChannelStatistics> channel_stats =
+  std::optional<ChannelStatistics> channel_stats =
       audio_channel_->GetChannelStatistics();
   ASSERT_TRUE(channel_stats);
   EXPECT_EQ(channel_stats->remote_ssrc, kAc2Ssrc);
diff --git a/audio/voip/test/audio_egress_unittest.cc b/audio/voip/test/audio_egress_unittest.cc
index a5b098e..46b351b 100644
--- a/audio/voip/test/audio_egress_unittest.cc
+++ b/audio/voip/test/audio_egress_unittest.cc
@@ -226,7 +226,7 @@
 }
 
 TEST_F(AudioEgressTest, ChangeEncoderFromPcmuToOpus) {
-  absl::optional<SdpAudioFormat> pcmu = egress_->GetEncoderFormat();
+  std::optional<SdpAudioFormat> pcmu = egress_->GetEncoderFormat();
   EXPECT_TRUE(pcmu);
   EXPECT_EQ(pcmu->clockrate_hz, kPcmuFormat.clockrate_hz);
   EXPECT_EQ(pcmu->num_channels, kPcmuFormat.num_channels);
@@ -238,7 +238,7 @@
                       encoder_factory_->Create(env_, kOpusFormat,
                                                {.payload_type = kOpusPayload}));
 
-  absl::optional<SdpAudioFormat> opus = egress_->GetEncoderFormat();
+  std::optional<SdpAudioFormat> opus = egress_->GetEncoderFormat();
   EXPECT_TRUE(opus);
   EXPECT_EQ(opus->clockrate_hz, kOpusFormat.clockrate_hz);
   EXPECT_EQ(opus->num_channels, kOpusFormat.num_channels);
diff --git a/audio/voip/voip_core.cc b/audio/voip/voip_core.cc
index e4aec20..885e9af 100644
--- a/audio/voip/voip_core.cc
+++ b/audio/voip/voip_core.cc
@@ -122,7 +122,7 @@
 }
 
 ChannelId VoipCore::CreateChannel(Transport* transport,
-                                  absl::optional<uint32_t> local_ssrc) {
+                                  std::optional<uint32_t> local_ssrc) {
   ChannelId channel_id;
 
   // Set local ssrc to random if not set by caller.
diff --git a/audio/voip/voip_core.h b/audio/voip/voip_core.h
index 3ee1e8c..5d88ba0 100644
--- a/audio/voip/voip_core.h
+++ b/audio/voip/voip_core.h
@@ -69,7 +69,7 @@
 
   // Implements VoipBase interfaces.
   ChannelId CreateChannel(Transport* transport,
-                          absl::optional<uint32_t> local_ssrc) override;
+                          std::optional<uint32_t> local_ssrc) override;
   VoipResult ReleaseChannel(ChannelId channel_id) override;
   VoipResult StartSend(ChannelId channel_id) override;
   VoipResult StopSend(ChannelId channel_id) override;
diff --git a/call/BUILD.gn b/call/BUILD.gn
index cc81b38..fd387d9 100644
--- a/call/BUILD.gn
+++ b/call/BUILD.gn
@@ -78,7 +78,6 @@
     "../rtc_base/network:sent_packet",
     "//third_party/abseil-cpp/absl/functional:any_invocable",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -126,7 +125,6 @@
     "../rtc_base:stringutils",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -220,7 +218,6 @@
     "//third_party/abseil-cpp/absl/container:inlined_vector",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -232,7 +229,6 @@
   ]
   deps = [
     ":rtp_interfaces",
-    "//third_party/abseil-cpp/absl/types:optional",
 
     # For api/bitrate_constraints.h
     "../api:libjingle_peerconnection_api",
@@ -334,7 +330,6 @@
     "adaptation:resource_adaptation",
     "//third_party/abseil-cpp/absl/functional:bind_front",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -381,7 +376,6 @@
     "../rtc_base:checks",
     "../rtc_base:stringutils",
     "../video/config:encoder_config",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -512,7 +506,6 @@
         "//third_party/abseil-cpp/absl/container:inlined_vector",
         "//third_party/abseil-cpp/absl/functional:any_invocable",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
         "//third_party/abseil-cpp/absl/types:variant",
       ]
     }
diff --git a/call/adaptation/BUILD.gn b/call/adaptation/BUILD.gn
index 5dde21d..4743e94 100644
--- a/call/adaptation/BUILD.gn
+++ b/call/adaptation/BUILD.gn
@@ -58,7 +58,6 @@
     "../../video/config:encoder_config",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -95,7 +94,6 @@
       "../../test:scoped_key_value_config",
       "../../test:test_support",
       "../../video/config:encoder_config",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -125,7 +123,6 @@
       "../../video:video_stream_encoder_interface",
       "../../video/config:encoder_config",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
diff --git a/call/adaptation/encoder_settings.cc b/call/adaptation/encoder_settings.cc
index c894e83..7c00dce 100644
--- a/call/adaptation/encoder_settings.cc
+++ b/call/adaptation/encoder_settings.cc
@@ -46,7 +46,7 @@
 }
 
 VideoCodecType GetVideoCodecTypeOrGeneric(
-    const absl::optional<EncoderSettings>& settings) {
+    const std::optional<EncoderSettings>& settings) {
   return settings.has_value() ? settings->encoder_config().codec_type
                               : kVideoCodecGeneric;
 }
diff --git a/call/adaptation/encoder_settings.h b/call/adaptation/encoder_settings.h
index 30ce0a0..2d5e9bc 100644
--- a/call/adaptation/encoder_settings.h
+++ b/call/adaptation/encoder_settings.h
@@ -11,7 +11,8 @@
 #ifndef CALL_ADAPTATION_ENCODER_SETTINGS_H_
 #define CALL_ADAPTATION_ENCODER_SETTINGS_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/video_codecs/video_codec.h"
 #include "api/video_codecs/video_encoder.h"
 #include "video/config/video_encoder_config.h"
@@ -41,7 +42,7 @@
 };
 
 VideoCodecType GetVideoCodecTypeOrGeneric(
-    const absl::optional<EncoderSettings>& settings);
+    const std::optional<EncoderSettings>& settings);
 
 }  // namespace webrtc
 
diff --git a/call/adaptation/resource_adaptation_processor.h b/call/adaptation/resource_adaptation_processor.h
index c2d9c3e..a4cc1ca 100644
--- a/call/adaptation/resource_adaptation_processor.h
+++ b/call/adaptation/resource_adaptation_processor.h
@@ -13,12 +13,12 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/adaptation/resource.h"
 #include "api/rtp_parameters.h"
 #include "api/scoped_refptr.h"
diff --git a/call/adaptation/resource_adaptation_processor_interface.h b/call/adaptation/resource_adaptation_processor_interface.h
index 4729488..b5c417a 100644
--- a/call/adaptation/resource_adaptation_processor_interface.h
+++ b/call/adaptation/resource_adaptation_processor_interface.h
@@ -12,9 +12,9 @@
 #define CALL_ADAPTATION_RESOURCE_ADAPTATION_PROCESSOR_INTERFACE_H_
 
 #include <map>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/adaptation/resource.h"
 #include "api/rtp_parameters.h"
 #include "api/scoped_refptr.h"
diff --git a/call/adaptation/test/fake_resource.h b/call/adaptation/test/fake_resource.h
index 1119a96..0e02b0c 100644
--- a/call/adaptation/test/fake_resource.h
+++ b/call/adaptation/test/fake_resource.h
@@ -11,11 +11,11 @@
 #ifndef CALL_ADAPTATION_TEST_FAKE_RESOURCE_H_
 #define CALL_ADAPTATION_TEST_FAKE_RESOURCE_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/adaptation/resource.h"
 #include "api/scoped_refptr.h"
 
diff --git a/call/adaptation/video_source_restrictions.cc b/call/adaptation/video_source_restrictions.cc
index 719bc53..8ca40d4 100644
--- a/call/adaptation/video_source_restrictions.cc
+++ b/call/adaptation/video_source_restrictions.cc
@@ -19,14 +19,14 @@
 namespace webrtc {
 
 VideoSourceRestrictions::VideoSourceRestrictions()
-    : max_pixels_per_frame_(absl::nullopt),
-      target_pixels_per_frame_(absl::nullopt),
-      max_frame_rate_(absl::nullopt) {}
+    : max_pixels_per_frame_(std::nullopt),
+      target_pixels_per_frame_(std::nullopt),
+      max_frame_rate_(std::nullopt) {}
 
 VideoSourceRestrictions::VideoSourceRestrictions(
-    absl::optional<size_t> max_pixels_per_frame,
-    absl::optional<size_t> target_pixels_per_frame,
-    absl::optional<double> max_frame_rate)
+    std::optional<size_t> max_pixels_per_frame,
+    std::optional<size_t> target_pixels_per_frame,
+    std::optional<double> max_frame_rate)
     : max_pixels_per_frame_(std::move(max_pixels_per_frame)),
       target_pixels_per_frame_(std::move(target_pixels_per_frame)),
       max_frame_rate_(std::move(max_frame_rate)) {
@@ -51,32 +51,32 @@
   return ss.Release();
 }
 
-const absl::optional<size_t>& VideoSourceRestrictions::max_pixels_per_frame()
+const std::optional<size_t>& VideoSourceRestrictions::max_pixels_per_frame()
     const {
   return max_pixels_per_frame_;
 }
 
-const absl::optional<size_t>& VideoSourceRestrictions::target_pixels_per_frame()
+const std::optional<size_t>& VideoSourceRestrictions::target_pixels_per_frame()
     const {
   return target_pixels_per_frame_;
 }
 
-const absl::optional<double>& VideoSourceRestrictions::max_frame_rate() const {
+const std::optional<double>& VideoSourceRestrictions::max_frame_rate() const {
   return max_frame_rate_;
 }
 
 void VideoSourceRestrictions::set_max_pixels_per_frame(
-    absl::optional<size_t> max_pixels_per_frame) {
+    std::optional<size_t> max_pixels_per_frame) {
   max_pixels_per_frame_ = std::move(max_pixels_per_frame);
 }
 
 void VideoSourceRestrictions::set_target_pixels_per_frame(
-    absl::optional<size_t> target_pixels_per_frame) {
+    std::optional<size_t> target_pixels_per_frame) {
   target_pixels_per_frame_ = std::move(target_pixels_per_frame);
 }
 
 void VideoSourceRestrictions::set_max_frame_rate(
-    absl::optional<double> max_frame_rate) {
+    std::optional<double> max_frame_rate) {
   max_frame_rate_ = std::move(max_frame_rate);
 }
 
diff --git a/call/adaptation/video_source_restrictions.h b/call/adaptation/video_source_restrictions.h
index be8520a..6e1b6c6 100644
--- a/call/adaptation/video_source_restrictions.h
+++ b/call/adaptation/video_source_restrictions.h
@@ -11,11 +11,10 @@
 #ifndef CALL_ADAPTATION_VIDEO_SOURCE_RESTRICTIONS_H_
 #define CALL_ADAPTATION_VIDEO_SOURCE_RESTRICTIONS_H_
 
+#include <optional>
 #include <string>
 #include <utility>
 
-#include "absl/types/optional.h"
-
 namespace webrtc {
 
 // Describes optional restrictions to the resolution and frame rate of a video
@@ -26,9 +25,9 @@
   VideoSourceRestrictions();
   // All values must be positive or nullopt.
   // TODO(hbos): Support expressing "disable this stream"?
-  VideoSourceRestrictions(absl::optional<size_t> max_pixels_per_frame,
-                          absl::optional<size_t> target_pixels_per_frame,
-                          absl::optional<double> max_frame_rate);
+  VideoSourceRestrictions(std::optional<size_t> max_pixels_per_frame,
+                          std::optional<size_t> target_pixels_per_frame,
+                          std::optional<double> max_frame_rate);
 
   bool operator==(const VideoSourceRestrictions& rhs) const {
     return max_pixels_per_frame_ == rhs.max_pixels_per_frame_ &&
@@ -43,7 +42,7 @@
 
   // The source must produce a resolution less than or equal to
   // max_pixels_per_frame().
-  const absl::optional<size_t>& max_pixels_per_frame() const;
+  const std::optional<size_t>& max_pixels_per_frame() const;
   // The source should produce a resolution as close to the
   // target_pixels_per_frame() as possible, provided this does not exceed
   // max_pixels_per_frame().
@@ -52,13 +51,13 @@
   // the camera in the smallest resolution that is greater than or equal to the
   // target and scale it down to the target if it is greater. Is this an
   // accurate description of what this does today, or do we do something else?
-  const absl::optional<size_t>& target_pixels_per_frame() const;
-  const absl::optional<double>& max_frame_rate() const;
+  const std::optional<size_t>& target_pixels_per_frame() const;
+  const std::optional<double>& max_frame_rate() const;
 
-  void set_max_pixels_per_frame(absl::optional<size_t> max_pixels_per_frame);
+  void set_max_pixels_per_frame(std::optional<size_t> max_pixels_per_frame);
   void set_target_pixels_per_frame(
-      absl::optional<size_t> target_pixels_per_frame);
-  void set_max_frame_rate(absl::optional<double> max_frame_rate);
+      std::optional<size_t> target_pixels_per_frame);
+  void set_max_frame_rate(std::optional<double> max_frame_rate);
 
   // Update `this` with min(`this`, `other`).
   void UpdateMin(const VideoSourceRestrictions& other);
@@ -66,9 +65,9 @@
  private:
   // These map to rtc::VideoSinkWants's `max_pixel_count` and
   // `target_pixel_count`.
-  absl::optional<size_t> max_pixels_per_frame_;
-  absl::optional<size_t> target_pixels_per_frame_;
-  absl::optional<double> max_frame_rate_;
+  std::optional<size_t> max_pixels_per_frame_;
+  std::optional<size_t> target_pixels_per_frame_;
+  std::optional<double> max_frame_rate_;
 };
 
 bool DidRestrictionsIncrease(VideoSourceRestrictions before,
diff --git a/call/adaptation/video_source_restrictions_unittest.cc b/call/adaptation/video_source_restrictions_unittest.cc
index 8c1ae4c..1205332 100644
--- a/call/adaptation/video_source_restrictions_unittest.cc
+++ b/call/adaptation/video_source_restrictions_unittest.cc
@@ -19,19 +19,19 @@
 const size_t kHdPixels = 1280 * 720;
 
 const VideoSourceRestrictions kUnlimited;
-const VideoSourceRestrictions k15fps(absl::nullopt, absl::nullopt, 15.0);
-const VideoSourceRestrictions kHd(kHdPixels, kHdPixels, absl::nullopt);
+const VideoSourceRestrictions k15fps(std::nullopt, std::nullopt, 15.0);
+const VideoSourceRestrictions kHd(kHdPixels, kHdPixels, std::nullopt);
 const VideoSourceRestrictions kHd15fps(kHdPixels, kHdPixels, 15.0);
 const VideoSourceRestrictions kVga7fps(kHdPixels / 2, kHdPixels / 2, 7.0);
 
 VideoSourceRestrictions RestrictionsFromMaxPixelsPerFrame(
     size_t max_pixels_per_frame) {
-  return VideoSourceRestrictions(max_pixels_per_frame, absl::nullopt,
-                                 absl::nullopt);
+  return VideoSourceRestrictions(max_pixels_per_frame, std::nullopt,
+                                 std::nullopt);
 }
 
 VideoSourceRestrictions RestrictionsFromMaxFrameRate(double max_frame_rate) {
-  return VideoSourceRestrictions(absl::nullopt, absl::nullopt, max_frame_rate);
+  return VideoSourceRestrictions(std::nullopt, std::nullopt, max_frame_rate);
 }
 
 }  // namespace
diff --git a/call/adaptation/video_stream_adapter.cc b/call/adaptation/video_stream_adapter.cc
index 5a970fb..eb949c9 100644
--- a/call/adaptation/video_stream_adapter.cc
+++ b/call/adaptation/video_stream_adapter.cc
@@ -12,9 +12,9 @@
 
 #include <algorithm>
 #include <limits>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/sequence_checker.h"
 #include "api/video/video_adaptation_counters.h"
@@ -38,7 +38,7 @@
   RTC_DCHECK(fps != std::numeric_limits<int>::max());
   return (fps * 2) / 3;
 }
-// TODO(hbos): Use absl::optional<> instead?
+// TODO(hbos): Use std::optional<> instead?
 int GetHigherFrameRateThan(int fps) {
   return fps != std::numeric_limits<int>::max()
              ? (fps * 3) / 2
@@ -118,16 +118,16 @@
     case DegradationPreference::BALANCED:
       break;
     case DegradationPreference::MAINTAIN_FRAMERATE:
-      source_restrictions.set_max_frame_rate(absl::nullopt);
+      source_restrictions.set_max_frame_rate(std::nullopt);
       break;
     case DegradationPreference::MAINTAIN_RESOLUTION:
-      source_restrictions.set_max_pixels_per_frame(absl::nullopt);
-      source_restrictions.set_target_pixels_per_frame(absl::nullopt);
+      source_restrictions.set_max_pixels_per_frame(std::nullopt);
+      source_restrictions.set_target_pixels_per_frame(std::nullopt);
       break;
     case DegradationPreference::DISABLED:
-      source_restrictions.set_max_pixels_per_frame(absl::nullopt);
-      source_restrictions.set_target_pixels_per_frame(absl::nullopt);
-      source_restrictions.set_max_frame_rate(absl::nullopt);
+      source_restrictions.set_max_pixels_per_frame(std::nullopt);
+      source_restrictions.set_target_pixels_per_frame(std::nullopt);
+      source_restrictions.set_max_frame_rate(std::nullopt);
   }
   return source_restrictions;
 }
@@ -145,7 +145,7 @@
   return (pixel_count * 3) / 5;
 }
 
-// TODO(hbos): Use absl::optional<> instead?
+// TODO(hbos): Use std::optional<> instead?
 int GetHigherResolutionThan(int pixel_count) {
   return pixel_count != std::numeric_limits<int>::max()
              ? (pixel_count * 5) / 3
@@ -211,7 +211,7 @@
       balanced_settings_(field_trials),
       adaptation_validation_id_(0),
       degradation_preference_(DegradationPreference::DISABLED),
-      awaiting_frame_size_change_(absl::nullopt) {
+      awaiting_frame_size_change_(std::nullopt) {
   sequence_checker_.Detach();
   RTC_DCHECK(input_state_provider_);
   RTC_DCHECK(encoder_stats_observer_);
@@ -240,7 +240,7 @@
   ++adaptation_validation_id_;
   current_restrictions_ = {VideoSourceRestrictions(),
                            VideoAdaptationCounters()};
-  awaiting_frame_size_change_ = absl::nullopt;
+  awaiting_frame_size_change_ = std::nullopt;
   BroadcastVideoRestrictionsUpdate(input_state_provider_->InputState(),
                                    nullptr);
 }
@@ -420,7 +420,7 @@
   RTC_DCHECK_EQ(degradation_preference_, DegradationPreference::BALANCED);
   int frame_size_pixels = input_state.single_active_stream_pixels().value_or(
       input_state.frame_size_pixels().value());
-  absl::optional<int> min_fps_diff =
+  std::optional<int> min_fps_diff =
       balanced_settings_.MinFpsDiff(frame_size_pixels);
   if (current_restrictions_.counters.fps_adaptations <
           restrictions.counters.fps_adaptations &&
@@ -492,9 +492,9 @@
   RTC_LOG(LS_INFO) << "Scaling down resolution, max pixels: " << target_pixels;
   new_restrictions.restrictions.set_max_pixels_per_frame(
       target_pixels != std::numeric_limits<int>::max()
-          ? absl::optional<size_t>(target_pixels)
-          : absl::nullopt);
-  new_restrictions.restrictions.set_target_pixels_per_frame(absl::nullopt);
+          ? std::optional<size_t>(target_pixels)
+          : std::nullopt);
+  new_restrictions.restrictions.set_target_pixels_per_frame(std::nullopt);
   ++new_restrictions.counters.resolution_adaptations;
   return new_restrictions;
 }
@@ -523,8 +523,8 @@
   RTC_LOG(LS_INFO) << "Scaling down framerate: " << max_frame_rate;
   new_restrictions.restrictions.set_max_frame_rate(
       max_frame_rate != std::numeric_limits<int>::max()
-          ? absl::optional<double>(max_frame_rate)
-          : absl::nullopt);
+          ? std::optional<double>(max_frame_rate)
+          : std::nullopt);
   ++new_restrictions.counters.fps_adaptations;
   return new_restrictions;
 }
@@ -548,12 +548,12 @@
                    << max_pixels_wanted;
   new_restrictions.restrictions.set_max_pixels_per_frame(
       max_pixels_wanted != std::numeric_limits<int>::max()
-          ? absl::optional<size_t>(max_pixels_wanted)
-          : absl::nullopt);
+          ? std::optional<size_t>(max_pixels_wanted)
+          : std::nullopt);
   new_restrictions.restrictions.set_target_pixels_per_frame(
       max_pixels_wanted != std::numeric_limits<int>::max()
-          ? absl::optional<size_t>(target_pixels)
-          : absl::nullopt);
+          ? std::optional<size_t>(target_pixels)
+          : std::nullopt);
   --new_restrictions.counters.resolution_adaptations;
   RTC_DCHECK_GE(new_restrictions.counters.resolution_adaptations, 0);
   return new_restrictions;
@@ -601,8 +601,8 @@
   RestrictionsWithCounters new_restrictions = current_restrictions;
   new_restrictions.restrictions.set_max_frame_rate(
       max_frame_rate != std::numeric_limits<int>::max()
-          ? absl::optional<double>(max_frame_rate)
-          : absl::nullopt);
+          ? std::optional<double>(max_frame_rate)
+          : std::nullopt);
   --new_restrictions.counters.fps_adaptations;
   RTC_DCHECK_GE(new_restrictions.counters.fps_adaptations, 0);
   return new_restrictions;
@@ -669,7 +669,7 @@
     awaiting_frame_size_change_.emplace(
         false, adaptation.input_state().frame_size_pixels().value());
   } else {
-    awaiting_frame_size_change_ = absl::nullopt;
+    awaiting_frame_size_change_ = std::nullopt;
   }
   current_restrictions_ = {adaptation.restrictions(), adaptation.counters()};
   BroadcastVideoRestrictionsUpdate(adaptation.input_state(), resource);
@@ -717,10 +717,10 @@
     : pixels_increased(pixels_increased),
       frame_size_pixels(frame_size_pixels) {}
 
-absl::optional<uint32_t> VideoStreamAdapter::GetSingleActiveLayerPixels(
+std::optional<uint32_t> VideoStreamAdapter::GetSingleActiveLayerPixels(
     const VideoCodec& codec) {
   int num_active = 0;
-  absl::optional<uint32_t> pixels;
+  std::optional<uint32_t> pixels;
   if (codec.codecType == VideoCodecType::kVideoCodecAV1 &&
       codec.GetScalabilityMode().has_value()) {
     for (int i = 0;
@@ -747,7 +747,7 @@
       }
     }
   }
-  return (num_active > 1) ? absl::nullopt : pixels;
+  return (num_active > 1) ? std::nullopt : pixels;
 }
 
 }  // namespace webrtc
diff --git a/call/adaptation/video_stream_adapter.h b/call/adaptation/video_stream_adapter.h
index 5c17417..fcf0a6d 100644
--- a/call/adaptation/video_stream_adapter.h
+++ b/call/adaptation/video_stream_adapter.h
@@ -12,10 +12,10 @@
 #define CALL_ADAPTATION_VIDEO_STREAM_ADAPTER_H_
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/adaptation/resource.h"
 #include "api/field_trials_view.h"
@@ -165,7 +165,7 @@
     VideoAdaptationCounters counters;
   };
 
-  static absl::optional<uint32_t> GetSingleActiveLayerPixels(
+  static std::optional<uint32_t> GetSingleActiveLayerPixels(
       const VideoCodec& codec);
 
  private:
@@ -249,7 +249,7 @@
     const bool pixels_increased;
     const int frame_size_pixels;
   };
-  absl::optional<AwaitingFrameSizeChange> awaiting_frame_size_change_
+  std::optional<AwaitingFrameSizeChange> awaiting_frame_size_change_
       RTC_GUARDED_BY(&sequence_checker_);
   // The previous restrictions value. Starts as unrestricted.
   VideoSourceRestrictions last_video_source_restrictions_
diff --git a/call/adaptation/video_stream_adapter_unittest.cc b/call/adaptation/video_stream_adapter_unittest.cc
index d4bc650..162adf9 100644
--- a/call/adaptation/video_stream_adapter_unittest.cc
+++ b/call/adaptation/video_stream_adapter_unittest.cc
@@ -10,10 +10,10 @@
 
 #include "call/adaptation/video_stream_adapter.h"
 
+#include <optional>
 #include <string>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
 #include "api/video/video_adaptation_reason.h"
 #include "api/video_codecs/video_codec.h"
@@ -180,9 +180,9 @@
   adapter_.ApplyAdaptation(adaptation, nullptr);
   EXPECT_EQ(static_cast<size_t>((kInputPixels * 3) / 5),
             adapter_.source_restrictions().max_pixels_per_frame());
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             adapter_.source_restrictions().target_pixels_per_frame());
-  EXPECT_EQ(absl::nullopt, adapter_.source_restrictions().max_frame_rate());
+  EXPECT_EQ(std::nullopt, adapter_.source_restrictions().max_frame_rate());
   EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
 }
 
@@ -219,7 +219,7 @@
             adapter_.source_restrictions().max_pixels_per_frame());
   EXPECT_EQ(static_cast<size_t>(target),
             adapter_.source_restrictions().target_pixels_per_frame());
-  EXPECT_EQ(absl::nullopt, adapter_.source_restrictions().max_frame_rate());
+  EXPECT_EQ(std::nullopt, adapter_.source_restrictions().max_frame_rate());
   EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
 }
 
@@ -247,9 +247,9 @@
   Adaptation adaptation = adapter_.GetAdaptationDown();
   EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
   adapter_.ApplyAdaptation(adaptation, nullptr);
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             adapter_.source_restrictions().max_pixels_per_frame());
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             adapter_.source_restrictions().target_pixels_per_frame());
   EXPECT_EQ(static_cast<double>((kInputFps * 2) / 3),
             adapter_.source_restrictions().max_frame_rate());
@@ -286,9 +286,9 @@
   Adaptation adaptation = adapter_.GetAdaptationUp();
   EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
   fake_stream.ApplyAdaptation(adaptation);
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             adapter_.source_restrictions().max_pixels_per_frame());
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             adapter_.source_restrictions().target_pixels_per_frame());
   EXPECT_EQ(static_cast<double>((input_fps * 3) / 2),
             adapter_.source_restrictions().max_frame_rate());
@@ -321,9 +321,9 @@
   Adaptation adaptation = adapter_.GetAdaptationDown();
   EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
   adapter_.ApplyAdaptation(adaptation, nullptr);
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             adapter_.source_restrictions().max_pixels_per_frame());
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             adapter_.source_restrictions().target_pixels_per_frame());
   EXPECT_EQ(static_cast<double>(kBalancedMediumFrameRateFps),
             adapter_.source_restrictions().max_frame_rate());
@@ -349,9 +349,9 @@
     EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
     fake_stream.ApplyAdaptation(adaptation);
   }
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             adapter_.source_restrictions().max_pixels_per_frame());
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             adapter_.source_restrictions().target_pixels_per_frame());
   EXPECT_EQ(static_cast<double>(kBalancedHighFrameRateFps),
             adapter_.source_restrictions().max_frame_rate());
@@ -368,7 +368,7 @@
       static_cast<size_t>((kBalancedHighResolutionPixels * 3) / 5);
   EXPECT_EQ(kReducedPixelsFirstStep,
             adapter_.source_restrictions().max_pixels_per_frame());
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             adapter_.source_restrictions().target_pixels_per_frame());
   EXPECT_EQ(static_cast<double>(kBalancedHighFrameRateFps),
             adapter_.source_restrictions().max_frame_rate());
@@ -387,7 +387,7 @@
   }
   EXPECT_EQ(kReducedPixelsSecondStep,
             adapter_.source_restrictions().max_pixels_per_frame());
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             adapter_.source_restrictions().target_pixels_per_frame());
   EXPECT_EQ(static_cast<double>(kBalancedHighFrameRateFps),
             adapter_.source_restrictions().max_frame_rate());
@@ -482,7 +482,7 @@
     Adaptation adaptation = adapter_.GetAdaptationUp();
     EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
     fake_stream.ApplyAdaptation(adaptation);
-    EXPECT_EQ(absl::nullopt, adapter_.source_restrictions().max_frame_rate());
+    EXPECT_EQ(std::nullopt, adapter_.source_restrictions().max_frame_rate());
     EXPECT_EQ(2, adapter_.adaptation_counters().resolution_adaptations);
     EXPECT_EQ(0, adapter_.adaptation_counters().fps_adaptations);
   }
diff --git a/call/adaptation/video_stream_input_state.cc b/call/adaptation/video_stream_input_state.cc
index 9c0d475..0a12d2e 100644
--- a/call/adaptation/video_stream_input_state.cc
+++ b/call/adaptation/video_stream_input_state.cc
@@ -16,18 +16,18 @@
 
 VideoStreamInputState::VideoStreamInputState()
     : has_input_(false),
-      frame_size_pixels_(absl::nullopt),
+      frame_size_pixels_(std::nullopt),
       frames_per_second_(0),
       video_codec_type_(VideoCodecType::kVideoCodecGeneric),
       min_pixels_per_frame_(kDefaultMinPixelsPerFrame),
-      single_active_stream_pixels_(absl::nullopt) {}
+      single_active_stream_pixels_(std::nullopt) {}
 
 void VideoStreamInputState::set_has_input(bool has_input) {
   has_input_ = has_input;
 }
 
 void VideoStreamInputState::set_frame_size_pixels(
-    absl::optional<int> frame_size_pixels) {
+    std::optional<int> frame_size_pixels) {
   frame_size_pixels_ = frame_size_pixels;
 }
 
@@ -45,7 +45,7 @@
 }
 
 void VideoStreamInputState::set_single_active_stream_pixels(
-    absl::optional<int> single_active_stream_pixels) {
+    std::optional<int> single_active_stream_pixels) {
   single_active_stream_pixels_ = single_active_stream_pixels;
 }
 
@@ -53,7 +53,7 @@
   return has_input_;
 }
 
-absl::optional<int> VideoStreamInputState::frame_size_pixels() const {
+std::optional<int> VideoStreamInputState::frame_size_pixels() const {
   return frame_size_pixels_;
 }
 
@@ -69,7 +69,7 @@
   return min_pixels_per_frame_;
 }
 
-absl::optional<int> VideoStreamInputState::single_active_stream_pixels() const {
+std::optional<int> VideoStreamInputState::single_active_stream_pixels() const {
   return single_active_stream_pixels_;
 }
 
diff --git a/call/adaptation/video_stream_input_state.h b/call/adaptation/video_stream_input_state.h
index 191e223..744788d 100644
--- a/call/adaptation/video_stream_input_state.h
+++ b/call/adaptation/video_stream_input_state.h
@@ -11,7 +11,8 @@
 #ifndef CALL_ADAPTATION_VIDEO_STREAM_INPUT_STATE_H_
 #define CALL_ADAPTATION_VIDEO_STREAM_INPUT_STATE_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/video/video_codec_type.h"
 
 namespace webrtc {
@@ -23,29 +24,29 @@
   VideoStreamInputState();
 
   void set_has_input(bool has_input);
-  void set_frame_size_pixels(absl::optional<int> frame_size_pixels);
+  void set_frame_size_pixels(std::optional<int> frame_size_pixels);
   void set_frames_per_second(int frames_per_second);
   void set_video_codec_type(VideoCodecType video_codec_type);
   void set_min_pixels_per_frame(int min_pixels_per_frame);
   void set_single_active_stream_pixels(
-      absl::optional<int> single_active_stream_pixels);
+      std::optional<int> single_active_stream_pixels);
 
   bool has_input() const;
-  absl::optional<int> frame_size_pixels() const;
+  std::optional<int> frame_size_pixels() const;
   int frames_per_second() const;
   VideoCodecType video_codec_type() const;
   int min_pixels_per_frame() const;
-  absl::optional<int> single_active_stream_pixels() const;
+  std::optional<int> single_active_stream_pixels() const;
 
   bool HasInputFrameSizeAndFramesPerSecond() const;
 
  private:
   bool has_input_;
-  absl::optional<int> frame_size_pixels_;
+  std::optional<int> frame_size_pixels_;
   int frames_per_second_;
   VideoCodecType video_codec_type_;
   int min_pixels_per_frame_;
-  absl::optional<int> single_active_stream_pixels_;
+  std::optional<int> single_active_stream_pixels_;
 };
 
 }  // namespace webrtc
diff --git a/call/adaptation/video_stream_input_state_provider_unittest.cc b/call/adaptation/video_stream_input_state_provider_unittest.cc
index 5da2ef2..e9cd72b 100644
--- a/call/adaptation/video_stream_input_state_provider_unittest.cc
+++ b/call/adaptation/video_stream_input_state_provider_unittest.cc
@@ -24,11 +24,11 @@
   VideoStreamInputStateProvider input_state_provider(&frame_rate_provider);
   VideoStreamInputState input_state = input_state_provider.InputState();
   EXPECT_EQ(false, input_state.has_input());
-  EXPECT_EQ(absl::nullopt, input_state.frame_size_pixels());
+  EXPECT_EQ(std::nullopt, input_state.frame_size_pixels());
   EXPECT_EQ(0, input_state.frames_per_second());
   EXPECT_EQ(VideoCodecType::kVideoCodecGeneric, input_state.video_codec_type());
   EXPECT_EQ(kDefaultMinPixelsPerFrame, input_state.min_pixels_per_frame());
-  EXPECT_EQ(absl::nullopt, input_state.single_active_stream_pixels());
+  EXPECT_EQ(std::nullopt, input_state.single_active_stream_pixels());
 }
 
 TEST(VideoStreamInputStateProviderTest, ValuesSet) {
diff --git a/call/audio_receive_stream.h b/call/audio_receive_stream.h
index f2118e8..5154360 100644
--- a/call/audio_receive_stream.h
+++ b/call/audio_receive_stream.h
@@ -13,10 +13,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_decoder_factory.h"
 #include "api/call/transport.h"
 #include "api/crypto/crypto_options.h"
@@ -42,7 +42,7 @@
     uint64_t packets_discarded = 0;
     uint32_t nacks_sent = 0;
     std::string codec_name;
-    absl::optional<int> codec_payload_type;
+    std::optional<int> codec_payload_type;
     uint32_t jitter_ms = 0;
     uint32_t jitter_buffer_ms = 0;
     uint32_t jitter_buffer_preferred_ms = 0;
@@ -84,21 +84,21 @@
     // The timestamp at which the last packet was received, i.e. the time of the
     // local clock when it was received - not the RTP timestamp of that packet.
     // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-lastpacketreceivedtimestamp
-    absl::optional<Timestamp> last_packet_received;
+    std::optional<Timestamp> last_packet_received;
     uint64_t jitter_buffer_flushes = 0;
     double relative_packet_arrival_delay_seconds = 0.0;
     int32_t interruption_count = 0;
     int32_t total_interruption_duration_ms = 0;
     // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-estimatedplayouttimestamp
-    absl::optional<int64_t> estimated_playout_ntp_timestamp_ms;
+    std::optional<int64_t> estimated_playout_ntp_timestamp_ms;
     // Remote outbound stats derived by the received RTCP sender reports.
     // https://w3c.github.io/webrtc-stats/#remoteoutboundrtpstats-dict*
-    absl::optional<int64_t> last_sender_report_timestamp_ms;
-    absl::optional<int64_t> last_sender_report_remote_timestamp_ms;
+    std::optional<int64_t> last_sender_report_timestamp_ms;
+    std::optional<int64_t> last_sender_report_remote_timestamp_ms;
     uint64_t sender_reports_packets_sent = 0;
     uint64_t sender_reports_bytes_sent = 0;
     uint64_t sender_reports_reports_count = 0;
-    absl::optional<TimeDelta> round_trip_time;
+    std::optional<TimeDelta> round_trip_time;
     TimeDelta total_round_trip_time = TimeDelta::Zero();
     int round_trip_time_measurements = 0;
   };
@@ -141,7 +141,7 @@
 
     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory;
 
-    absl::optional<AudioCodecPairId> codec_pair_id;
+    std::optional<AudioCodecPairId> codec_pair_id;
 
     // Per PeerConnection crypto options.
     webrtc::CryptoOptions crypto_options;
diff --git a/call/audio_send_stream.h b/call/audio_send_stream.h
index 1b7a906..3794dfb 100644
--- a/call/audio_send_stream.h
+++ b/call/audio_send_stream.h
@@ -12,10 +12,10 @@
 #define CALL_AUDIO_SEND_STREAM_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_processing_statistics.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_encoder.h"
@@ -54,7 +54,7 @@
     int32_t packets_lost = -1;
     float fraction_lost = -1.0f;
     std::string codec_name;
-    absl::optional<int> codec_payload_type;
+    std::optional<int> codec_payload_type;
     int32_t jitter_ms = -1;
     int64_t rtt_ms = -1;
     int16_t audio_level = 0;
@@ -129,7 +129,7 @@
 
     // Defines whether to turn on audio network adaptor, and defines its config
     // string.
-    absl::optional<std::string> audio_network_adaptor_config;
+    std::optional<std::string> audio_network_adaptor_config;
 
     struct SendCodecSpec {
       SendCodecSpec(int payload_type, const SdpAudioFormat& format);
@@ -146,15 +146,15 @@
       bool nack_enabled = false;
       bool transport_cc_enabled = false;
       bool enable_non_sender_rtt = false;
-      absl::optional<int> cng_payload_type;
-      absl::optional<int> red_payload_type;
+      std::optional<int> cng_payload_type;
+      std::optional<int> red_payload_type;
       // If unset, use the encoder's default target bitrate.
-      absl::optional<int> target_bitrate_bps;
+      std::optional<int> target_bitrate_bps;
     };
 
-    absl::optional<SendCodecSpec> send_codec_spec;
+    std::optional<SendCodecSpec> send_codec_spec;
     rtc::scoped_refptr<AudioEncoderFactory> encoder_factory;
-    absl::optional<AudioCodecPairId> codec_pair_id;
+    std::optional<AudioCodecPairId> codec_pair_id;
 
     // Track ID as specified during track creation.
     std::string track_id;
diff --git a/call/bitrate_allocator.cc b/call/bitrate_allocator.cc
index e196f56..1b6d63a 100644
--- a/call/bitrate_allocator.cc
+++ b/call/bitrate_allocator.cc
@@ -318,14 +318,14 @@
   return allocation;
 }
 
-// Returns new allocation if modified, absl::nullopt otherwise.
-absl::optional<std::map<BitrateAllocatorObserver*, int>> MaybeApplySurplus(
+// Returns new allocation if modified, std::nullopt otherwise.
+std::optional<std::map<BitrateAllocatorObserver*, int>> MaybeApplySurplus(
     const std::map<BitrateAllocatorObserver*, int>& allocation,
     const std::vector<AllocatableTrack>& allocatable_tracks,
     DataRate bitrate,
     DataRate upper_elastic_limit) {
   if (upper_elastic_limit.IsZero())
-    return absl::nullopt;
+    return std::nullopt;
 
   // In this first pass looping over all `allocatable_tracks`, we aggregates
   // - `surplus`: sum of unused rates for all kCanContribute* tracks,
@@ -345,12 +345,12 @@
     }
     const DataRate allocated = DataRate::BitsPerSec(it->second);
     sum_allocated += allocated;
-    if (const absl::optional<TrackRateElasticity> elasticity =
+    if (const std::optional<TrackRateElasticity> elasticity =
             observer_config.config.rate_elasticity) {
       bool inactive_can_contribute_and_consume = false;
       if (elasticity == TrackRateElasticity::kCanContributeUnusedRate ||
           elasticity == TrackRateElasticity::kCanContributeAndConsume) {
-        if (const absl::optional<DataRate> used =
+        if (const std::optional<DataRate> used =
                 observer_config.observer->GetUsedRate()) {
           if (*used < allocated) {
             surplus += allocated - *used;
@@ -375,7 +375,7 @@
       (sum_allocated >= bitrate) ? (sum_allocated - bitrate) : DataRate::Zero();
   if (sum_demand < 0.0001 || overshoot > surplus) {
     // No demand for extra bitrate or no available surplus.
-    return absl::nullopt;
+    return std::nullopt;
   }
   surplus -= overshoot;
 
@@ -388,7 +388,7 @@
       // No allocation for this track.
       continue;
     }
-    absl::optional<TrackRateElasticity> elasticity =
+    std::optional<TrackRateElasticity> elasticity =
         observer_config.config.rate_elasticity;
     if (elasticity == TrackRateElasticity::kCanConsumeExtraRate ||
         elasticity == TrackRateElasticity::kCanContributeAndConsume) {
diff --git a/call/bitrate_allocator.h b/call/bitrate_allocator.h
index 07d92d1..33dd0e9 100644
--- a/call/bitrate_allocator.h
+++ b/call/bitrate_allocator.h
@@ -40,7 +40,7 @@
   // implementation, as bitrate in bps.
   virtual uint32_t OnBitrateUpdated(BitrateAllocationUpdate update) = 0;
   // Returns the bitrate consumed (vs allocated) by BitrateAllocatorObserver
-  virtual absl::optional<DataRate> GetUsedRate() const = 0;
+  virtual std::optional<DataRate> GetUsedRate() const = 0;
 
  protected:
   virtual ~BitrateAllocatorObserver() {}
@@ -71,7 +71,7 @@
   // observers. If an observer has twice the bitrate_priority of other
   // observers, it should be allocated twice the bitrate above its min.
   double bitrate_priority;
-  absl::optional<TrackRateElasticity> rate_elasticity;
+  std::optional<TrackRateElasticity> rate_elasticity;
 };
 
 // Interface used for mocking
@@ -97,7 +97,7 @@
   BitrateAllocatorObserver* observer;
   MediaStreamAllocationConfig config;
   int64_t allocated_bitrate_bps;
-  absl::optional<DataRate> last_used_bitrate;
+  std::optional<DataRate> last_used_bitrate;
   double media_ratio;  // Part of the total bitrate used for media [0.0, 1.0].
 
   uint32_t LastAllocatedBitrate() const;
diff --git a/call/bitrate_allocator_unittest.cc b/call/bitrate_allocator_unittest.cc
index 9c6599a..7b4fff3 100644
--- a/call/bitrate_allocator_unittest.cc
+++ b/call/bitrate_allocator_unittest.cc
@@ -76,9 +76,7 @@
     last_probing_interval_ms_ = update.bwe_period.ms();
     return update.target_bitrate.bps() * protection_ratio_;
   }
-  absl::optional<DataRate> GetUsedRate() const override {
-    return absl::nullopt;
-  }
+  std::optional<DataRate> GetUsedRate() const override { return std::nullopt; }
   uint32_t last_bitrate_bps_;
   uint8_t last_fraction_loss_;
   int64_t last_rtt_ms_;
@@ -89,7 +87,7 @@
 class TestContributingBitrateObserver : public TestBitrateObserver {
  public:
   TestContributingBitrateObserver() : rate_usage_(DataRate::Zero()) {}
-  absl::optional<DataRate> GetUsedRate() const override { return rate_usage_; }
+  std::optional<DataRate> GetUsedRate() const override { return rate_usage_; }
   DataRate rate_usage_;
 };
 
@@ -129,7 +127,7 @@
       uint32_t pad_up_bitrate_bps,
       bool enforce_min_bitrate,
       double bitrate_priority,
-      absl::optional<TrackRateElasticity> rate_elasticity = absl::nullopt) {
+      std::optional<TrackRateElasticity> rate_elasticity = std::nullopt) {
     allocator_->AddObserver(
         observer, {min_bitrate_bps, max_bitrate_bps, pad_up_bitrate_bps,
                    /* priority_bitrate */ 0, enforce_min_bitrate,
diff --git a/call/bitrate_estimator_tests.cc b/call/bitrate_estimator_tests.cc
index 2ffba5d..379f947 100644
--- a/call/bitrate_estimator_tests.cc
+++ b/call/bitrate_estimator_tests.cc
@@ -180,8 +180,8 @@
               &test->env().clock(),
               test::CreateSquareFrameGenerator(
                   test::VideoTestConstants::kDefaultWidth,
-                  test::VideoTestConstants::kDefaultHeight, absl::nullopt,
-                  absl::nullopt),
+                  test::VideoTestConstants::kDefaultHeight, std::nullopt,
+                  std::nullopt),
               test::VideoTestConstants::kDefaultFramerate,
               test->env().task_queue_factory());
       frame_generator_capturer_->Init();
diff --git a/call/call.cc b/call/call.cc
index 2e4a25e..aa48491 100644
--- a/call/call.cc
+++ b/call/call.cc
@@ -17,13 +17,13 @@
 #include <cstdint>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <utility>
 #include <vector>
 
 #include "absl/functional/bind_front.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/media_types.h"
 #include "api/rtc_event_log/rtc_event_log.h"
 #include "api/sequence_checker.h"
@@ -288,13 +288,13 @@
         RTC_GUARDED_BY(sequence_checker_);
     RateCounter received_rtcp_bytes_per_second_counter_
         RTC_GUARDED_BY(sequence_checker_);
-    absl::optional<Timestamp> first_received_rtp_audio_timestamp_
+    std::optional<Timestamp> first_received_rtp_audio_timestamp_
         RTC_GUARDED_BY(sequence_checker_);
-    absl::optional<Timestamp> last_received_rtp_audio_timestamp_
+    std::optional<Timestamp> last_received_rtp_audio_timestamp_
         RTC_GUARDED_BY(sequence_checker_);
-    absl::optional<Timestamp> first_received_rtp_video_timestamp_
+    std::optional<Timestamp> first_received_rtp_video_timestamp_
         RTC_GUARDED_BY(sequence_checker_);
-    absl::optional<Timestamp> last_received_rtp_video_timestamp_
+    std::optional<Timestamp> last_received_rtp_video_timestamp_
         RTC_GUARDED_BY(sequence_checker_);
   };
 
@@ -306,7 +306,7 @@
     explicit SendStats(Clock* clock);
     ~SendStats();
 
-    void SetFirstPacketTime(absl::optional<Timestamp> first_sent_packet_time);
+    void SetFirstPacketTime(std::optional<Timestamp> first_sent_packet_time);
     void PauseSendAndPacerBitrateCounters();
     void AddTargetBitrateSample(uint32_t target_bitrate_bps);
     void SetMinAllocatableRate(BitrateAllocationLimits limits);
@@ -320,7 +320,7 @@
     AvgCounter pacer_bitrate_kbps_counter_ RTC_GUARDED_BY(sequence_checker_);
     uint32_t min_allocated_send_bitrate_bps_ RTC_GUARDED_BY(sequence_checker_){
         0};
-    absl::optional<Timestamp> first_sent_packet_time_
+    std::optional<Timestamp> first_sent_packet_time_
         RTC_GUARDED_BY(destructor_sequence_checker_);
   };
 
@@ -451,7 +451,7 @@
   // Sequence checker for outgoing network traffic. Could be the network thread.
   // Could also be a pacer owned thread or TQ such as the TaskQueueSender.
   RTC_NO_UNIQUE_ADDRESS SequenceChecker sent_packet_sequence_checker_;
-  absl::optional<rtc::SentPacket> last_sent_packet_
+  std::optional<rtc::SentPacket> last_sent_packet_
       RTC_GUARDED_BY(sent_packet_sequence_checker_);
 };
 }  // namespace internal
@@ -620,7 +620,7 @@
 }
 
 void Call::SendStats::SetFirstPacketTime(
-    absl::optional<Timestamp> first_sent_packet_time) {
+    std::optional<Timestamp> first_sent_packet_time) {
   RTC_DCHECK_RUN_ON(&destructor_sequence_checker_);
   first_sent_packet_time_ = first_sent_packet_time;
 }
@@ -771,7 +771,7 @@
 
   // Stream config is logged in AudioSendStream::ConfigureStream, as it may
   // change during the stream's lifetime.
-  absl::optional<RtpState> suspended_rtp_state;
+  std::optional<RtpState> suspended_rtp_state;
   {
     const auto& iter = suspended_audio_send_ssrcs_.find(config.rtp.ssrc);
     if (iter != suspended_audio_send_ssrcs_.end()) {
diff --git a/call/call_config.h b/call/call_config.h
index 724dad4..74c15509 100644
--- a/call/call_config.h
+++ b/call/call_config.h
@@ -81,7 +81,7 @@
   Metronome* encode_metronome = nullptr;
 
   // The burst interval of the pacer, see TaskQueuePacedSender constructor.
-  absl::optional<TimeDelta> pacer_burst_interval;
+  std::optional<TimeDelta> pacer_burst_interval;
 
   // Enables send packet batching from the egress RTP sender.
   bool enable_send_packet_batching = false;
diff --git a/call/create_call.cc b/call/create_call.cc
index 573033e..f0c4b54 100644
--- a/call/create_call.cc
+++ b/call/create_call.cc
@@ -11,7 +11,10 @@
 #include "call/create_call.h"
 
 #include <memory>
+#include <optional>
 
+#include "api/test/simulated_network.h"
+#include "api/units/time_delta.h"
 #include "call/call.h"
 
 namespace webrtc {
diff --git a/call/fake_network_pipe.cc b/call/fake_network_pipe.cc
index 3c7207b..474d2ac 100644
--- a/call/fake_network_pipe.cc
+++ b/call/fake_network_pipe.cc
@@ -33,10 +33,10 @@
 NetworkPacket::NetworkPacket(rtc::CopyOnWriteBuffer packet,
                              int64_t send_time,
                              int64_t arrival_time,
-                             absl::optional<PacketOptions> packet_options,
+                             std::optional<PacketOptions> packet_options,
                              bool is_rtcp,
                              MediaType media_type,
-                             absl::optional<int64_t> packet_time_us,
+                             std::optional<int64_t> packet_time_us,
                              Transport* transport)
     : packet_(std::move(packet)),
       send_time_(send_time),
@@ -146,7 +146,7 @@
 bool FakeNetworkPipe::SendRtcp(rtc::ArrayView<const uint8_t> packet,
                                Transport* transport) {
   RTC_DCHECK(transport);
-  EnqueuePacket(rtc::CopyOnWriteBuffer(packet), absl::nullopt, true, transport);
+  EnqueuePacket(rtc::CopyOnWriteBuffer(packet), std::nullopt, true, transport);
   return true;
 }
 
@@ -161,8 +161,8 @@
 }
 
 void FakeNetworkPipe::DeliverRtcpPacket(rtc::CopyOnWriteBuffer packet) {
-  EnqueuePacket(std::move(packet), absl::nullopt, true, MediaType::ANY,
-                absl::nullopt);
+  EnqueuePacket(std::move(packet), std::nullopt, true, MediaType::ANY,
+                std::nullopt);
 }
 
 void FakeNetworkPipe::SetClockOffset(int64_t offset_ms) {
@@ -174,10 +174,10 @@
     : packet(std::move(packet)) {}
 
 bool FakeNetworkPipe::EnqueuePacket(rtc::CopyOnWriteBuffer packet,
-                                    absl::optional<PacketOptions> options,
+                                    std::optional<PacketOptions> options,
                                     bool is_rtcp,
                                     MediaType media_type,
-                                    absl::optional<int64_t> packet_time_us) {
+                                    std::optional<int64_t> packet_time_us) {
   MutexLock lock(&process_lock_);
   int64_t time_now_us = clock_->TimeInMicroseconds();
   return EnqueuePacket(NetworkPacket(std::move(packet), time_now_us,
@@ -186,14 +186,14 @@
 }
 
 bool FakeNetworkPipe::EnqueuePacket(rtc::CopyOnWriteBuffer packet,
-                                    absl::optional<PacketOptions> options,
+                                    std::optional<PacketOptions> options,
                                     bool is_rtcp,
                                     Transport* transport) {
   MutexLock lock(&process_lock_);
   int64_t time_now_us = clock_->TimeInMicroseconds();
   return EnqueuePacket(NetworkPacket(std::move(packet), time_now_us,
                                      time_now_us, options, is_rtcp,
-                                     MediaType::ANY, absl::nullopt, transport));
+                                     MediaType::ANY, std::nullopt, transport));
 }
 
 bool FakeNetworkPipe::EnqueuePacket(NetworkPacket&& net_packet) {
@@ -348,14 +348,14 @@
   }
 }
 
-absl::optional<int64_t> FakeNetworkPipe::TimeUntilNextProcess() {
+std::optional<int64_t> FakeNetworkPipe::TimeUntilNextProcess() {
   MutexLock lock(&process_lock_);
-  absl::optional<int64_t> delivery_us = network_behavior_->NextDeliveryTimeUs();
+  std::optional<int64_t> delivery_us = network_behavior_->NextDeliveryTimeUs();
   if (delivery_us) {
     int64_t delay_us = *delivery_us - clock_->TimeInMicroseconds();
     return std::max<int64_t>((delay_us + 500) / 1000, 0);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool FakeNetworkPipe::HasReceiver() const {
diff --git a/call/fake_network_pipe.h b/call/fake_network_pipe.h
index 7bc7e0f..ea4b1af 100644
--- a/call/fake_network_pipe.h
+++ b/call/fake_network_pipe.h
@@ -37,10 +37,10 @@
   NetworkPacket(rtc::CopyOnWriteBuffer packet,
                 int64_t send_time,
                 int64_t arrival_time,
-                absl::optional<PacketOptions> packet_options,
+                std::optional<PacketOptions> packet_options,
                 bool is_rtcp,
                 MediaType media_type,
-                absl::optional<int64_t> packet_time_us,
+                std::optional<int64_t> packet_time_us,
                 Transport* transport);
 
   NetworkPacket(RtpPacketReceived packet,
@@ -69,11 +69,11 @@
   }
   bool is_rtcp() const { return is_rtcp_; }
   MediaType media_type() const { return media_type_; }
-  absl::optional<int64_t> packet_time_us() const { return packet_time_us_; }
+  std::optional<int64_t> packet_time_us() const { return packet_time_us_; }
   RtpPacketReceived* packet_received() {
     return packet_received_ ? &packet_received_.value() : nullptr;
   }
-  absl::optional<RtpPacketReceived> packet_received() const {
+  std::optional<RtpPacketReceived> packet_received() const {
     return packet_received_;
   }
   Transport* transport() const { return transport_; }
@@ -86,15 +86,15 @@
   int64_t arrival_time_;
   // If using a Transport for outgoing degradation, populate with
   // PacketOptions (transport-wide sequence number) for RTP.
-  absl::optional<PacketOptions> packet_options_;
+  std::optional<PacketOptions> packet_options_;
   bool is_rtcp_;
   // If using a PacketReceiver for incoming degradation, populate with
   // appropriate MediaType and packet time. This type/timing will be kept and
   // forwarded. The packet time might be altered to reflect time spent in fake
   // network pipe.
   MediaType media_type_;
-  absl::optional<int64_t> packet_time_us_;
-  absl::optional<RtpPacketReceived> packet_received_;
+  std::optional<int64_t> packet_time_us_;
+  std::optional<RtpPacketReceived> packet_received_;
   Transport* transport_;
 };
 
@@ -150,7 +150,7 @@
   // Processes the network queues and trigger PacketReceiver::IncomingPacket for
   // packets ready to be delivered.
   void Process() override;
-  absl::optional<int64_t> TimeUntilNextProcess() override;
+  std::optional<int64_t> TimeUntilNextProcess() override;
 
   // Get statistics.
   float PercentageLoss();
@@ -179,15 +179,15 @@
   // Returns true if enqueued, or false if packet was dropped. Use this method
   // when enqueueing packets that should be received by PacketReceiver instance.
   bool EnqueuePacket(rtc::CopyOnWriteBuffer packet,
-                     absl::optional<PacketOptions> options,
+                     std::optional<PacketOptions> options,
                      bool is_rtcp,
                      MediaType media_type,
-                     absl::optional<int64_t> packet_time_us);
+                     std::optional<int64_t> packet_time_us);
 
   // Returns true if enqueued, or false if packet was dropped. Use this method
   // when enqueueing packets that should be received by Transport instance.
   bool EnqueuePacket(rtc::CopyOnWriteBuffer packet,
-                     absl::optional<PacketOptions> options,
+                     std::optional<PacketOptions> options,
                      bool is_rtcp,
                      Transport* transport);
 
diff --git a/call/receive_time_calculator_unittest.cc b/call/receive_time_calculator_unittest.cc
index f2e3d54..312a79d 100644
--- a/call/receive_time_calculator_unittest.cc
+++ b/call/receive_time_calculator_unittest.cc
@@ -15,9 +15,9 @@
 #include <algorithm>
 #include <cmath>
 #include <cstdint>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "rtc_base/random.h"
 #include "rtc_base/time_utils.h"
 #include "test/gtest.h"
@@ -50,7 +50,7 @@
 
  private:
   int64_t clock_us_;
-  absl::optional<int64_t> last_query_us_;
+  std::optional<int64_t> last_query_us_;
   float drift_;
   float accumulated_drift_us_ = 0;
 };
diff --git a/call/rtp_bitrate_configurator.cc b/call/rtp_bitrate_configurator.cc
index 264dcdc..f0a36ad 100644
--- a/call/rtp_bitrate_configurator.cc
+++ b/call/rtp_bitrate_configurator.cc
@@ -49,7 +49,7 @@
   return bitrate_config_;
 }
 
-absl::optional<BitrateConstraints>
+std::optional<BitrateConstraints>
 RtpBitrateConfigurator::UpdateWithSdpParameters(
     const BitrateConstraints& bitrate_config) {
   RTC_DCHECK_GE(bitrate_config.min_bitrate_bps, 0);
@@ -58,7 +58,7 @@
     RTC_DCHECK_GT(bitrate_config.max_bitrate_bps, 0);
   }
 
-  absl::optional<int> new_start;
+  std::optional<int> new_start;
   // Only update the "start" bitrate if it's set, and different from the old
   // value. In practice, this value comes from the x-google-start-bitrate codec
   // parameter in SDP, and setting the same remote description twice shouldn't
@@ -72,7 +72,7 @@
   return UpdateConstraints(new_start);
 }
 
-absl::optional<BitrateConstraints>
+std::optional<BitrateConstraints>
 RtpBitrateConfigurator::UpdateWithClientPreferences(
     const BitrateSettings& bitrate_mask) {
   bitrate_config_mask_ = bitrate_mask;
@@ -80,17 +80,17 @@
 }
 
 // Relay cap can change only max bitrate.
-absl::optional<BitrateConstraints> RtpBitrateConfigurator::UpdateWithRelayCap(
+std::optional<BitrateConstraints> RtpBitrateConfigurator::UpdateWithRelayCap(
     DataRate cap) {
   if (cap.IsFinite()) {
     RTC_DCHECK(!cap.IsZero());
   }
   max_bitrate_over_relay_ = cap;
-  return UpdateConstraints(absl::nullopt);
+  return UpdateConstraints(std::nullopt);
 }
 
-absl::optional<BitrateConstraints> RtpBitrateConfigurator::UpdateConstraints(
-    const absl::optional<int>& new_start) {
+std::optional<BitrateConstraints> RtpBitrateConfigurator::UpdateConstraints(
+    const std::optional<int>& new_start) {
   BitrateConstraints updated;
   updated.min_bitrate_bps =
       std::max(bitrate_config_mask_.min_bitrate_bps.value_or(0),
@@ -114,7 +114,7 @@
   if (updated.min_bitrate_bps == bitrate_config_.min_bitrate_bps &&
       updated.max_bitrate_bps == bitrate_config_.max_bitrate_bps &&
       !new_start) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (new_start) {
diff --git a/call/rtp_bitrate_configurator.h b/call/rtp_bitrate_configurator.h
index 5cb779a..754629d 100644
--- a/call/rtp_bitrate_configurator.h
+++ b/call/rtp_bitrate_configurator.h
@@ -11,7 +11,8 @@
 #ifndef CALL_RTP_BITRATE_CONFIGURATOR_H_
 #define CALL_RTP_BITRATE_CONFIGURATOR_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/transport/bitrate_settings.h"
 #include "api/units/data_rate.h"
 
@@ -36,7 +37,7 @@
   // implemented. Passing -1 leaves the start bitrate unchanged. Behavior is not
   // guaranteed for other negative values or 0.
   // The optional return value is set with new configuration if it was updated.
-  absl::optional<BitrateConstraints> UpdateWithSdpParameters(
+  std::optional<BitrateConstraints> UpdateWithSdpParameters(
       const BitrateConstraints& bitrate_config_);
 
   // The greater min and smaller max set by this and SetSdpBitrateParameters
@@ -45,17 +46,17 @@
   // Assumes 0 <= min <= start <= max holds for set parameters.
   // Update the bitrate configuration
   // The optional return value is set with new configuration if it was updated.
-  absl::optional<BitrateConstraints> UpdateWithClientPreferences(
+  std::optional<BitrateConstraints> UpdateWithClientPreferences(
       const BitrateSettings& bitrate_mask);
 
   // Apply a cap for relayed calls.
-  absl::optional<BitrateConstraints> UpdateWithRelayCap(DataRate cap);
+  std::optional<BitrateConstraints> UpdateWithRelayCap(DataRate cap);
 
  private:
   // Applies update to the BitrateConstraints cached in `config_`, resetting
   // with `new_start` if set.
-  absl::optional<BitrateConstraints> UpdateConstraints(
-      const absl::optional<int>& new_start);
+  std::optional<BitrateConstraints> UpdateConstraints(
+      const std::optional<int>& new_start);
 
   // Bitrate config used until valid bitrate estimates are calculated. Also
   // used to cap total bitrate used. This comes from the remote connection.
diff --git a/call/rtp_bitrate_configurator_unittest.cc b/call/rtp_bitrate_configurator_unittest.cc
index 6449a1a..0b019ce 100644
--- a/call/rtp_bitrate_configurator_unittest.cc
+++ b/call/rtp_bitrate_configurator_unittest.cc
@@ -14,7 +14,7 @@
 #include "test/gtest.h"
 
 namespace webrtc {
-using absl::nullopt;
+using std::nullopt;
 
 class RtpBitrateConfiguratorTest : public ::testing::Test {
  public:
@@ -22,10 +22,10 @@
       : configurator_(new RtpBitrateConfigurator(BitrateConstraints())) {}
   std::unique_ptr<RtpBitrateConfigurator> configurator_;
   void UpdateConfigMatches(BitrateConstraints bitrate_config,
-                           absl::optional<int> min_bitrate_bps,
-                           absl::optional<int> start_bitrate_bps,
-                           absl::optional<int> max_bitrate_bps) {
-    absl::optional<BitrateConstraints> result =
+                           std::optional<int> min_bitrate_bps,
+                           std::optional<int> start_bitrate_bps,
+                           std::optional<int> max_bitrate_bps) {
+    std::optional<BitrateConstraints> result =
         configurator_->UpdateWithSdpParameters(bitrate_config);
     EXPECT_TRUE(result.has_value());
     if (start_bitrate_bps.has_value())
@@ -37,10 +37,10 @@
   }
 
   void UpdateMaskMatches(BitrateSettings bitrate_mask,
-                         absl::optional<int> min_bitrate_bps,
-                         absl::optional<int> start_bitrate_bps,
-                         absl::optional<int> max_bitrate_bps) {
-    absl::optional<BitrateConstraints> result =
+                         std::optional<int> min_bitrate_bps,
+                         std::optional<int> start_bitrate_bps,
+                         std::optional<int> max_bitrate_bps) {
+    std::optional<BitrateConstraints> result =
         configurator_->UpdateWithClientPreferences(bitrate_mask);
     EXPECT_TRUE(result.has_value());
     if (start_bitrate_bps.has_value())
diff --git a/call/rtp_config.cc b/call/rtp_config.cc
index 5457a94..43b615c 100644
--- a/call/rtp_config.cc
+++ b/call/rtp_config.cc
@@ -155,12 +155,12 @@
   return flexfec.payload_type != -1 && ssrc == flexfec.ssrc;
 }
 
-absl::optional<uint32_t> RtpConfig::GetRtxSsrcAssociatedWithMediaSsrc(
+std::optional<uint32_t> RtpConfig::GetRtxSsrcAssociatedWithMediaSsrc(
     uint32_t media_ssrc) const {
   RTC_DCHECK(IsMediaSsrc(media_ssrc));
   // If we don't use RTX there is no association.
   if (rtx.ssrcs.empty())
-    return absl::nullopt;
+    return std::nullopt;
   // If we use RTX there MUST be an association ssrcs[i] <-> rtx.ssrcs[i].
   RTC_DCHECK_EQ(ssrcs.size(), rtx.ssrcs.size());
   return FindAssociatedSsrc(media_ssrc, ssrcs, rtx.ssrcs);
@@ -189,7 +189,7 @@
   return media_ssrc;
 }
 
-absl::optional<std::string> RtpConfig::GetRidForSsrc(uint32_t ssrc) const {
+std::optional<std::string> RtpConfig::GetRidForSsrc(uint32_t ssrc) const {
   auto it = std::find(ssrcs.begin(), ssrcs.end(), ssrc);
   if (it != ssrcs.end()) {
     size_t ssrc_index = std::distance(ssrcs.begin(), it);
@@ -197,7 +197,7 @@
       return rids[ssrc_index];
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace webrtc
diff --git a/call/rtp_config.h b/call/rtp_config.h
index ec76d42..0e667b2 100644
--- a/call/rtp_config.h
+++ b/call/rtp_config.h
@@ -14,10 +14,10 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/rtp_headers.h"
 #include "api/rtp_parameters.h"
 
@@ -166,11 +166,11 @@
   bool IsMediaSsrc(uint32_t ssrc) const;
   bool IsRtxSsrc(uint32_t ssrc) const;
   bool IsFlexfecSsrc(uint32_t ssrc) const;
-  absl::optional<uint32_t> GetRtxSsrcAssociatedWithMediaSsrc(
+  std::optional<uint32_t> GetRtxSsrcAssociatedWithMediaSsrc(
       uint32_t media_ssrc) const;
   uint32_t GetMediaSsrcAssociatedWithRtxSsrc(uint32_t rtx_ssrc) const;
   uint32_t GetMediaSsrcAssociatedWithFlexfecSsrc(uint32_t flexfec_ssrc) const;
-  absl::optional<std::string> GetRidForSsrc(uint32_t ssrc) const;
+  std::optional<std::string> GetRidForSsrc(uint32_t ssrc) const;
 };
 }  // namespace webrtc
 #endif  // CALL_RTP_CONFIG_H_
diff --git a/call/rtp_payload_params.cc b/call/rtp_payload_params.cc
index 33e9c76..00e7509 100644
--- a/call/rtp_payload_params.cc
+++ b/call/rtp_payload_params.cc
@@ -35,7 +35,7 @@
 constexpr int kMaxSimulatedSpatialLayers = 3;
 
 void PopulateRtpWithCodecSpecifics(const CodecSpecificInfo& info,
-                                   absl::optional<int> spatial_index,
+                                   std::optional<int> spatial_index,
                                    RTPVideoHeader* rtp) {
   rtp->codec = info.codecType;
   rtp->is_last_frame_in_picture = info.end_of_picture;
@@ -198,7 +198,7 @@
 RTPVideoHeader RtpPayloadParams::GetRtpVideoHeader(
     const EncodedImage& image,
     const CodecSpecificInfo* codec_specific_info,
-    absl::optional<int64_t> shared_frame_id) {
+    std::optional<int64_t> shared_frame_id) {
   int64_t frame_id;
   if (shared_frame_id) {
     frame_id = *shared_frame_id;
@@ -219,8 +219,8 @@
   rtp_video_header.width = image._encodedWidth;
   rtp_video_header.height = image._encodedHeight;
   rtp_video_header.color_space = image.ColorSpace()
-                                     ? absl::make_optional(*image.ColorSpace())
-                                     : absl::nullopt;
+                                     ? std::make_optional(*image.ColorSpace())
+                                     : std::nullopt;
   rtp_video_header.video_frame_tracking_id = image.VideoFrameTrackingId();
   SetVideoTiming(image, &rtp_video_header.video_timing);
 
@@ -353,10 +353,10 @@
   RTC_DCHECK_NOTREACHED() << "Unsupported codec.";
 }
 
-absl::optional<FrameDependencyStructure> RtpPayloadParams::GenericStructure(
+std::optional<FrameDependencyStructure> RtpPayloadParams::GenericStructure(
     const CodecSpecificInfo* codec_specific_info) {
   if (codec_specific_info == nullptr) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   // This helper shouldn't be used when template structure is specified
   // explicetly.
@@ -367,15 +367,14 @@
         return MinimalisticStructure(/*num_spatial_layers=*/1,
                                      /*num_temporal_layer=*/1);
       }
-      return absl::nullopt;
+      return std::nullopt;
     case VideoCodecType::kVideoCodecVP8:
       return MinimalisticStructure(/*num_spatial_layers=*/1,
                                    /*num_temporal_layer=*/kMaxTemporalStreams);
     case VideoCodecType::kVideoCodecVP9: {
-      absl::optional<FrameDependencyStructure> structure =
-          MinimalisticStructure(
-              /*num_spatial_layers=*/kMaxSimulatedSpatialLayers,
-              /*num_temporal_layer=*/kMaxTemporalStreams);
+      std::optional<FrameDependencyStructure> structure = MinimalisticStructure(
+          /*num_spatial_layers=*/kMaxSimulatedSpatialLayers,
+          /*num_temporal_layer=*/kMaxTemporalStreams);
       const CodecSpecificInfoVP9& vp9 = codec_specific_info->codecSpecific.VP9;
       if (vp9.ss_data_available && vp9.spatial_layer_resolution_present) {
         RenderResolution first_valid;
@@ -411,7 +410,7 @@
     case VideoCodecType::kVideoCodecAV1:
     case VideoCodecType::kVideoCodecH264:
     case VideoCodecType::kVideoCodecH265:
-      return absl::nullopt;
+      return std::nullopt;
   }
   RTC_DCHECK_NOTREACHED() << "Unsupported codec.";
 }
diff --git a/call/rtp_payload_params.h b/call/rtp_payload_params.h
index ee685d1..870e3c3 100644
--- a/call/rtp_payload_params.h
+++ b/call/rtp_payload_params.h
@@ -12,9 +12,9 @@
 #define CALL_RTP_PAYLOAD_PARAMS_H_
 
 #include <array>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/video_codecs/video_encoder.h"
 #include "call/rtp_config.h"
@@ -38,11 +38,11 @@
 
   RTPVideoHeader GetRtpVideoHeader(const EncodedImage& image,
                                    const CodecSpecificInfo* codec_specific_info,
-                                   absl::optional<int64_t> shared_frame_id);
+                                   std::optional<int64_t> shared_frame_id);
 
   // Returns structure that aligns with simulated generic info generated by
   // `GetRtpVideoHeader` for the `codec_specific_info`
-  absl::optional<FrameDependencyStructure> GenericStructure(
+  std::optional<FrameDependencyStructure> GenericStructure(
       const CodecSpecificInfo* codec_specific_info);
 
   uint32_t ssrc() const;
@@ -122,7 +122,7 @@
   // that, for a given object, we either always use
   // SetDependenciesVp8Deprecated(), or always use SetDependenciesVp8New().
   // TODO(bugs.webrtc.org/10242): Remove.
-  absl::optional<bool> new_version_used_;
+  std::optional<bool> new_version_used_;
 
   const uint32_t ssrc_;
   RtpPayloadState state_;
diff --git a/call/rtp_payload_params_unittest.cc b/call/rtp_payload_params_unittest.cc
index 0099084..15096cf 100644
--- a/call/rtp_payload_params_unittest.cc
+++ b/call/rtp_payload_params_unittest.cc
@@ -13,10 +13,10 @@
 #include <string.h>
 
 #include <map>
+#include <optional>
 #include <set>
 
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/transport/field_trial_based_config.h"
 #include "api/video/video_content_type.h"
@@ -144,7 +144,7 @@
   EXPECT_EQ(kVideoRotation_90, header.rotation);
   EXPECT_EQ(VideoContentType::SCREENSHARE, header.content_type);
   EXPECT_EQ(kVideoCodecVP9, header.codec);
-  EXPECT_EQ(absl::make_optional(color_space), header.color_space);
+  EXPECT_EQ(std::make_optional(color_space), header.color_space);
   EXPECT_EQ(kPictureId + 1, vp9_header.picture_id);
   EXPECT_EQ(kTl0PicIdx, vp9_header.tl0_pic_idx);
   EXPECT_EQ(vp9_header.temporal_idx, codec_info.codecSpecific.VP9.temporal_idx);
@@ -371,7 +371,7 @@
 
   RtpPayloadParams params(kSsrc1, &state, FieldTrialBasedConfig());
   RTPVideoHeader header =
-      params.GetRtpVideoHeader(encoded_image, &codec_info, absl::nullopt);
+      params.GetRtpVideoHeader(encoded_image, &codec_info, std::nullopt);
 
   EXPECT_THAT(header.codec, Eq(kVideoCodecGeneric));
 
@@ -379,7 +379,7 @@
   EXPECT_THAT(header.generic->frame_id, Eq(123));
 
   encoded_image._frameType = VideoFrameType::kVideoFrameDelta;
-  header = params.GetRtpVideoHeader(encoded_image, &codec_info, absl::nullopt);
+  header = params.GetRtpVideoHeader(encoded_image, &codec_info, std::nullopt);
   ASSERT_TRUE(header.generic);
   EXPECT_THAT(header.generic->frame_id, Eq(124));
 }
diff --git a/call/rtp_transport_config.h b/call/rtp_transport_config.h
index cce5214..b310710 100644
--- a/call/rtp_transport_config.h
+++ b/call/rtp_transport_config.h
@@ -12,8 +12,8 @@
 #define CALL_RTP_TRANSPORT_CONFIG_H_
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/network_state_predictor.h"
 #include "api/transport/bitrate_settings.h"
@@ -37,7 +37,7 @@
   NetworkControllerFactoryInterface* network_controller_factory = nullptr;
 
   // The burst interval of the pacer, see TaskQueuePacedSender constructor.
-  absl::optional<TimeDelta> pacer_burst_interval;
+  std::optional<TimeDelta> pacer_burst_interval;
 };
 }  // namespace webrtc
 
diff --git a/call/rtp_transport_controller_send.cc b/call/rtp_transport_controller_send.cc
index 627adba..34cf06d 100644
--- a/call/rtp_transport_controller_send.cc
+++ b/call/rtp_transport_controller_send.cc
@@ -11,12 +11,12 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/task_queue/pending_task_safety_flag.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/transport/goog_cc_factory.h"
@@ -199,7 +199,7 @@
 }
 
 void RtpTransportControllerSend::UpdateControlState() {
-  absl::optional<TargetTransferRate> update = control_handler_->GetUpdate();
+  std::optional<TargetTransferRate> update = control_handler_->GetUpdate();
   if (!update)
     return;
   retransmission_rate_limiter_.SetMaxRate(update->target_rate.bps());
@@ -215,13 +215,13 @@
   }
 }
 
-absl::optional<bool> RtpTransportControllerSend::GetCongestedStateUpdate()
+std::optional<bool> RtpTransportControllerSend::GetCongestedStateUpdate()
     const {
   bool congested = transport_feedback_adapter_.GetOutstandingData() >=
                    congestion_window_size_;
   if (congested != is_congested_)
     return congested;
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 PacketRouter* RtpTransportControllerSend::packet_router() {
@@ -326,7 +326,7 @@
     return;
   }
 
-  absl::optional<BitrateConstraints> relay_constraint_update =
+  std::optional<BitrateConstraints> relay_constraint_update =
       ApplyOrLiftRelayCap(IsRelayed(network_route));
 
   // Check whether the network route has changed on each transport.
@@ -413,7 +413,7 @@
 int64_t RtpTransportControllerSend::GetPacerQueuingDelayMs() const {
   return pacer_.OldestPacketWaitTime().ms();
 }
-absl::optional<Timestamp> RtpTransportControllerSend::GetFirstPacketTime()
+std::optional<Timestamp> RtpTransportControllerSend::GetFirstPacketTime()
     const {
   return pacer_.FirstSentPacketTime();
 }
@@ -444,7 +444,7 @@
 void RtpTransportControllerSend::ProcessSentPacket(
     const rtc::SentPacket& sent_packet) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
-  absl::optional<SentPacket> packet_msg =
+  std::optional<SentPacket> packet_msg =
       transport_feedback_adapter_.ProcessSentPacket(sent_packet);
   if (!packet_msg)
     return;
@@ -493,7 +493,7 @@
 void RtpTransportControllerSend::SetSdpBitrateParameters(
     const BitrateConstraints& constraints) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
-  absl::optional<BitrateConstraints> updated =
+  std::optional<BitrateConstraints> updated =
       bitrate_configurator_.UpdateWithSdpParameters(constraints);
   if (updated.has_value()) {
     UpdateBitrateConstraints(*updated);
@@ -507,7 +507,7 @@
 void RtpTransportControllerSend::SetClientBitratePreferences(
     const BitrateSettings& preferences) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
-  absl::optional<BitrateConstraints> updated =
+  std::optional<BitrateConstraints> updated =
       bitrate_configurator_.UpdateWithClientPreferences(preferences);
   if (updated.has_value()) {
     UpdateBitrateConstraints(*updated);
@@ -518,7 +518,7 @@
   }
 }
 
-absl::optional<BitrateConstraints>
+std::optional<BitrateConstraints>
 RtpTransportControllerSend::ApplyOrLiftRelayCap(bool is_relayed) {
   DataRate cap = is_relayed ? relay_bandwidth_cap_ : DataRate::PlusInfinity();
   return bitrate_configurator_.UpdateWithRelayCap(cap);
@@ -608,7 +608,7 @@
     const rtcp::TransportFeedback& feedback) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   feedback_demuxer_.OnTransportFeedback(feedback);
-  absl::optional<TransportPacketsFeedback> feedback_msg =
+  std::optional<TransportPacketsFeedback> feedback_msg =
       transport_feedback_adapter_.ProcessTransportFeedback(feedback,
                                                            receive_time);
   if (feedback_msg) {
diff --git a/call/rtp_transport_controller_send.h b/call/rtp_transport_controller_send.h
index 9b91d9a..602feb3 100644
--- a/call/rtp_transport_controller_send.h
+++ b/call/rtp_transport_controller_send.h
@@ -93,7 +93,7 @@
   void OnNetworkAvailability(bool network_available) override;
   NetworkLinkRtcpObserver* GetRtcpObserver() override;
   int64_t GetPacerQueuingDelayMs() const override;
-  absl::optional<Timestamp> GetFirstPacketTime() const override;
+  std::optional<Timestamp> GetFirstPacketTime() const override;
   void EnablePeriodicAlrProbing(bool enable) override;
   void OnSentPacket(const rtc::SentPacket& sent_packet) override;
   void OnReceivedPacket(const ReceivedPacket& packet_msg) override;
@@ -134,7 +134,7 @@
   void StartProcessPeriodicTasks() RTC_RUN_ON(sequence_checker_);
   void UpdateControllerWithTimeInterval() RTC_RUN_ON(sequence_checker_);
 
-  absl::optional<BitrateConstraints> ApplyOrLiftRelayCap(bool is_relayed);
+  std::optional<BitrateConstraints> ApplyOrLiftRelayCap(bool is_relayed);
   bool IsRelevantRouteChange(const rtc::NetworkRoute& old_route,
                              const rtc::NetworkRoute& new_route) const;
   void UpdateBitrateConstraints(const BitrateConstraints& updated);
@@ -142,7 +142,7 @@
   void PostUpdates(NetworkControlUpdate update) RTC_RUN_ON(sequence_checker_);
   void UpdateControlState() RTC_RUN_ON(sequence_checker_);
   void UpdateCongestedState() RTC_RUN_ON(sequence_checker_);
-  absl::optional<bool> GetCongestedStateUpdate() const
+  std::optional<bool> GetCongestedStateUpdate() const
       RTC_RUN_ON(sequence_checker_);
 
   // Called by packet router just before packet is sent to the RTP modules.
diff --git a/call/rtp_transport_controller_send_interface.h b/call/rtp_transport_controller_send_interface.h
index aa71698..13eede6 100644
--- a/call/rtp_transport_controller_send_interface.h
+++ b/call/rtp_transport_controller_send_interface.h
@@ -15,11 +15,11 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/crypto/crypto_options.h"
 #include "api/fec_controller.h"
 #include "api/frame_transformer_interface.h"
@@ -138,7 +138,7 @@
   virtual void OnNetworkAvailability(bool network_available) = 0;
   virtual NetworkLinkRtcpObserver* GetRtcpObserver() = 0;
   virtual int64_t GetPacerQueuingDelayMs() const = 0;
-  virtual absl::optional<Timestamp> GetFirstPacketTime() const = 0;
+  virtual std::optional<Timestamp> GetFirstPacketTime() const = 0;
   virtual void EnablePeriodicAlrProbing(bool enable) = 0;
 
   // Called when a packet has been sent.
diff --git a/call/rtp_video_sender.cc b/call/rtp_video_sender.cc
index f7454ae..431e5c0 100644
--- a/call/rtp_video_sender.cc
+++ b/call/rtp_video_sender.cc
@@ -294,9 +294,9 @@
   return rtp_streams;
 }
 
-absl::optional<VideoCodecType> GetVideoCodecType(const RtpConfig& config) {
+std::optional<VideoCodecType> GetVideoCodecType(const RtpConfig& config) {
   if (config.raw_payload) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return PayloadStringToCodecType(config.payload_name);
 }
@@ -552,7 +552,7 @@
     RTPSenderVideo& sender_video = *rtp_streams_[simulcast_index].sender_video;
     if (codec_specific_info && codec_specific_info->template_structure) {
       sender_video.SetVideoStructure(&*codec_specific_info->template_structure);
-    } else if (absl::optional<FrameDependencyStructure> structure =
+    } else if (std::optional<FrameDependencyStructure> structure =
                    params_[simulcast_index].GenericStructure(
                        codec_specific_info)) {
       sender_video.SetVideoStructure(&*structure);
@@ -561,7 +561,7 @@
     }
   }
 
-  absl::optional<int64_t> frame_id;
+  std::optional<int64_t> frame_id;
   if (!independent_frame_ids_) {
     frame_id = shared_frame_id_;
   }
@@ -599,7 +599,7 @@
       // If spatial scalability is enabled, it is covered by a single stream.
       rtp_streams_[0].rtp_rtcp->SetVideoBitrateAllocation(bitrate);
     } else {
-      std::vector<absl::optional<VideoBitrateAllocation>> layer_bitrates =
+      std::vector<std::optional<VideoBitrateAllocation>> layer_bitrates =
           bitrate.GetSimulcastAllocations();
       // Simulcast is in use, split the VideoBitrateAllocation into one struct
       // per rtp stream, moving over the temporal layer allocation.
@@ -726,7 +726,7 @@
     // Only happens during shutdown, when RTP module is already inactive,
     // so OK to call fec generator here.
     if (rtp_streams_[i].fec_generator) {
-      absl::optional<RtpState> fec_state =
+      std::optional<RtpState> fec_state =
           rtp_streams_[i].fec_generator->GetRtpState();
       if (fec_state) {
         uint32_t ssrc = rtp_config_.flexfec.ssrc;
diff --git a/call/rtp_video_sender.h b/call/rtp_video_sender.h
index c35bc6f..3cb2e9e 100644
--- a/call/rtp_video_sender.h
+++ b/call/rtp_video_sender.h
@@ -13,10 +13,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <unordered_set>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/call/transport.h"
 #include "api/environment/environment.h"
@@ -182,7 +182,7 @@
   const std::vector<webrtc_internal_rtp_video_sender::RtpStreamSender>
       rtp_streams_;
   const RtpConfig rtp_config_;
-  const absl::optional<VideoCodecType> codec_type_;
+  const std::optional<VideoCodecType> codec_type_;
   RtpTransportControllerSendInterface* const transport_;
 
   // When using the generic descriptor we want all simulcast streams to share
diff --git a/call/rtp_video_sender_interface.h b/call/rtp_video_sender_interface.h
index 6bbcb7f..76f7de7 100644
--- a/call/rtp_video_sender_interface.h
+++ b/call/rtp_video_sender_interface.h
@@ -12,9 +12,9 @@
 #define CALL_RTP_VIDEO_SENDER_INTERFACE_H_
 
 #include <map>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/call/bitrate_allocation.h"
 #include "api/fec_controller_override.h"
diff --git a/call/rtp_video_sender_unittest.cc b/call/rtp_video_sender_unittest.cc
index d3959fb..98cd307 100644
--- a/call/rtp_video_sender_unittest.cc
+++ b/call/rtp_video_sender_unittest.cc
@@ -723,7 +723,7 @@
 
   // Send in delta frame.
   encoded_image._frameType = VideoFrameType::kVideoFrameDelta;
-  codec_specific.template_structure = absl::nullopt;
+  codec_specific.template_structure = std::nullopt;
   codec_specific.generic_frame_info =
       GenericFrameInfo::Builder().T(1).Dtis("D").Build();
   codec_specific.generic_frame_info->encoder_buffers = {{0, true, false}};
@@ -1000,7 +1000,7 @@
   EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
             EncodedImageCallback::Result::OK);
   // Send in 2nd spatial layer.
-  codec_specific.template_structure = absl::nullopt;
+  codec_specific.template_structure = std::nullopt;
   codec_specific.generic_frame_info =
       GenericFrameInfo::Builder().S(1).Dtis("-S").Build();
   codec_specific.generic_frame_info->encoder_buffers = {{0, true, false},
@@ -1164,7 +1164,7 @@
 
   // Send in a new key frame without the support for the dependency descriptor.
   encoded_image._frameType = VideoFrameType::kVideoFrameKey;
-  codec_specific.template_structure = absl::nullopt;
+  codec_specific.template_structure = std::nullopt;
   EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
             EncodedImageCallback::Result::OK);
   test.AdvanceTime(TimeDelta::Millis(33));
diff --git a/call/simulated_packet_receiver.h b/call/simulated_packet_receiver.h
index 2db46e8..e70937d 100644
--- a/call/simulated_packet_receiver.h
+++ b/call/simulated_packet_receiver.h
@@ -34,7 +34,7 @@
   // Returns the time until next process or nullopt to indicate that the next
   // process time is unknown. If the next process time is unknown, this should
   // be checked again any time a packet is enqueued.
-  virtual absl::optional<int64_t> TimeUntilNextProcess() = 0;
+  virtual std::optional<int64_t> TimeUntilNextProcess() = 0;
 };
 
 }  // namespace webrtc
diff --git a/call/syncable.h b/call/syncable.h
index 6817be9..09c0f22 100644
--- a/call/syncable.h
+++ b/call/syncable.h
@@ -16,7 +16,7 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
 
 namespace webrtc {
 
@@ -34,7 +34,7 @@
   virtual ~Syncable();
 
   virtual uint32_t id() const = 0;
-  virtual absl::optional<Info> GetInfo() const = 0;
+  virtual std::optional<Info> GetInfo() const = 0;
   virtual bool GetPlayoutRtpTimestamp(uint32_t* rtp_timestamp,
                                       int64_t* time_ms) const = 0;
   virtual bool SetMinimumPlayoutDelay(int delay_ms) = 0;
diff --git a/call/test/mock_rtp_transport_controller_send.h b/call/test/mock_rtp_transport_controller_send.h
index d1e1d64..84caccf 100644
--- a/call/test/mock_rtp_transport_controller_send.h
+++ b/call/test/mock_rtp_transport_controller_send.h
@@ -86,7 +86,7 @@
   MOCK_METHOD(void, OnNetworkAvailability, (bool), (override));
   MOCK_METHOD(NetworkLinkRtcpObserver*, GetRtcpObserver, (), (override));
   MOCK_METHOD(int64_t, GetPacerQueuingDelayMs, (), (const, override));
-  MOCK_METHOD(absl::optional<Timestamp>,
+  MOCK_METHOD(std::optional<Timestamp>,
               GetFirstPacketTime,
               (),
               (const, override));
diff --git a/call/video_receive_stream.h b/call/video_receive_stream.h
index 4bdf81f..23cf035 100644
--- a/call/video_receive_stream.h
+++ b/call/video_receive_stream.h
@@ -55,7 +55,7 @@
     std::function<void(const RecordableEncodedFrame&)> callback;
     // Memento of when a keyframe request was last sent. The
     // VideoReceiveStreamInterface client should not interpret the attribute.
-    absl::optional<int64_t> last_keyframe_request_ms;
+    std::optional<int64_t> last_keyframe_request_ms;
   };
 
   // TODO(mflodman) Move all these settings to VideoDecoder and move the
@@ -88,8 +88,8 @@
     uint32_t frames_rendered = 0;
 
     // Decoder stats.
-    absl::optional<std::string> decoder_implementation_name;
-    absl::optional<bool> power_efficient_decoder;
+    std::optional<std::string> decoder_implementation_name;
+    std::optional<bool> power_efficient_decoder;
     FrameCounts frame_counts;
     int decode_ms = 0;
     int max_decode_ms = 0;
@@ -127,7 +127,7 @@
     // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totalsqauredinterframedelay
     double total_squared_inter_frame_delay = 0;
     int64_t first_frame_received_to_decoded_ms = -1;
-    absl::optional<uint64_t> qp_sum;
+    std::optional<uint64_t> qp_sum;
 
     // TODO(webrtc:357636606): Propagate this score upwards in the chain.
     // Corruption score, indicating the probability of corruption. Its value is
@@ -136,8 +136,8 @@
     // However, note that the corruption score may not accurately reflect
     // corruption. E.g. even if the corruption score is 0, the compressed frame
     // may still be corrupted and vice versa.
-    absl::optional<double> corruption_score_sum;
-    absl::optional<double> corruption_score_squared_sum;
+    std::optional<double> corruption_score_sum;
+    std::optional<double> corruption_score_squared_sum;
     // Number of frames the `corruption_score` was calculated on. This is
     // usually not the same as `frames_decoded`.
     uint32_t corruption_score_count = 0;
@@ -157,23 +157,23 @@
     VideoContentType content_type = VideoContentType::UNSPECIFIED;
 
     // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-estimatedplayouttimestamp
-    absl::optional<int64_t> estimated_playout_ntp_timestamp_ms;
+    std::optional<int64_t> estimated_playout_ntp_timestamp_ms;
     int sync_offset_ms = std::numeric_limits<int>::max();
 
     uint32_t ssrc = 0;
     std::string c_name;
     RtpReceiveStats rtp_stats;
     RtcpPacketTypeCounter rtcp_packet_type_counts;
-    absl::optional<RtpReceiveStats> rtx_rtp_stats;
+    std::optional<RtpReceiveStats> rtx_rtp_stats;
 
     // Timing frame info: all important timestamps for a full lifetime of a
     // single 'timing frame'.
-    absl::optional<webrtc::TimingFrameInfo> timing_frame_info;
+    std::optional<webrtc::TimingFrameInfo> timing_frame_info;
 
     // Remote outbound stats derived by the received RTCP sender reports.
     // https://w3c.github.io/webrtc-stats/#remoteoutboundrtpstats-dict*
-    absl::optional<int64_t> last_sender_report_timestamp_ms;
-    absl::optional<int64_t> last_sender_report_remote_timestamp_ms;
+    std::optional<int64_t> last_sender_report_timestamp_ms;
+    std::optional<int64_t> last_sender_report_remote_timestamp_ms;
     uint32_t sender_reports_packets_sent = 0;
     uint64_t sender_reports_bytes_sent = 0;
     uint64_t sender_reports_reports_count = 0;
diff --git a/call/video_send_stream.h b/call/video_send_stream.h
index 2c3fe55..bd22096 100644
--- a/call/video_send_stream.h
+++ b/call/video_send_stream.h
@@ -14,10 +14,10 @@
 #include <stdint.h>
 
 #include <map>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/adaptation/resource.h"
 #include "api/call/transport.h"
 #include "api/crypto/crypto_options.h"
@@ -72,7 +72,7 @@
     // If `type` is kRtx or kFlexfec this value is present. The referenced SSRC
     // is the kMedia stream that this stream is performing retransmissions or
     // FEC for. If `type` is kMedia, this value is null.
-    absl::optional<uint32_t> referenced_media_ssrc;
+    std::optional<uint32_t> referenced_media_ssrc;
     FrameCounts frame_counts;
     int width = 0;
     int height = 0;
@@ -87,21 +87,21 @@
     RtcpPacketTypeCounter rtcp_packet_type_counts;
     // A snapshot of the most recent Report Block with additional data of
     // interest to statistics. Used to implement RTCRemoteInboundRtpStreamStats.
-    absl::optional<ReportBlockData> report_block_data;
+    std::optional<ReportBlockData> report_block_data;
     double encode_frame_rate = 0.0;
     int frames_encoded = 0;
-    absl::optional<uint64_t> qp_sum;
+    std::optional<uint64_t> qp_sum;
     uint64_t total_encode_time_ms = 0;
     uint64_t total_encoded_bytes_target = 0;
     uint32_t huge_frames_sent = 0;
-    absl::optional<ScalabilityMode> scalability_mode;
+    std::optional<ScalabilityMode> scalability_mode;
   };
 
   struct Stats {
     Stats();
     ~Stats();
     std::string ToString(int64_t time_ms) const;
-    absl::optional<std::string> encoder_implementation_name;
+    std::optional<std::string> encoder_implementation_name;
     double input_frame_rate = 0;
     int encode_frame_rate = 0;
     int avg_encode_time_ms = 0;
@@ -145,7 +145,7 @@
         webrtc::VideoContentType::UNSPECIFIED;
     uint32_t frames_sent = 0;
     uint32_t huge_frames_sent = 0;
-    absl::optional<bool> power_efficient_encoder;
+    std::optional<bool> power_efficient_encoder;
   };
 
   struct Config {
diff --git a/common_audio/BUILD.gn b/common_audio/BUILD.gn
index 3603fdf..3d1688f 100644
--- a/common_audio/BUILD.gn
+++ b/common_audio/BUILD.gn
@@ -58,7 +58,6 @@
     "../rtc_base/system:file_wrapper",
     "../system_wrappers",
     "third_party/ooura:fft_size_256",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 
   defines = []
diff --git a/common_audio/mocks/mock_smoothing_filter.h b/common_audio/mocks/mock_smoothing_filter.h
index 9df49dd..0296659 100644
--- a/common_audio/mocks/mock_smoothing_filter.h
+++ b/common_audio/mocks/mock_smoothing_filter.h
@@ -19,7 +19,7 @@
 class MockSmoothingFilter : public SmoothingFilter {
  public:
   MOCK_METHOD(void, AddSample, (float), (override));
-  MOCK_METHOD(absl::optional<float>, GetAverage, (), (override));
+  MOCK_METHOD(std::optional<float>, GetAverage, (), (override));
   MOCK_METHOD(bool, SetTimeConstantMs, (int), (override));
 };
 
diff --git a/common_audio/smoothing_filter.cc b/common_audio/smoothing_filter.cc
index eaaf3a0..1c603f6 100644
--- a/common_audio/smoothing_filter.cc
+++ b/common_audio/smoothing_filter.cc
@@ -55,10 +55,10 @@
   last_sample_ = sample;
 }
 
-absl::optional<float> SmoothingFilterImpl::GetAverage() {
+std::optional<float> SmoothingFilterImpl::GetAverage() {
   if (!init_end_time_ms_) {
     // `init_end_time_ms_` undefined since we have not received any sample.
-    return absl::nullopt;
+    return std::nullopt;
   }
   ExtrapolateLastSample(rtc::TimeMillis());
   return state_;
diff --git a/common_audio/smoothing_filter.h b/common_audio/smoothing_filter.h
index 3419de7..488cc97 100644
--- a/common_audio/smoothing_filter.h
+++ b/common_audio/smoothing_filter.h
@@ -13,7 +13,7 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
 
 namespace webrtc {
 
@@ -21,7 +21,7 @@
  public:
   virtual ~SmoothingFilter() = default;
   virtual void AddSample(float sample) = 0;
-  virtual absl::optional<float> GetAverage() = 0;
+  virtual std::optional<float> GetAverage() = 0;
   virtual bool SetTimeConstantMs(int time_constant_ms) = 0;
 };
 
@@ -49,7 +49,7 @@
   ~SmoothingFilterImpl() override;
 
   void AddSample(float sample) override;
-  absl::optional<float> GetAverage() override;
+  std::optional<float> GetAverage() override;
   bool SetTimeConstantMs(int time_constant_ms) override;
 
   // Methods used for unittests.
@@ -63,7 +63,7 @@
   const float init_factor_;
   const float init_const_;
 
-  absl::optional<int64_t> init_end_time_ms_;
+  std::optional<int64_t> init_end_time_ms_;
   float last_sample_;
   float alpha_;
   float state_;
diff --git a/common_video/BUILD.gn b/common_video/BUILD.gn
index 73a8adb..0270646 100644
--- a/common_video/BUILD.gn
+++ b/common_video/BUILD.gn
@@ -88,7 +88,6 @@
     "../system_wrappers:metrics",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
     "//third_party/abseil-cpp/absl/numeric:bits",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/libyuv",
   ]
   if (rtc_use_h265) {
@@ -164,7 +163,6 @@
       "../test:test_support",
       "../test:video_test_common",
       "//testing/gtest",
-      "//third_party/abseil-cpp/absl/types:optional",
       "//third_party/libyuv",
     ]
 
diff --git a/common_video/bitrate_adjuster.cc b/common_video/bitrate_adjuster.cc
index c53c3a0..4053696 100644
--- a/common_video/bitrate_adjuster.cc
+++ b/common_video/bitrate_adjuster.cc
@@ -67,7 +67,7 @@
   return adjusted_bitrate_bps_;
 }
 
-absl::optional<uint32_t> BitrateAdjuster::GetEstimatedBitrateBps() {
+std::optional<uint32_t> BitrateAdjuster::GetEstimatedBitrateBps() {
   MutexLock lock(&mutex_);
   return bitrate_tracker_.Rate(rtc::TimeMillis());
 }
diff --git a/common_video/corruption_detection_message.h b/common_video/corruption_detection_message.h
index b6572c9..5fa2aed 100644
--- a/common_video/corruption_detection_message.h
+++ b/common_video/corruption_detection_message.h
@@ -12,9 +12,9 @@
 #define COMMON_VIDEO_CORRUPTION_DETECTION_MESSAGE_H_
 
 #include <cstddef>
+#include <optional>
 
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 
 namespace webrtc {
@@ -84,28 +84,28 @@
 
   ~Builder() = default;
 
-  absl::optional<CorruptionDetectionMessage> Build() {
+  std::optional<CorruptionDetectionMessage> Build() {
     if (message_.sequence_index_ < 0 ||
         message_.sequence_index_ > 0b0111'1111) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (message_.std_dev_ < 0.0 || message_.std_dev_ > 40.0) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (message_.luma_error_threshold_ < 0 ||
         message_.luma_error_threshold_ > 15) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (message_.chroma_error_threshold_ < 0 ||
         message_.chroma_error_threshold_ > 15) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (message_.sample_values_.size() > kMaxSampleSize) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     for (double sample_value : message_.sample_values_) {
       if (sample_value < 0.0 || sample_value > 255.0) {
-        return absl::nullopt;
+        return std::nullopt;
       }
     }
     return message_;
diff --git a/common_video/corruption_detection_message_unittest.cc b/common_video/corruption_detection_message_unittest.cc
index ee11161..4bb47ce 100644
--- a/common_video/corruption_detection_message_unittest.cc
+++ b/common_video/corruption_detection_message_unittest.cc
@@ -10,9 +10,9 @@
 
 #include "common_video/corruption_detection_message.h"
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "test/gtest.h"
 
 namespace webrtc {
@@ -22,36 +22,36 @@
   EXPECT_EQ(CorruptionDetectionMessage::Builder()
                 .WithSequenceIndex(0b1000'0000)
                 .Build(),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(CorruptionDetectionMessageTest, FailsToCreateWhenSequenceIndexIsTooSmall) {
   EXPECT_EQ(CorruptionDetectionMessage::Builder().WithSequenceIndex(-1).Build(),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(CorruptionDetectionMessageTest, FailsToCreateWhenStddevIsTooLarge) {
   EXPECT_EQ(CorruptionDetectionMessage::Builder().WithStdDev(45.0).Build(),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(CorruptionDetectionMessageTest, FailsToCreateWhenStddevIsTooSmall) {
   EXPECT_EQ(CorruptionDetectionMessage::Builder().WithStdDev(-1.0).Build(),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(CorruptionDetectionMessageTest,
      FailsToCreateWhenLumaErrorThresholdIsTooLarge) {
   EXPECT_EQ(
       CorruptionDetectionMessage::Builder().WithLumaErrorThreshold(16).Build(),
-      absl::nullopt);
+      std::nullopt);
 }
 
 TEST(CorruptionDetectionMessageTest,
      FailsToCreateWhenLumaErrorThresholdIsTooSmall) {
   EXPECT_EQ(
       CorruptionDetectionMessage::Builder().WithLumaErrorThreshold(-1).Build(),
-      absl::nullopt);
+      std::nullopt);
 }
 
 TEST(CorruptionDetectionMessageTest,
@@ -59,7 +59,7 @@
   EXPECT_EQ(CorruptionDetectionMessage::Builder()
                 .WithChromaErrorThreshold(16)
                 .Build(),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(CorruptionDetectionMessageTest,
@@ -67,7 +67,7 @@
   EXPECT_EQ(CorruptionDetectionMessage::Builder()
                 .WithChromaErrorThreshold(-1)
                 .Build(),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(CorruptionDetectionMessageTest,
@@ -79,7 +79,7 @@
   EXPECT_EQ(CorruptionDetectionMessage::Builder()
                 .WithSampleValues(kSampleValues)
                 .Build(),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(CorruptionDetectionMessageTest, FailsToCreateWhenSampleValueIsTooLarge) {
@@ -88,7 +88,7 @@
   EXPECT_EQ(CorruptionDetectionMessage::Builder()
                 .WithSampleValues(kSampleValues)
                 .Build(),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(CorruptionDetectionMessageTest, FailsToCreateWhenSampleValueIsTooSmall) {
@@ -97,12 +97,12 @@
   EXPECT_EQ(CorruptionDetectionMessage::Builder()
                 .WithSampleValues(kSampleValues)
                 .Build(),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(CorruptionDetectionMessageTest,
      CreatesDefaultWhenNoParametersAreSpecified) {
-  EXPECT_NE(CorruptionDetectionMessage::Builder().Build(), absl::nullopt);
+  EXPECT_NE(CorruptionDetectionMessage::Builder().Build(), std::nullopt);
 }
 
 TEST(CorruptionDetectionMessageTest, CreatesWhenValidParametersAreSpecified) {
@@ -117,7 +117,7 @@
                 .WithChromaErrorThreshold(15)
                 .WithSampleValues(kSampleValues)
                 .Build(),
-            absl::nullopt);
+            std::nullopt);
 }
 
 }  // namespace
diff --git a/common_video/frame_rate_estimator.cc b/common_video/frame_rate_estimator.cc
index 4c5a341..2ac7aee 100644
--- a/common_video/frame_rate_estimator.cc
+++ b/common_video/frame_rate_estimator.cc
@@ -22,13 +22,13 @@
   frame_times_.push_back(time);
 }
 
-absl::optional<double> FrameRateEstimator::GetAverageFps() const {
+std::optional<double> FrameRateEstimator::GetAverageFps() const {
   if (frame_times_.size() < 2) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   TimeDelta time_span = frame_times_.back() - frame_times_.front();
   if (time_span < TimeDelta::Micros(1)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   TimeDelta avg_frame_interval = time_span / (frame_times_.size() - 1);
 
@@ -36,7 +36,7 @@
          avg_frame_interval.us();
 }
 
-absl::optional<double> FrameRateEstimator::GetAverageFps(Timestamp now) {
+std::optional<double> FrameRateEstimator::GetAverageFps(Timestamp now) {
   CullOld(now);
   return GetAverageFps();
 }
diff --git a/common_video/frame_rate_estimator.h b/common_video/frame_rate_estimator.h
index 95219a5..55e6e20 100644
--- a/common_video/frame_rate_estimator.h
+++ b/common_video/frame_rate_estimator.h
@@ -12,8 +12,8 @@
 #define COMMON_VIDEO_FRAME_RATE_ESTIMATOR_H_
 
 #include <deque>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
 
@@ -41,10 +41,10 @@
   void OnFrame(Timestamp time);
 
   // Get the current average FPS, based on the frames currently in the window.
-  absl::optional<double> GetAverageFps() const;
+  std::optional<double> GetAverageFps() const;
 
   // Move the window so it ends at `now`, and return the new fps estimate.
-  absl::optional<double> GetAverageFps(Timestamp now);
+  std::optional<double> GetAverageFps(Timestamp now);
 
   // Completely clear the averaging window.
   void Reset();
diff --git a/common_video/framerate_controller.cc b/common_video/framerate_controller.cc
index 23e9c70..4e2e0b8 100644
--- a/common_video/framerate_controller.cc
+++ b/common_video/framerate_controller.cc
@@ -71,7 +71,7 @@
 
 void FramerateController::Reset() {
   max_framerate_ = std::numeric_limits<double>::max();
-  next_frame_timestamp_ns_ = absl::nullopt;
+  next_frame_timestamp_ns_ = std::nullopt;
 }
 
 void FramerateController::KeepFrame(int64_t in_timestamp_ns) {
diff --git a/common_video/framerate_controller.h b/common_video/framerate_controller.h
index 371ffd4..44e2e67 100644
--- a/common_video/framerate_controller.h
+++ b/common_video/framerate_controller.h
@@ -13,7 +13,7 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
 
 namespace webrtc {
 
@@ -38,7 +38,7 @@
 
  private:
   double max_framerate_;
-  absl::optional<int64_t> next_frame_timestamp_ns_;
+  std::optional<int64_t> next_frame_timestamp_ns_;
 };
 
 }  // namespace webrtc
diff --git a/common_video/h264/h264_bitstream_parser.cc b/common_video/h264/h264_bitstream_parser.cc
index 5c0ebb8..96be4c8 100644
--- a/common_video/h264/h264_bitstream_parser.cc
+++ b/common_video/h264/h264_bitstream_parser.cc
@@ -36,7 +36,7 @@
   if (!sps_ || !pps_)
     return kInvalidStream;
 
-  last_slice_qp_delta_ = absl::nullopt;
+  last_slice_qp_delta_ = std::nullopt;
   const std::vector<uint8_t> slice_rbsp = H264::ParseRbsp(source);
   if (slice_rbsp.size() < H264::kNaluTypeSize)
     return kInvalidStream;
@@ -344,13 +344,13 @@
         bitstream.subview(index.payload_start_offset, index.payload_size));
 }
 
-absl::optional<int> H264BitstreamParser::GetLastSliceQp() const {
+std::optional<int> H264BitstreamParser::GetLastSliceQp() const {
   if (!last_slice_qp_delta_ || !pps_)
-    return absl::nullopt;
+    return std::nullopt;
   const int qp = 26 + pps_->pic_init_qp_minus26 + *last_slice_qp_delta_;
   if (qp < kMinQpValue || qp > kMaxQpValue) {
     RTC_LOG(LS_ERROR) << "Parsed invalid QP from bitstream.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return qp;
 }
diff --git a/common_video/h264/h264_bitstream_parser.h b/common_video/h264/h264_bitstream_parser.h
index 1fad989..5b605b5 100644
--- a/common_video/h264/h264_bitstream_parser.h
+++ b/common_video/h264/h264_bitstream_parser.h
@@ -13,7 +13,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/video_codecs/bitstream_parser.h"
 #include "common_video/h264/pps_parser.h"
 #include "common_video/h264/sps_parser.h"
@@ -32,7 +33,7 @@
   ~H264BitstreamParser() override;
 
   void ParseBitstream(rtc::ArrayView<const uint8_t> bitstream) override;
-  absl::optional<int> GetLastSliceQp() const override;
+  std::optional<int> GetLastSliceQp() const override;
 
  protected:
   enum Result {
@@ -45,11 +46,11 @@
                                   uint8_t nalu_type);
 
   // SPS/PPS state, updated when parsing new SPS/PPS, used to parse slices.
-  absl::optional<SpsParser::SpsState> sps_;
-  absl::optional<PpsParser::PpsState> pps_;
+  std::optional<SpsParser::SpsState> sps_;
+  std::optional<PpsParser::PpsState> pps_;
 
   // Last parsed slice QP.
-  absl::optional<int32_t> last_slice_qp_delta_;
+  std::optional<int32_t> last_slice_qp_delta_;
 };
 
 }  // namespace webrtc
diff --git a/common_video/h264/h264_bitstream_parser_unittest.cc b/common_video/h264/h264_bitstream_parser_unittest.cc
index e03da7a..00186a6 100644
--- a/common_video/h264/h264_bitstream_parser_unittest.cc
+++ b/common_video/h264/h264_bitstream_parser_unittest.cc
@@ -122,7 +122,7 @@
 TEST(H264BitstreamParserTest, ReportsLastSliceQpForImageSlices) {
   H264BitstreamParser h264_parser;
   h264_parser.ParseBitstream(kH264BitstreamChunk);
-  absl::optional<int> qp = h264_parser.GetLastSliceQp();
+  std::optional<int> qp = h264_parser.GetLastSliceQp();
   ASSERT_TRUE(qp.has_value());
   EXPECT_EQ(35, *qp);
 
@@ -140,7 +140,7 @@
 
   // Parse an additional image slice.
   h264_parser.ParseBitstream(kH264BitstreamNextImageSliceChunkCabac);
-  absl::optional<int> qp = h264_parser.GetLastSliceQp();
+  std::optional<int> qp = h264_parser.GetLastSliceQp();
   ASSERT_TRUE(qp.has_value());
   EXPECT_EQ(24, *qp);
 }
@@ -149,14 +149,14 @@
   H264BitstreamParser h264_parser;
   h264_parser.ParseBitstream(kH264BitstreamWeightedPred);
 
-  absl::optional<int> qp = h264_parser.GetLastSliceQp();
+  std::optional<int> qp = h264_parser.GetLastSliceQp();
   ASSERT_TRUE(qp.has_value());
   EXPECT_EQ(11, *qp);
 }
 
 TEST(H264BitstreamParserTest, ReportsLastSliceQpForWeightedPredSlicesL0Active) {
   H264BitstreamParser h264_parser;
-  absl::optional<int> qp;
+  std::optional<int> qp;
   h264_parser.ParseBitstream(H264BitstreamCVWP1SPS);
 
   h264_parser.ParseBitstream(H264BitstreamCVWP1PFrame1);
@@ -182,7 +182,7 @@
 
 TEST(H264BitstreamParserTest, ReportsLastSliceQpForWeightedPredSlicesL1Active) {
   H264BitstreamParser h264_parser;
-  absl::optional<int> qp;
+  std::optional<int> qp;
   h264_parser.ParseBitstream(H264BitstreamCVWP2SPS);
 
   h264_parser.ParseBitstream(H264BitstreamCVWP2BFrame1);
diff --git a/common_video/h264/pps_parser.cc b/common_video/h264/pps_parser.cc
index f12ab9b..2518765 100644
--- a/common_video/h264/pps_parser.cc
+++ b/common_video/h264/pps_parser.cc
@@ -29,7 +29,7 @@
 // You can find it on this page:
 // http://www.itu.int/rec/T-REC-H.264
 
-absl::optional<PpsParser::PpsState> PpsParser::ParsePps(
+std::optional<PpsParser::PpsState> PpsParser::ParsePps(
     rtc::ArrayView<const uint8_t> data) {
   // First, parse out rbsp, which is basically the source buffer minus emulation
   // bytes (the last byte of a 0x00 0x00 0x03 sequence). RBSP is defined in
@@ -52,7 +52,7 @@
   return reader.Ok();
 }
 
-absl::optional<PpsParser::SliceHeader> PpsParser::ParseSliceHeader(
+std::optional<PpsParser::SliceHeader> PpsParser::ParseSliceHeader(
     rtc::ArrayView<const uint8_t> data) {
   std::vector<uint8_t> unpacked_buffer = H264::ParseRbsp(data);
   BitstreamReader slice_reader(unpacked_buffer);
@@ -68,12 +68,12 @@
   // The rest of the slice header requires information from the SPS to parse.
 
   if (!slice_reader.Ok()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return slice_header;
 }
 
-absl::optional<PpsParser::PpsState> PpsParser::ParseInternal(
+std::optional<PpsParser::PpsState> PpsParser::ParseInternal(
     rtc::ArrayView<const uint8_t> buffer) {
   BitstreamReader reader(buffer);
   PpsState pps;
@@ -123,7 +123,7 @@
       int64_t bits_to_consume =
           int64_t{slice_group_id_bits} * pic_size_in_map_units;
       if (!reader.Ok() || bits_to_consume > std::numeric_limits<int>::max()) {
-        return absl::nullopt;
+        return std::nullopt;
       }
       reader.ConsumeBits(bits_to_consume);
     }
@@ -134,7 +134,7 @@
   pps.num_ref_idx_l1_default_active_minus1 = reader.ReadExponentialGolomb();
   if (pps.num_ref_idx_l0_default_active_minus1 > H264::kMaxReferenceIndex ||
       pps.num_ref_idx_l1_default_active_minus1 > H264::kMaxReferenceIndex) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   // weighted_pred_flag: u(1)
   pps.weighted_pred_flag = reader.Read<bool>();
@@ -146,7 +146,7 @@
   // Sanity-check parsed value
   if (!reader.Ok() || pps.pic_init_qp_minus26 > kMaxPicInitQpDeltaValue ||
       pps.pic_init_qp_minus26 < kMinPicInitQpDeltaValue) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   // pic_init_qs_minus26: se(v)
   reader.ReadExponentialGolomb();
@@ -158,7 +158,7 @@
   // redundant_pic_cnt_present_flag: u(1)
   pps.redundant_pic_cnt_present_flag = reader.ReadBit();
   if (!reader.Ok()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return pps;
diff --git a/common_video/h264/pps_parser.h b/common_video/h264/pps_parser.h
index d2d0609..e4207d7 100644
--- a/common_video/h264/pps_parser.h
+++ b/common_video/h264/pps_parser.h
@@ -14,7 +14,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/array_view.h"
 
 namespace webrtc {
@@ -47,10 +48,10 @@
   };
 
   // Unpack RBSP and parse PPS state from the supplied buffer.
-  static absl::optional<PpsState> ParsePps(rtc::ArrayView<const uint8_t> data);
+  static std::optional<PpsState> ParsePps(rtc::ArrayView<const uint8_t> data);
   // TODO: bugs.webrtc.org/42225170 - Deprecate.
-  static inline absl::optional<PpsState> ParsePps(const uint8_t* data,
-                                                  size_t length) {
+  static inline std::optional<PpsState> ParsePps(const uint8_t* data,
+                                                 size_t length) {
     return ParsePps(rtc::MakeArrayView(data, length));
   }
 
@@ -58,13 +59,13 @@
                           uint32_t* pps_id,
                           uint32_t* sps_id);
 
-  static absl::optional<SliceHeader> ParseSliceHeader(
+  static std::optional<SliceHeader> ParseSliceHeader(
       rtc::ArrayView<const uint8_t> data);
 
  protected:
   // Parse the PPS state, for a buffer where RBSP decoding has already been
   // performed.
-  static absl::optional<PpsState> ParseInternal(
+  static std::optional<PpsState> ParseInternal(
       rtc::ArrayView<const uint8_t> buffer);
 };
 
diff --git a/common_video/h264/pps_parser_unittest.cc b/common_video/h264/pps_parser_unittest.cc
index a325e8c..ea8c8ed 100644
--- a/common_video/h264/pps_parser_unittest.cc
+++ b/common_video/h264/pps_parser_unittest.cc
@@ -196,7 +196,7 @@
 
   PpsParser::PpsState generated_pps_;
   rtc::Buffer buffer_;
-  absl::optional<PpsParser::PpsState> parsed_pps_;
+  std::optional<PpsParser::PpsState> parsed_pps_;
 };
 
 TEST_F(PpsParserTest, ZeroPps) {
@@ -227,7 +227,7 @@
         H264::ParseNaluType(chunk[index.payload_start_offset]);
     if (nalu_type == H264::NaluType::kIdr) {
       // Skip NAL type header and parse slice header.
-      absl::optional<PpsParser::SliceHeader> slice_header =
+      std::optional<PpsParser::SliceHeader> slice_header =
           PpsParser::ParseSliceHeader(chunk.subview(
               index.payload_start_offset + 1, index.payload_size - 1));
       ASSERT_TRUE(slice_header.has_value());
diff --git a/common_video/h264/sps_parser.cc b/common_video/h264/sps_parser.cc
index 000e028..936080e 100644
--- a/common_video/h264/sps_parser.cc
+++ b/common_video/h264/sps_parser.cc
@@ -32,14 +32,14 @@
 // http://www.itu.int/rec/T-REC-H.264
 
 // Unpack RBSP and parse SPS state from the supplied buffer.
-absl::optional<SpsParser::SpsState> SpsParser::ParseSps(
+std::optional<SpsParser::SpsState> SpsParser::ParseSps(
     rtc::ArrayView<const uint8_t> data) {
   std::vector<uint8_t> unpacked_buffer = H264::ParseRbsp(data);
   BitstreamReader reader(unpacked_buffer);
   return ParseSpsUpToVui(reader);
 }
 
-absl::optional<SpsParser::SpsState> SpsParser::ParseSpsUpToVui(
+std::optional<SpsParser::SpsState> SpsParser::ParseSpsUpToVui(
     BitstreamReader& reader) {
   // Now, we need to use a bitstream reader to parse through the actual AVC SPS
   // format. See Section 7.3.2.1.1 ("Sequence parameter set data syntax") of the
@@ -102,7 +102,7 @@
               int delta_scale = reader.ReadSignedExponentialGolomb();
               if (!reader.Ok() || delta_scale < kScalingDeltaMin ||
                   delta_scale > kScaldingDeltaMax) {
-                return absl::nullopt;
+                return std::nullopt;
               }
               next_scale = (last_scale + delta_scale + 256) % 256;
             }
@@ -122,7 +122,7 @@
   // log2_max_frame_num_minus4: ue(v)
   uint32_t log2_max_frame_num_minus4 = reader.ReadExponentialGolomb();
   if (!reader.Ok() || log2_max_frame_num_minus4 > kMaxLog2Minus4) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   sps.log2_max_frame_num = log2_max_frame_num_minus4 + 4;
 
@@ -132,7 +132,7 @@
     // log2_max_pic_order_cnt_lsb_minus4: ue(v)
     uint32_t log2_max_pic_order_cnt_lsb_minus4 = reader.ReadExponentialGolomb();
     if (!reader.Ok() || log2_max_pic_order_cnt_lsb_minus4 > kMaxLog2Minus4) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     sps.log2_max_pic_order_cnt_lsb = log2_max_pic_order_cnt_lsb_minus4 + 4;
   } else if (sps.pic_order_cnt_type == 1) {
@@ -149,7 +149,7 @@
       // offset_for_ref_frame[i]: se(v)
       reader.ReadExponentialGolomb();
       if (!reader.Ok()) {
-        return absl::nullopt;
+        return std::nullopt;
       }
     }
   }
@@ -197,7 +197,7 @@
 
   // Far enough! We don't use the rest of the SPS.
   if (!reader.Ok()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Figure out the crop units in pixels. That's based on the chroma format's
diff --git a/common_video/h264/sps_parser.h b/common_video/h264/sps_parser.h
index ae8df60..7347e6d 100644
--- a/common_video/h264/sps_parser.h
+++ b/common_video/h264/sps_parser.h
@@ -11,7 +11,8 @@
 #ifndef COMMON_VIDEO_H264_SPS_PARSER_H_
 #define COMMON_VIDEO_H264_SPS_PARSER_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "rtc_base/bitstream_reader.h"
 #include "rtc_base/system/rtc_export.h"
 
@@ -42,17 +43,17 @@
   };
 
   // Unpack RBSP and parse SPS state from the supplied buffer.
-  static absl::optional<SpsState> ParseSps(rtc::ArrayView<const uint8_t> data);
+  static std::optional<SpsState> ParseSps(rtc::ArrayView<const uint8_t> data);
   // TODO: bugs.webrtc.org/42225170 - Deprecate.
-  static inline absl::optional<SpsState> ParseSps(const uint8_t* data,
-                                                  size_t length) {
+  static inline std::optional<SpsState> ParseSps(const uint8_t* data,
+                                                 size_t length) {
     return ParseSps(rtc::MakeArrayView(data, length));
   }
 
  protected:
   // Parse the SPS state, up till the VUI part, for a buffer where RBSP
   // decoding has already been performed.
-  static absl::optional<SpsState> ParseSpsUpToVui(BitstreamReader& reader);
+  static std::optional<SpsState> ParseSpsUpToVui(BitstreamReader& reader);
 };
 
 }  // namespace webrtc
diff --git a/common_video/h264/sps_parser_unittest.cc b/common_video/h264/sps_parser_unittest.cc
index 721aa3f..6904e8e 100644
--- a/common_video/h264/sps_parser_unittest.cc
+++ b/common_video/h264/sps_parser_unittest.cc
@@ -116,7 +116,7 @@
   const uint8_t buffer[] = {0x7A, 0x00, 0x1F, 0xBC, 0xD9, 0x40, 0x50, 0x05,
                             0xBA, 0x10, 0x00, 0x00, 0x03, 0x00, 0xC0, 0x00,
                             0x00, 0x2A, 0xE0, 0xF1, 0x83, 0x19, 0x60};
-  absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
+  std::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(1280u, sps->width);
   EXPECT_EQ(720u, sps->height);
@@ -128,7 +128,7 @@
   const uint8_t buffer[] = {0x7A, 0x00, 0x1E, 0xBC, 0xD9, 0x40, 0xA0, 0x2F,
                             0xF8, 0x98, 0x40, 0x00, 0x00, 0x03, 0x01, 0x80,
                             0x00, 0x00, 0x56, 0x83, 0xC5, 0x8B, 0x65, 0x80};
-  absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
+  std::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(640u, sps->width);
   EXPECT_EQ(360u, sps->height);
@@ -140,7 +140,7 @@
   const uint8_t buffer[] = {0x7A, 0x00, 0x0D, 0xBC, 0xD9, 0x43, 0x43, 0x3E,
                             0x5E, 0x10, 0x00, 0x00, 0x03, 0x00, 0x60, 0x00,
                             0x00, 0x15, 0xA0, 0xF1, 0x42, 0x99, 0x60};
-  absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
+  std::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(200u, sps->width);
   EXPECT_EQ(400u, sps->height);
@@ -149,7 +149,7 @@
 TEST(H264SpsParserTest, TestSyntheticSPSQvgaLandscape) {
   rtc::Buffer buffer;
   GenerateFakeSps(320u, 180u, 1, 0, 0, &buffer);
-  absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
+  std::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(320u, sps->width);
   EXPECT_EQ(180u, sps->height);
@@ -159,7 +159,7 @@
 TEST(H264SpsParserTest, TestSyntheticSPSWeirdResolution) {
   rtc::Buffer buffer;
   GenerateFakeSps(156u, 122u, 2, 0, 0, &buffer);
-  absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
+  std::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(156u, sps->width);
   EXPECT_EQ(122u, sps->height);
@@ -173,7 +173,7 @@
                             0x10, 0xc2, 0x00, 0x84, 0x3b, 0x50, 0x3c, 0x01,
                             0x13, 0xf2, 0xcd, 0xc0, 0x40, 0x40, 0x50, 0x00,
                             0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xe8, 0x40};
-  absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
+  std::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(1920u, sps->width);
   EXPECT_EQ(1080u, sps->height);
@@ -182,7 +182,7 @@
 TEST(H264SpsParserTest, TestLog2MaxFrameNumMinus4) {
   rtc::Buffer buffer;
   GenerateFakeSps(320u, 180u, 1, 0, 0, &buffer);
-  absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
+  std::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(320u, sps->width);
   EXPECT_EQ(180u, sps->height);
@@ -204,7 +204,7 @@
 TEST(H264SpsParserTest, TestLog2MaxPicOrderCntMinus4) {
   rtc::Buffer buffer;
   GenerateFakeSps(320u, 180u, 1, 0, 0, &buffer);
-  absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
+  std::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(320u, sps->width);
   EXPECT_EQ(180u, sps->height);
diff --git a/common_video/h264/sps_vui_rewriter.cc b/common_video/h264/sps_vui_rewriter.cc
index fa824a5..236ecb8 100644
--- a/common_video/h264/sps_vui_rewriter.cc
+++ b/common_video/h264/sps_vui_rewriter.cc
@@ -136,14 +136,14 @@
 
 SpsVuiRewriter::ParseResult SpsVuiRewriter::ParseAndRewriteSps(
     rtc::ArrayView<const uint8_t> buffer,
-    absl::optional<SpsParser::SpsState>* sps,
+    std::optional<SpsParser::SpsState>* sps,
     const webrtc::ColorSpace* color_space,
     rtc::Buffer* destination) {
   // Create temporary RBSP decoded buffer of the payload (exlcuding the
   // leading nalu type header byte (the SpsParser uses only the payload).
   std::vector<uint8_t> rbsp_buffer = H264::ParseRbsp(buffer);
   BitstreamReader source_buffer(rbsp_buffer);
-  absl::optional<SpsParser::SpsState> sps_state =
+  std::optional<SpsParser::SpsState> sps_state =
       SpsParser::ParseSpsUpToVui(source_buffer);
   if (!sps_state)
     return ParseResult::kFailure;
@@ -212,7 +212,7 @@
 
 SpsVuiRewriter::ParseResult SpsVuiRewriter::ParseAndRewriteSps(
     rtc::ArrayView<const uint8_t> buffer,
-    absl::optional<SpsParser::SpsState>* sps,
+    std::optional<SpsParser::SpsState>* sps,
     const webrtc::ColorSpace* color_space,
     rtc::Buffer* destination,
     Direction direction) {
@@ -253,7 +253,7 @@
       // protect legacy receive clients) in RtpDepacketizerH264::ParseSingleNalu
       // (receive side, in orderer to protect us from unknown or legacy send
       // clients).
-      absl::optional<SpsParser::SpsState> sps;
+      std::optional<SpsParser::SpsState> sps;
       rtc::Buffer output_nalu;
 
       // Add the type header to the output buffer first, so that the rewriter
diff --git a/common_video/h264/sps_vui_rewriter.h b/common_video/h264/sps_vui_rewriter.h
index 66f7e1a..9323219 100644
--- a/common_video/h264/sps_vui_rewriter.h
+++ b/common_video/h264/sps_vui_rewriter.h
@@ -15,7 +15,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/video/color_space.h"
 #include "common_video/h264/sps_parser.h"
 #include "rtc_base/buffer.h"
@@ -42,12 +43,11 @@
   // SPS state. This function assumes that any previous headers
   // (NALU start, type, Stap-A, etc) have already been parsed and that RBSP
   // decoding has been performed.
-  static ParseResult ParseAndRewriteSps(
-      rtc::ArrayView<const uint8_t> buffer,
-      absl::optional<SpsParser::SpsState>* sps,
-      const ColorSpace* color_space,
-      rtc::Buffer* destination,
-      Direction Direction);
+  static ParseResult ParseAndRewriteSps(rtc::ArrayView<const uint8_t> buffer,
+                                        std::optional<SpsParser::SpsState>* sps,
+                                        const ColorSpace* color_space,
+                                        rtc::Buffer* destination,
+                                        Direction Direction);
 
   // Parses NAL units from `buffer`, strips AUD blocks and rewrites VUI in SPS
   // blocks if necessary.
@@ -56,11 +56,10 @@
       const ColorSpace* color_space);
 
  private:
-  static ParseResult ParseAndRewriteSps(
-      rtc::ArrayView<const uint8_t> buffer,
-      absl::optional<SpsParser::SpsState>* sps,
-      const ColorSpace* color_space,
-      rtc::Buffer* destination);
+  static ParseResult ParseAndRewriteSps(rtc::ArrayView<const uint8_t> buffer,
+                                        std::optional<SpsParser::SpsState>* sps,
+                                        const ColorSpace* color_space,
+                                        rtc::Buffer* destination);
 
   static void UpdateStats(ParseResult result, Direction direction);
 };
diff --git a/common_video/h264/sps_vui_rewriter_unittest.cc b/common_video/h264/sps_vui_rewriter_unittest.cc
index d440905..4fbfdfe 100644
--- a/common_video/h264/sps_vui_rewriter_unittest.cc
+++ b/common_video/h264/sps_vui_rewriter_unittest.cc
@@ -307,7 +307,7 @@
   rtc::Buffer original_sps;
   GenerateFakeSps(vui, &original_sps);
 
-  absl::optional<SpsParser::SpsState> sps;
+  std::optional<SpsParser::SpsState> sps;
   rtc::Buffer rewritten_sps;
   SpsVuiRewriter::ParseResult result = SpsVuiRewriter::ParseAndRewriteSps(
       original_sps, &sps, color_space, &rewritten_sps,
diff --git a/common_video/h265/h265_bitstream_parser.cc b/common_video/h265/h265_bitstream_parser.cc
index ee41a79..9ee6ff0 100644
--- a/common_video/h265/h265_bitstream_parser.cc
+++ b/common_video/h265/h265_bitstream_parser.cc
@@ -38,7 +38,7 @@
                              " to be"                                         \
                           << " in range [" << (min) << ":" << (max) << "]"    \
                           << " found " << (val) << " instead";                \
-      return absl::nullopt;                                                   \
+      return std::nullopt;                                                    \
     }                                                                         \
   } while (0)
 
@@ -82,8 +82,8 @@
 H265BitstreamParser::Result H265BitstreamParser::ParseNonParameterSetNalu(
     rtc::ArrayView<const uint8_t> source,
     uint8_t nalu_type) {
-  last_slice_qp_delta_ = absl::nullopt;
-  last_slice_pps_id_ = absl::nullopt;
+  last_slice_qp_delta_ = std::nullopt;
+  last_slice_pps_id_ = std::nullopt;
   const std::vector<uint8_t> slice_rbsp = H265::ParseRbsp(source);
   if (slice_rbsp.size() < H265::kNaluHeaderSize)
     return kInvalidStream;
@@ -165,7 +165,7 @@
       // short_term_ref_pic_set_sps_flag: u(1)
       short_term_ref_pic_set_sps_flag = slice_reader.Read<bool>();
       if (!short_term_ref_pic_set_sps_flag) {
-        absl::optional<H265SpsParser::ShortTermRefPicSet> ref_pic_set =
+        std::optional<H265SpsParser::ShortTermRefPicSet> ref_pic_set =
             H265SpsParser::ParseShortTermRefPicSet(
                 sps->num_short_term_ref_pic_sets,
                 sps->num_short_term_ref_pic_sets, sps->short_term_ref_pic_set,
@@ -426,7 +426,7 @@
   H265::NaluType nalu_type = H265::ParseNaluType(slice[0]);
   switch (nalu_type) {
     case H265::NaluType::kVps: {
-      absl::optional<H265VpsParser::VpsState> vps_state;
+      std::optional<H265VpsParser::VpsState> vps_state;
       if (slice.size() >= H265::kNaluHeaderSize) {
         vps_state =
             H265VpsParser::ParseVps(slice.subview(H265::kNaluHeaderSize));
@@ -440,7 +440,7 @@
       break;
     }
     case H265::NaluType::kSps: {
-      absl::optional<H265SpsParser::SpsState> sps_state;
+      std::optional<H265SpsParser::SpsState> sps_state;
       if (slice.size() >= H265::kNaluHeaderSize) {
         sps_state =
             H265SpsParser::ParseSps(slice.subview(H265::kNaluHeaderSize));
@@ -453,7 +453,7 @@
       break;
     }
     case H265::NaluType::kPps: {
-      absl::optional<H265PpsParser::PpsState> pps_state;
+      std::optional<H265PpsParser::PpsState> pps_state;
       if (slice.size() >= H265::kNaluHeaderSize) {
         std::vector<uint8_t> unpacked_buffer =
             H265::ParseRbsp(slice.subview(H265::kNaluHeaderSize));
@@ -490,7 +490,7 @@
   }
 }
 
-absl::optional<uint32_t>
+std::optional<uint32_t>
 H265BitstreamParser::ParsePpsIdFromSliceSegmentLayerRbsp(
     rtc::ArrayView<const uint8_t> data,
     uint8_t nalu_type) {
@@ -500,7 +500,7 @@
   // first_slice_segment_in_pic_flag: u(1)
   slice_reader.ConsumeBits(1);
   if (!slice_reader.Ok()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (nalu_type >= H265::NaluType::kBlaWLp &&
@@ -513,7 +513,7 @@
   uint32_t slice_pic_parameter_set_id = slice_reader.ReadExponentialGolomb();
   IN_RANGE_OR_RETURN_NULL(slice_pic_parameter_set_id, 0, 63);
   if (!slice_reader.Ok()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return slice_pic_parameter_set_id;
@@ -527,25 +527,25 @@
         bitstream.subview(index.payload_start_offset, index.payload_size));
 }
 
-absl::optional<int> H265BitstreamParser::GetLastSliceQp() const {
+std::optional<int> H265BitstreamParser::GetLastSliceQp() const {
   if (!last_slice_qp_delta_ || !last_slice_pps_id_) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   const H265PpsParser::PpsState* pps = GetPPS(last_slice_pps_id_.value());
   if (!pps)
-    return absl::nullopt;
+    return std::nullopt;
   const int parsed_qp = 26 + pps->init_qp_minus26 + *last_slice_qp_delta_;
   if (parsed_qp < kMinQpValue || parsed_qp > kMaxQpValue) {
     RTC_LOG(LS_ERROR) << "Parsed invalid QP from bitstream.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return parsed_qp;
 }
 
-absl::optional<uint32_t> H265BitstreamParser::GetLastSlicePpsId() const {
+std::optional<uint32_t> H265BitstreamParser::GetLastSlicePpsId() const {
   if (!last_slice_pps_id_) {
     RTC_LOG(LS_ERROR) << "Failed to parse PPS id from bitstream.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return last_slice_pps_id_;
diff --git a/common_video/h265/h265_bitstream_parser.h b/common_video/h265/h265_bitstream_parser.h
index cf18ccb..3ac8a5a 100644
--- a/common_video/h265/h265_bitstream_parser.h
+++ b/common_video/h265/h265_bitstream_parser.h
@@ -14,9 +14,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/video_codecs/bitstream_parser.h"
 #include "common_video/h265/h265_pps_parser.h"
 #include "common_video/h265/h265_sps_parser.h"
@@ -35,11 +35,11 @@
 
   // New interface.
   void ParseBitstream(rtc::ArrayView<const uint8_t> bitstream) override;
-  absl::optional<int> GetLastSliceQp() const override;
+  std::optional<int> GetLastSliceQp() const override;
 
-  absl::optional<uint32_t> GetLastSlicePpsId() const;
+  std::optional<uint32_t> GetLastSlicePpsId() const;
 
-  static absl::optional<uint32_t> ParsePpsIdFromSliceSegmentLayerRbsp(
+  static std::optional<uint32_t> ParsePpsIdFromSliceSegmentLayerRbsp(
       rtc::ArrayView<const uint8_t> data,
       uint8_t nalu_type);
 
@@ -63,8 +63,8 @@
   flat_map<uint32_t, H265PpsParser::PpsState> pps_;
 
   // Last parsed slice QP.
-  absl::optional<int32_t> last_slice_qp_delta_;
-  absl::optional<uint32_t> last_slice_pps_id_;
+  std::optional<int32_t> last_slice_qp_delta_;
+  std::optional<uint32_t> last_slice_pps_id_;
 };
 
 }  // namespace webrtc
diff --git a/common_video/h265/h265_bitstream_parser_unittest.cc b/common_video/h265/h265_bitstream_parser_unittest.cc
index 5889c70..aed779c 100644
--- a/common_video/h265/h265_bitstream_parser_unittest.cc
+++ b/common_video/h265/h265_bitstream_parser_unittest.cc
@@ -105,7 +105,7 @@
 TEST(H265BitstreamParserTest, ReportsLastSliceQpForImageSlices) {
   H265BitstreamParser h265_parser;
   h265_parser.ParseBitstream(kH265BitstreamChunk);
-  absl::optional<int> qp = h265_parser.GetLastSliceQp();
+  std::optional<int> qp = h265_parser.GetLastSliceQp();
   ASSERT_TRUE(qp.has_value());
   EXPECT_EQ(34, *qp);
 
@@ -119,14 +119,14 @@
 TEST(H265BitstreamParserTest, ReportsLastSliceQpFromShortTermReferenceSlices) {
   H265BitstreamParser h265_parser;
   h265_parser.ParseBitstream(kH265SliceStrChunk);
-  absl::optional<int> qp = h265_parser.GetLastSliceQp();
+  std::optional<int> qp = h265_parser.GetLastSliceQp();
   ASSERT_TRUE(qp.has_value());
   EXPECT_EQ(33, *qp);
 }
 
 TEST(H265BitstreamParserTest, PpsIdFromSlice) {
   H265BitstreamParser h265_parser;
-  absl::optional<uint32_t> pps_id =
+  std::optional<uint32_t> pps_id =
       h265_parser.ParsePpsIdFromSliceSegmentLayerRbsp(kH265SliceChunk,
                                                       H265::NaluType::kTrailR);
   ASSERT_TRUE(pps_id);
@@ -136,7 +136,7 @@
 TEST(H265BitstreamParserTest, ReportsLastSliceQpInvalidQPSlices) {
   H265BitstreamParser h265_parser;
   h265_parser.ParseBitstream(kH265BitstreamInvalidQPChunk);
-  absl::optional<int> qp = h265_parser.GetLastSliceQp();
+  std::optional<int> qp = h265_parser.GetLastSliceQp();
   ASSERT_FALSE(qp.has_value());
 
   h265_parser.ParseBitstream(kH265BitstreamInvalidQPChunk52);
diff --git a/common_video/h265/h265_pps_parser.cc b/common_video/h265/h265_pps_parser.cc
index 3339f65..c1c21e4 100644
--- a/common_video/h265/h265_pps_parser.cc
+++ b/common_video/h265/h265_pps_parser.cc
@@ -11,9 +11,9 @@
 #include "common_video/h265/h265_pps_parser.h"
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "common_video/h265/h265_common.h"
 #include "rtc_base/bit_buffer.h"
 #include "rtc_base/bitstream_reader.h"
@@ -26,7 +26,7 @@
                              " to be"                                         \
                           << " in range [" << (min) << ":" << (max) << "]"    \
                           << " found " << (val) << " instead";                \
-      return absl::nullopt;                                                   \
+      return std::nullopt;                                                    \
     }                                                                         \
   } while (0)
 
@@ -46,7 +46,7 @@
     if (!reader.Ok() || !(a)) {                                          \
       RTC_LOG(LS_WARNING) << "Error in stream: invalid value, expected " \
                           << #a;                                         \
-      return absl::nullopt;                                              \
+      return std::nullopt;                                               \
     }                                                                    \
   } while (0)
 
@@ -62,7 +62,7 @@
 // You can find it on this page:
 // http://www.itu.int/rec/T-REC-H.265
 
-absl::optional<H265PpsParser::PpsState> H265PpsParser::ParsePps(
+std::optional<H265PpsParser::PpsState> H265PpsParser::ParsePps(
     rtc::ArrayView<const uint8_t> data,
     const H265SpsParser::SpsState* sps) {
   // First, parse out rbsp, which is basically the source buffer minus emulation
@@ -88,18 +88,18 @@
   return reader.Ok();
 }
 
-absl::optional<H265PpsParser::PpsState> H265PpsParser::ParseInternal(
+std::optional<H265PpsParser::PpsState> H265PpsParser::ParseInternal(
     rtc::ArrayView<const uint8_t> buffer,
     const H265SpsParser::SpsState* sps) {
   BitstreamReader reader(buffer);
   PpsState pps;
 
   if (!sps) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (!ParsePpsIdsInternal(reader, pps.pps_id, pps.sps_id)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // dependent_slice_segments_enabled_flag: u(1)
@@ -221,14 +221,14 @@
   if (pps_scaling_list_data_present_flag) {
     // scaling_list_data()
     if (!H265SpsParser::ParseScalingListData(reader)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
   // lists_modification_present_flag: u(1)
   pps.lists_modification_present_flag = reader.Read<bool>();
 
   if (!reader.Ok()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return pps;
diff --git a/common_video/h265/h265_pps_parser.h b/common_video/h265/h265_pps_parser.h
index 1bd0ead..11cd286 100644
--- a/common_video/h265/h265_pps_parser.h
+++ b/common_video/h265/h265_pps_parser.h
@@ -11,7 +11,8 @@
 #ifndef COMMON_VIDEO_H265_H265_PPS_PARSER_H_
 #define COMMON_VIDEO_H265_H265_PPS_PARSER_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/array_view.h"
 #include "common_video/h265/h265_sps_parser.h"
 #include "rtc_base/bitstream_reader.h"
@@ -43,10 +44,10 @@
   };
 
   // Unpack RBSP and parse PPS state from the supplied buffer.
-  static absl::optional<PpsState> ParsePps(rtc::ArrayView<const uint8_t> data,
-                                           const H265SpsParser::SpsState* sps);
+  static std::optional<PpsState> ParsePps(rtc::ArrayView<const uint8_t> data,
+                                          const H265SpsParser::SpsState* sps);
   // TODO: bugs.webrtc.org/42225170 - Deprecate.
-  static inline absl::optional<PpsState> ParsePps(
+  static inline std::optional<PpsState> ParsePps(
       const uint8_t* data,
       size_t length,
       const H265SpsParser::SpsState* sps) {
@@ -67,7 +68,7 @@
  protected:
   // Parse the PPS state, for a bit buffer where RBSP decoding has already been
   // performed.
-  static absl::optional<PpsState> ParseInternal(
+  static std::optional<PpsState> ParseInternal(
       rtc::ArrayView<const uint8_t> buffer,
       const H265SpsParser::SpsState* sps);
   static bool ParsePpsIdsInternal(BitstreamReader& reader,
diff --git a/common_video/h265/h265_pps_parser_unittest.cc b/common_video/h265/h265_pps_parser_unittest.cc
index c683a43..61cf0a5 100644
--- a/common_video/h265/h265_pps_parser_unittest.cc
+++ b/common_video/h265/h265_pps_parser_unittest.cc
@@ -222,8 +222,8 @@
 
   H265PpsParser::PpsState generated_pps_;
   rtc::Buffer buffer_;
-  absl::optional<H265PpsParser::PpsState> parsed_pps_;
-  absl::optional<H265SpsParser::SpsState> parsed_sps_;
+  std::optional<H265PpsParser::PpsState> parsed_pps_;
+  std::optional<H265SpsParser::SpsState> parsed_sps_;
 };
 
 TEST_F(H265PpsParserTest, ZeroPps) {
diff --git a/common_video/h265/h265_sps_parser.cc b/common_video/h265/h265_sps_parser.cc
index cb59d60..fa23f6a 100644
--- a/common_video/h265/h265_sps_parser.cc
+++ b/common_video/h265/h265_sps_parser.cc
@@ -25,7 +25,7 @@
                              " to be"                                         \
                           << " in range [" << (min) << ":" << (max) << "]"    \
                           << " found " << (val) << " instead";                \
-      return absl::nullopt;                                                   \
+      return std::nullopt;                                                    \
     }                                                                         \
   } while (0)
 
@@ -45,16 +45,16 @@
     if (!reader.Ok() || !(a)) {                                          \
       RTC_LOG(LS_WARNING) << "Error in stream: invalid value, expected " \
                           << #a;                                         \
-      return absl::nullopt;                                              \
+      return std::nullopt;                                               \
     }                                                                    \
   } while (0)
 
 namespace {
-using OptionalSps = absl::optional<webrtc::H265SpsParser::SpsState>;
+using OptionalSps = std::optional<webrtc::H265SpsParser::SpsState>;
 using OptionalShortTermRefPicSet =
-    absl::optional<webrtc::H265SpsParser::ShortTermRefPicSet>;
+    std::optional<webrtc::H265SpsParser::ShortTermRefPicSet>;
 using OptionalProfileTierLevel =
-    absl::optional<webrtc::H265SpsParser::ProfileTierLevel>;
+    std::optional<webrtc::H265SpsParser::ProfileTierLevel>;
 
 constexpr int kMaxNumSizeIds = 4;
 constexpr int kMaxNumMatrixIds = 6;
@@ -103,7 +103,7 @@
 // http://www.itu.int/rec/T-REC-H.265
 
 // Unpack RBSP and parse SPS state from the supplied buffer.
-absl::optional<H265SpsParser::SpsState> H265SpsParser::ParseSps(
+std::optional<H265SpsParser::SpsState> H265SpsParser::ParseSps(
     rtc::ArrayView<const uint8_t> data) {
   return ParseSpsInternal(H265::ParseRbsp(data));
 }
@@ -146,7 +146,7 @@
   return reader.Ok();
 }
 
-absl::optional<H265SpsParser::ShortTermRefPicSet>
+std::optional<H265SpsParser::ShortTermRefPicSet>
 H265SpsParser::ParseShortTermRefPicSet(
     uint32_t st_rps_idx,
     uint32_t num_short_term_ref_pic_sets,
@@ -297,13 +297,13 @@
       st_ref_pic_set.num_negative_pics + st_ref_pic_set.num_positive_pics;
 
   if (!reader.Ok()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return OptionalShortTermRefPicSet(st_ref_pic_set);
 }
 
-absl::optional<H265SpsParser::ProfileTierLevel>
+std::optional<H265SpsParser::ProfileTierLevel>
 H265SpsParser::ParseProfileTierLevel(bool profile_present,
                                      int max_num_sub_layers_minus1,
                                      BitstreamReader& reader) {
@@ -327,7 +327,7 @@
     if (!reader.Ok() || (!pf_tier_level.general_progressive_source_flag &&
                          pf_tier_level.general_interlaced_source_flag)) {
       RTC_LOG(LS_WARNING) << "Interlaced streams not supported";
-      return absl::nullopt;
+      return std::nullopt;
     }
     pf_tier_level.general_non_packed_constraint_flag = reader.ReadBits(1);
     pf_tier_level.general_frame_only_constraint_flag = reader.ReadBits(1);
@@ -378,13 +378,13 @@
   }
 
   if (!reader.Ok()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return OptionalProfileTierLevel(pf_tier_level);
 }
 
-absl::optional<H265SpsParser::SpsState> H265SpsParser::ParseSpsInternal(
+std::optional<H265SpsParser::SpsState> H265SpsParser::ParseSpsInternal(
     rtc::ArrayView<const uint8_t> buffer) {
   BitstreamReader reader(buffer);
 
@@ -416,7 +416,7 @@
   OptionalProfileTierLevel profile_tier_level =
       ParseProfileTierLevel(true, sps.sps_max_sub_layers_minus1, reader);
   if (!profile_tier_level) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   // sps_seq_parameter_set_id: ue(v)
   sps.sps_id = reader.ReadExponentialGolomb();
@@ -572,7 +572,7 @@
     if (sps_scaling_list_data_present_flag) {
       // scaling_list_data()
       if (!ParseScalingListData(reader)) {
-        return absl::nullopt;
+        return std::nullopt;
       }
     }
   }
@@ -622,7 +622,7 @@
     if (ref_pic_set) {
       sps.short_term_ref_pic_set[st_rps_idx] = *ref_pic_set;
     } else {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
@@ -675,7 +675,7 @@
   }
 
   if (!reader.Ok()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return OptionalSps(sps);
diff --git a/common_video/h265/h265_sps_parser.h b/common_video/h265/h265_sps_parser.h
index 072e2e9..4af1bf3 100644
--- a/common_video/h265/h265_sps_parser.h
+++ b/common_video/h265/h265_sps_parser.h
@@ -11,9 +11,9 @@
 #ifndef COMMON_VIDEO_H265_H265_SPS_PARSER_H_
 #define COMMON_VIDEO_H265_H265_SPS_PARSER_H_
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "rtc_base/bitstream_reader.h"
 #include "rtc_base/system/rtc_export.h"
@@ -104,23 +104,23 @@
   };
 
   // Unpack RBSP and parse SPS state from the supplied buffer.
-  static absl::optional<SpsState> ParseSps(rtc::ArrayView<const uint8_t> data);
+  static std::optional<SpsState> ParseSps(rtc::ArrayView<const uint8_t> data);
   // TODO: bugs.webrtc.org/42225170 - Deprecate.
-  static inline absl::optional<SpsState> ParseSps(const uint8_t* data,
-                                                  size_t length) {
+  static inline std::optional<SpsState> ParseSps(const uint8_t* data,
+                                                 size_t length) {
     return ParseSps(rtc::MakeArrayView(data, length));
   }
 
   static bool ParseScalingListData(BitstreamReader& reader);
 
-  static absl::optional<ShortTermRefPicSet> ParseShortTermRefPicSet(
+  static std::optional<ShortTermRefPicSet> ParseShortTermRefPicSet(
       uint32_t st_rps_idx,
       uint32_t num_short_term_ref_pic_sets,
       const std::vector<ShortTermRefPicSet>& ref_pic_sets,
       uint32_t sps_max_dec_pic_buffering_minus1,
       BitstreamReader& reader);
 
-  static absl::optional<H265SpsParser::ProfileTierLevel> ParseProfileTierLevel(
+  static std::optional<H265SpsParser::ProfileTierLevel> ParseProfileTierLevel(
       bool profile_present,
       int max_num_sub_layers_minus1,
       BitstreamReader& reader);
@@ -128,7 +128,7 @@
  protected:
   // Parse the SPS state, for a bit buffer where RBSP decoding has already been
   // performed.
-  static absl::optional<SpsState> ParseSpsInternal(
+  static std::optional<SpsState> ParseSpsInternal(
       rtc::ArrayView<const uint8_t> buffer);
 
   // From Table A.8 - General tier and level limits.
diff --git a/common_video/h265/h265_sps_parser_unittest.cc b/common_video/h265/h265_sps_parser_unittest.cc
index 46d8d2d..1c8537b 100644
--- a/common_video/h265/h265_sps_parser_unittest.cc
+++ b/common_video/h265/h265_sps_parser_unittest.cc
@@ -389,7 +389,7 @@
                             0x02, 0x80, 0x80, 0x2d, 0x16, 0x59, 0x59, 0xa4,
                             0x93, 0x2b, 0x80, 0x40, 0x00, 0x00, 0x03, 0x00,
                             0x40, 0x00, 0x00, 0x07, 0x82};
-  absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
+  std::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(1280u, sps->width);
   EXPECT_EQ(720u, sps->height);
@@ -417,7 +417,7 @@
                             0x05, 0x02, 0x01, 0x09, 0xf2, 0xe5, 0x95, 0x9a,
                             0x49, 0x32, 0xb8, 0x04, 0x00, 0x00, 0x03, 0x00,
                             0x04, 0x00, 0x00, 0x03, 0x00, 0x78, 0x20};
-  absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
+  std::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(640u, sps->width);
   EXPECT_EQ(260u, sps->height);
@@ -444,7 +444,7 @@
                             0x08, 0x48, 0x04, 0x27, 0x72, 0xe5, 0x95, 0x9a,
                             0x49, 0x32, 0xb8, 0x04, 0x00, 0x00, 0x03, 0x00,
                             0x04, 0x00, 0x00, 0x03, 0x00, 0x78, 0x20};
-  absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
+  std::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(260u, sps->width);
   EXPECT_EQ(260u, sps->height);
@@ -453,7 +453,7 @@
 TEST_F(H265SpsParserTest, TestSyntheticSPSQvgaLandscape) {
   rtc::Buffer buffer;
   WriteSps(320u, 180u, 1, 0, 1, 0, &buffer);
-  absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
+  std::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(320u, sps->width);
   EXPECT_EQ(180u, sps->height);
@@ -463,7 +463,7 @@
 TEST_F(H265SpsParserTest, TestSyntheticSPSWeirdResolution) {
   rtc::Buffer buffer;
   WriteSps(156u, 122u, 2, 0, 1, 0, &buffer);
-  absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
+  std::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(156u, sps->width);
   EXPECT_EQ(122u, sps->height);
@@ -473,7 +473,7 @@
 TEST_F(H265SpsParserTest, TestLog2MaxSubLayersMinus1) {
   rtc::Buffer buffer;
   WriteSps(320u, 180u, 1, 0, 1, 0, &buffer);
-  absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
+  std::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(320u, sps->width);
   EXPECT_EQ(180u, sps->height);
@@ -481,8 +481,7 @@
   EXPECT_EQ(0u, sps->sps_max_sub_layers_minus1);
 
   WriteSps(320u, 180u, 1, 6, 1, 0, &buffer);
-  absl::optional<H265SpsParser::SpsState> sps1 =
-      H265SpsParser::ParseSps(buffer);
+  std::optional<H265SpsParser::SpsState> sps1 = H265SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps1.has_value());
   EXPECT_EQ(320u, sps1->width);
   EXPECT_EQ(180u, sps1->height);
@@ -490,7 +489,7 @@
   EXPECT_EQ(6u, sps1->sps_max_sub_layers_minus1);
 
   WriteSps(320u, 180u, 1, 7, 1, 0, &buffer);
-  absl::optional<H265SpsParser::SpsState> result =
+  std::optional<H265SpsParser::SpsState> result =
       H265SpsParser::ParseSps(buffer);
   EXPECT_FALSE(result.has_value());
 }
@@ -498,7 +497,7 @@
 TEST_F(H265SpsParserTest, TestSubLayerOrderingInfoPresentFlag) {
   rtc::Buffer buffer;
   WriteSps(320u, 180u, 1, 6, 1, 0, &buffer);
-  absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
+  std::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(320u, sps->width);
   EXPECT_EQ(180u, sps->height);
@@ -506,8 +505,7 @@
   EXPECT_EQ(6u, sps->sps_max_sub_layers_minus1);
 
   WriteSps(320u, 180u, 1, 6, 1, 0, &buffer);
-  absl::optional<H265SpsParser::SpsState> sps1 =
-      H265SpsParser::ParseSps(buffer);
+  std::optional<H265SpsParser::SpsState> sps1 = H265SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps1.has_value());
   EXPECT_EQ(320u, sps1->width);
   EXPECT_EQ(180u, sps1->height);
@@ -518,7 +516,7 @@
 TEST_F(H265SpsParserTest, TestLongTermRefPicsPresentFlag) {
   rtc::Buffer buffer;
   WriteSps(320u, 180u, 1, 0, 1, 0, &buffer);
-  absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
+  std::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps.has_value());
   EXPECT_EQ(320u, sps->width);
   EXPECT_EQ(180u, sps->height);
@@ -526,8 +524,7 @@
   EXPECT_EQ(0u, sps->long_term_ref_pics_present_flag);
 
   WriteSps(320u, 180u, 1, 6, 1, 1, &buffer);
-  absl::optional<H265SpsParser::SpsState> sps1 =
-      H265SpsParser::ParseSps(buffer);
+  std::optional<H265SpsParser::SpsState> sps1 = H265SpsParser::ParseSps(buffer);
   ASSERT_TRUE(sps1.has_value());
   EXPECT_EQ(320u, sps1->width);
   EXPECT_EQ(180u, sps1->height);
diff --git a/common_video/h265/h265_vps_parser.cc b/common_video/h265/h265_vps_parser.cc
index 0a00370..fd896ad 100644
--- a/common_video/h265/h265_vps_parser.cc
+++ b/common_video/h265/h265_vps_parser.cc
@@ -24,12 +24,12 @@
 // http://www.itu.int/rec/T-REC-H.265
 
 // Unpack RBSP and parse VPS state from the supplied buffer.
-absl::optional<H265VpsParser::VpsState> H265VpsParser::ParseVps(
+std::optional<H265VpsParser::VpsState> H265VpsParser::ParseVps(
     rtc::ArrayView<const uint8_t> data) {
   return ParseInternal(H265::ParseRbsp(data));
 }
 
-absl::optional<H265VpsParser::VpsState> H265VpsParser::ParseInternal(
+std::optional<H265VpsParser::VpsState> H265VpsParser::ParseInternal(
     rtc::ArrayView<const uint8_t> buffer) {
   BitstreamReader reader(buffer);
 
@@ -42,7 +42,7 @@
   vps.id = reader.ReadBits(4);
 
   if (!reader.Ok()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return vps;
diff --git a/common_video/h265/h265_vps_parser.h b/common_video/h265/h265_vps_parser.h
index e8ca1a0..2cbf5e5 100644
--- a/common_video/h265/h265_vps_parser.h
+++ b/common_video/h265/h265_vps_parser.h
@@ -11,7 +11,8 @@
 #ifndef COMMON_VIDEO_H265_H265_VPS_PARSER_H_
 #define COMMON_VIDEO_H265_H265_VPS_PARSER_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/array_view.h"
 #include "rtc_base/system/rtc_export.h"
 
@@ -29,17 +30,17 @@
   };
 
   // Unpack RBSP and parse VPS state from the supplied buffer.
-  static absl::optional<VpsState> ParseVps(rtc::ArrayView<const uint8_t> data);
+  static std::optional<VpsState> ParseVps(rtc::ArrayView<const uint8_t> data);
   // TODO: bugs.webrtc.org/42225170 - Deprecate.
-  static inline absl::optional<VpsState> ParseVps(const uint8_t* data,
-                                                  size_t length) {
+  static inline std::optional<VpsState> ParseVps(const uint8_t* data,
+                                                 size_t length) {
     return ParseVps(rtc::MakeArrayView(data, length));
   }
 
  protected:
   // Parse the VPS state, for a bit buffer where RBSP decoding has already been
   // performed.
-  static absl::optional<VpsState> ParseInternal(
+  static std::optional<VpsState> ParseInternal(
       rtc::ArrayView<const uint8_t> buffer);
 };
 
diff --git a/common_video/h265/h265_vps_parser_unittest.cc b/common_video/h265/h265_vps_parser_unittest.cc
index 87e1f58..fd2e8a8 100644
--- a/common_video/h265/h265_vps_parser_unittest.cc
+++ b/common_video/h265/h265_vps_parser_unittest.cc
@@ -32,7 +32,7 @@
   H265VpsParserTest() {}
   ~H265VpsParserTest() override {}
 
-  absl::optional<H265VpsParser::VpsState> vps_;
+  std::optional<H265VpsParser::VpsState> vps_;
 };
 
 TEST_F(H265VpsParserTest, TestSampleVPSId) {
diff --git a/common_video/include/bitrate_adjuster.h b/common_video/include/bitrate_adjuster.h
index 4b20830..966c35d 100644
--- a/common_video/include/bitrate_adjuster.h
+++ b/common_video/include/bitrate_adjuster.h
@@ -14,7 +14,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "rtc_base/rate_statistics.h"
 #include "rtc_base/synchronization/mutex.h"
 #include "rtc_base/system/rtc_export.h"
@@ -48,7 +49,7 @@
   uint32_t GetAdjustedBitrateBps() const;
 
   // Returns what we think the current bitrate is.
-  absl::optional<uint32_t> GetEstimatedBitrateBps();
+  std::optional<uint32_t> GetEstimatedBitrateBps();
 
   // This should be called after each frame is encoded. The timestamp at which
   // it is called is used to estimate the output bitrate of the encoder.
diff --git a/examples/BUILD.gn b/examples/BUILD.gn
index ed02eb7..57de7ce 100644
--- a/examples/BUILD.gn
+++ b/examples/BUILD.gn
@@ -720,7 +720,6 @@
       "../test:platform_video_capturer",
       "../test:rtp_test_utils",
       "//third_party/abseil-cpp/absl/memory",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
     if (is_win) {
       sources += [
diff --git a/examples/androidvoip/jni/android_voip_client.cc b/examples/androidvoip/jni/android_voip_client.cc
index 183f97a..5004fc0 100644
--- a/examples/androidvoip/jni/android_voip_client.cc
+++ b/examples/androidvoip/jni/android_voip_client.cc
@@ -304,7 +304,7 @@
   RUN_ON_VOIP_THREAD(StartSession, env);
 
   // CreateChannel guarantees to return valid channel id.
-  channel_ = voip_engine_->Base().CreateChannel(this, absl::nullopt);
+  channel_ = voip_engine_->Base().CreateChannel(this, std::nullopt);
 
   rtp_socket_.reset(rtc::AsyncUDPSocket::Create(voip_thread_->socketserver(),
                                                 rtp_local_address_));
@@ -357,7 +357,7 @@
   webrtc::VoipResult result = voip_engine_->Base().ReleaseChannel(*channel_);
   RTC_CHECK(result == webrtc::VoipResult::kOk);
 
-  channel_ = absl::nullopt;
+  channel_ = std::nullopt;
   Java_VoipClient_onStopSessionCompleted(env_, j_voip_client_,
                                          /*isSuccessful=*/true);
 }
diff --git a/examples/androidvoip/jni/android_voip_client.h b/examples/androidvoip/jni/android_voip_client.h
index 41b6a69..073613b 100644
--- a/examples/androidvoip/jni/android_voip_client.h
+++ b/examples/androidvoip/jni/android_voip_client.h
@@ -165,7 +165,7 @@
   // The entry point to all VoIP APIs.
   std::unique_ptr<webrtc::VoipEngine> voip_engine_ RTC_GUARDED_BY(voip_thread_);
   // Used by the VoIP API to facilitate a VoIP session.
-  absl::optional<webrtc::ChannelId> channel_ RTC_GUARDED_BY(voip_thread_);
+  std::optional<webrtc::ChannelId> channel_ RTC_GUARDED_BY(voip_thread_);
   // Members below are used for network related operations.
   std::unique_ptr<rtc::AsyncUDPSocket> rtp_socket_ RTC_GUARDED_BY(voip_thread_);
   std::unique_ptr<rtc::AsyncUDPSocket> rtcp_socket_
diff --git a/examples/peerconnection/client/conductor.cc b/examples/peerconnection/client/conductor.cc
index 23e5781..cbe11eb 100644
--- a/examples/peerconnection/client/conductor.cc
+++ b/examples/peerconnection/client/conductor.cc
@@ -14,11 +14,11 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/memory/memory.h"
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/audio/audio_mixer.h"
 #include "api/audio/audio_processing.h"
@@ -358,7 +358,7 @@
       }
       return;
     }
-    absl::optional<webrtc::SdpType> type_maybe =
+    std::optional<webrtc::SdpType> type_maybe =
         webrtc::SdpTypeFromString(type_str);
     if (!type_maybe) {
       RTC_LOG(LS_ERROR) << "Unknown SDP type: " << type_str;
diff --git a/logging/BUILD.gn b/logging/BUILD.gn
index 1f70095..39a51719 100644
--- a/logging/BUILD.gn
+++ b/logging/BUILD.gn
@@ -66,7 +66,6 @@
     "../rtc_base:logging",
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -176,7 +175,6 @@
     "../rtc_base:checks",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -218,7 +216,6 @@
     "../rtc_base:timeutils",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -318,7 +315,6 @@
     "../rtc_base:checks",
     "../rtc_base:logging",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -336,7 +332,6 @@
     "../rtc_base:safe_conversions",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -357,7 +352,6 @@
     "../rtc_base:checks",
     "../rtc_base:logging",
     "../rtc_base:safe_conversions",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 
   if (rtc_enable_protobuf) {
@@ -418,7 +412,6 @@
       "../rtc_base:checks",
       "../rtc_base:logging",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
@@ -559,7 +552,6 @@
       "//third_party/abseil-cpp/absl/base:core_headers",
       "//third_party/abseil-cpp/absl/memory",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -645,7 +637,6 @@
         "//third_party/abseil-cpp/absl/algorithm:container",
         "//third_party/abseil-cpp/absl/memory",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
 
@@ -670,7 +661,6 @@
           "//third_party/abseil-cpp/absl/flags:usage",
           "//third_party/abseil-cpp/absl/memory",
           "//third_party/abseil-cpp/absl/strings",
-          "//third_party/abseil-cpp/absl/types:optional",
         ]
       }
     }
diff --git a/logging/rtc_event_log/dependency_descriptor_encoder_decoder.cc b/logging/rtc_event_log/dependency_descriptor_encoder_decoder.cc
index bac57df..ca3c8d1 100644
--- a/logging/rtc_event_log/dependency_descriptor_encoder_decoder.cc
+++ b/logging/rtc_event_log/dependency_descriptor_encoder_decoder.cc
@@ -12,11 +12,11 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "logging/rtc_event_log/encoder/delta_encoding.h"
 #include "logging/rtc_event_log/encoder/optional_blob_encoding.h"
@@ -28,7 +28,7 @@
 namespace webrtc {
 
 // static
-absl::optional<rtclog2::DependencyDescriptorsWireInfo>
+std::optional<rtclog2::DependencyDescriptorsWireInfo>
 RtcEventLogDependencyDescriptorEncoderDecoder::Encode(
     const std::vector<rtc::ArrayView<const uint8_t>>& raw_dd_data) {
   if (raw_dd_data.empty()) {
@@ -49,13 +49,13 @@
 
   // Start and end bit.
   {
-    absl::optional<uint32_t> start_end_bit;
+    std::optional<uint32_t> start_end_bit;
     if (!base_dd.empty()) {
       start_end_bit = (base_dd[0] >> 6);
       res.set_start_end_bit(*start_end_bit);
     }
     if (!delta_dds.empty()) {
-      std::vector<absl::optional<uint64_t>> values(delta_dds.size());
+      std::vector<std::optional<uint64_t>> values(delta_dds.size());
       for (size_t i = 0; i < delta_dds.size(); ++i) {
         if (!delta_dds[i].empty()) {
           values[i] = delta_dds[i][0] >> 6;
@@ -70,14 +70,14 @@
 
   // Template IDs.
   {
-    absl::optional<uint32_t> template_id;
+    std::optional<uint32_t> template_id;
     if (!base_dd.empty()) {
       template_id = (base_dd[0] & 0b0011'1111);
       res.set_template_id(*template_id);
     }
 
     if (!delta_dds.empty()) {
-      std::vector<absl::optional<uint64_t>> values(delta_dds.size());
+      std::vector<std::optional<uint64_t>> values(delta_dds.size());
       for (size_t i = 0; i < delta_dds.size(); ++i) {
         if (!delta_dds[i].empty()) {
           values[i] = delta_dds[i][0] & 0b0011'1111;
@@ -92,14 +92,14 @@
 
   // Frame IDs.
   {
-    absl::optional<uint32_t> frame_id;
+    std::optional<uint32_t> frame_id;
     if (!base_dd.empty()) {
       frame_id = (uint16_t{base_dd[1]} << 8) + base_dd[2];
       res.set_frame_id(*frame_id);
     }
 
     if (!delta_dds.empty()) {
-      std::vector<absl::optional<uint64_t>> values(delta_dds.size());
+      std::vector<std::optional<uint64_t>> values(delta_dds.size());
       for (size_t i = 0; i < delta_dds.size(); ++i) {
         if (!delta_dds[i].empty()) {
           values[i] = (uint16_t{delta_dds[i][1]} << 8) + delta_dds[i][2];
@@ -114,7 +114,7 @@
 
   // Extended info
   {
-    std::vector<absl::optional<std::string>> values(raw_dd_data.size());
+    std::vector<std::optional<std::string>> values(raw_dd_data.size());
     for (size_t i = 0; i < raw_dd_data.size(); ++i) {
       if (raw_dd_data[i].size() > 3) {
         auto extended_info = raw_dd_data[i].subview(3);
@@ -143,49 +143,49 @@
 
   std::vector<std::vector<uint8_t>> res(num_packets);
 
-  absl::optional<uint64_t> start_end_bit_base;
+  std::optional<uint64_t> start_end_bit_base;
   if (dd_wire_info.has_start_end_bit()) {
     start_end_bit_base = dd_wire_info.start_end_bit();
   }
-  absl::optional<uint64_t> template_id_base;
+  std::optional<uint64_t> template_id_base;
   if (dd_wire_info.has_template_id()) {
     template_id_base = dd_wire_info.template_id();
   }
-  absl::optional<uint64_t> frame_id_base;
+  std::optional<uint64_t> frame_id_base;
   if (dd_wire_info.has_frame_id()) {
     frame_id_base = dd_wire_info.frame_id();
   }
 
-  std::vector<absl::optional<uint64_t>> start_end_bit_deltas;
+  std::vector<std::optional<uint64_t>> start_end_bit_deltas;
   if (dd_wire_info.has_start_end_bit_deltas()) {
     start_end_bit_deltas = DecodeDeltas(dd_wire_info.start_end_bit_deltas(),
                                         start_end_bit_base, num_packets - 1);
     RTC_DCHECK(start_end_bit_deltas.empty() ||
                start_end_bit_deltas.size() == (num_packets - 1));
   }
-  std::vector<absl::optional<uint64_t>> template_id_deltas;
+  std::vector<std::optional<uint64_t>> template_id_deltas;
   if (dd_wire_info.has_template_id_deltas()) {
     template_id_deltas = DecodeDeltas(dd_wire_info.template_id_deltas(),
                                       template_id_base, num_packets - 1);
     RTC_DCHECK(template_id_deltas.empty() ||
                template_id_deltas.size() == (num_packets - 1));
   }
-  std::vector<absl::optional<uint64_t>> frame_id_deltas;
+  std::vector<std::optional<uint64_t>> frame_id_deltas;
   if (dd_wire_info.has_frame_id_deltas()) {
     frame_id_deltas = DecodeDeltas(dd_wire_info.frame_id_deltas(),
                                    frame_id_base, num_packets - 1);
     RTC_DCHECK(frame_id_deltas.empty() ||
                frame_id_deltas.size() == (num_packets - 1));
   }
-  std::vector<absl::optional<std::string>> extended_infos;
+  std::vector<std::optional<std::string>> extended_infos;
   if (dd_wire_info.has_extended_infos()) {
     extended_infos =
         DecodeOptionalBlobs(dd_wire_info.extended_infos(), num_packets);
   }
 
-  auto recreate_raw_dd = [&](int i, const absl::optional<uint64_t>& be,
-                             const absl::optional<uint64_t>& tid,
-                             const absl::optional<uint64_t>& fid) {
+  auto recreate_raw_dd = [&](int i, const std::optional<uint64_t>& be,
+                             const std::optional<uint64_t>& tid,
+                             const std::optional<uint64_t>& fid) {
     absl::string_view ext;
     if (!extended_infos.empty() && extended_infos[i].has_value()) {
       ext = *extended_infos[i];
diff --git a/logging/rtc_event_log/dependency_descriptor_encoder_decoder.h b/logging/rtc_event_log/dependency_descriptor_encoder_decoder.h
index 863a3c8..eaa452b 100644
--- a/logging/rtc_event_log/dependency_descriptor_encoder_decoder.h
+++ b/logging/rtc_event_log/dependency_descriptor_encoder_decoder.h
@@ -13,9 +13,9 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "logging/rtc_event_log/events/rtc_event_log_parse_status.h"
 #include "logging/rtc_event_log/rtc_event_log2_proto_include.h"
@@ -24,7 +24,7 @@
 
 class RtcEventLogDependencyDescriptorEncoderDecoder {
  public:
-  static absl::optional<rtclog2::DependencyDescriptorsWireInfo> Encode(
+  static std::optional<rtclog2::DependencyDescriptorsWireInfo> Encode(
       const std::vector<rtc::ArrayView<const uint8_t>>& raw_dd_data);
   static RtcEventLogParseStatusOr<std::vector<std::vector<uint8_t>>> Decode(
       const rtclog2::DependencyDescriptorsWireInfo& dd_wire_info,
diff --git a/logging/rtc_event_log/encoder/delta_encoding.cc b/logging/rtc_event_log/encoder/delta_encoding.cc
index 7d62f4a..80fb587 100644
--- a/logging/rtc_event_log/encoder/delta_encoding.cc
+++ b/logging/rtc_event_log/encoder/delta_encoding.cc
@@ -15,12 +15,12 @@
 #include <cstdint>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "logging/rtc_event_log/encoder/bit_writer.h"
 #include "logging/rtc_event_log/encoder/var_int.h"
 #include "rtc_base/bitstream_reader.h"
@@ -186,8 +186,8 @@
   // therefore be decoded by FixedLengthDeltaDecoder, or whether it was produced
   // by a different encoder.
   static std::string EncodeDeltas(
-      absl::optional<uint64_t> base,
-      const std::vector<absl::optional<uint64_t>>& values);
+      std::optional<uint64_t> base,
+      const std::vector<std::optional<uint64_t>>& values);
 
   FixedLengthDeltaEncoder(const FixedLengthDeltaEncoder&) = delete;
   FixedLengthDeltaEncoder& operator=(const FixedLengthDeltaEncoder&) = delete;
@@ -196,8 +196,8 @@
   // Calculate min/max values of unsigned/signed deltas, given the bit width
   // of all the values in the series.
   static void CalculateMinAndMaxDeltas(
-      absl::optional<uint64_t> base,
-      const std::vector<absl::optional<uint64_t>>& values,
+      std::optional<uint64_t> base,
+      const std::vector<std::optional<uint64_t>>& values,
       uint64_t bit_width,
       uint64_t* max_unsigned_delta,
       uint64_t* max_pos_signed_delta,
@@ -215,8 +215,8 @@
   // Therefore, it was deemed acceptable to let them have a reference to
   // `values`, whose lifetime must exceed the lifetime of `this`.
   FixedLengthDeltaEncoder(const FixedLengthEncodingParameters& params,
-                          absl::optional<uint64_t> base,
-                          const std::vector<absl::optional<uint64_t>>& values,
+                          std::optional<uint64_t> base,
+                          const std::vector<std::optional<uint64_t>>& values,
                           size_t existent_values_count);
 
   // Perform delta-encoding using the parameters given to the ctor on the
@@ -243,11 +243,11 @@
   // The encoding scheme assumes that at least one value is transmitted OOB,
   // so that the first value can be encoded as a delta from that OOB value,
   // which is `base_`.
-  const absl::optional<uint64_t> base_;
+  const std::optional<uint64_t> base_;
 
   // The values to be encoded.
   // Note: This is a non-owning reference. See comment above ctor for details.
-  const std::vector<absl::optional<uint64_t>>& values_;
+  const std::vector<std::optional<uint64_t>>& values_;
 
   // Buffer into which encoded values will be written.
   // This is created dynmically as a way to enforce that the rest of the
@@ -258,8 +258,8 @@
 
 // TODO(eladalon): Reduce the number of passes.
 std::string FixedLengthDeltaEncoder::EncodeDeltas(
-    absl::optional<uint64_t> base,
-    const std::vector<absl::optional<uint64_t>>& values) {
+    std::optional<uint64_t> base,
+    const std::vector<std::optional<uint64_t>>& values) {
   RTC_DCHECK(!values.empty());
 
   // As a special case, if all of the elements are identical to the base,
@@ -267,7 +267,7 @@
   // the empty string is used to signal that.
   if (std::all_of(
           values.cbegin(), values.cend(),
-          [base](absl::optional<uint64_t> val) { return val == base; })) {
+          [base](std::optional<uint64_t> val) { return val == base; })) {
     return std::string();
   }
 
@@ -325,8 +325,8 @@
 }
 
 void FixedLengthDeltaEncoder::CalculateMinAndMaxDeltas(
-    absl::optional<uint64_t> base,
-    const std::vector<absl::optional<uint64_t>>& values,
+    std::optional<uint64_t> base,
+    const std::vector<std::optional<uint64_t>>& values,
     uint64_t bit_width,
     uint64_t* max_unsigned_delta_out,
     uint64_t* max_pos_signed_delta_out,
@@ -342,7 +342,7 @@
   uint64_t max_pos_signed_delta = 0;
   uint64_t min_neg_signed_delta = 0;
 
-  absl::optional<uint64_t> prev = base;
+  std::optional<uint64_t> prev = base;
   for (size_t i = 0; i < values.size(); ++i) {
     if (!values[i].has_value()) {
       continue;
@@ -394,8 +394,8 @@
 
 FixedLengthDeltaEncoder::FixedLengthDeltaEncoder(
     const FixedLengthEncodingParameters& params,
-    absl::optional<uint64_t> base,
-    const std::vector<absl::optional<uint64_t>>& values,
+    std::optional<uint64_t> base,
+    const std::vector<std::optional<uint64_t>>& values,
     size_t existent_values_count)
     : params_(params), base_(base), values_(values) {
   RTC_DCHECK(!values_.empty());
@@ -408,13 +408,13 @@
 
   if (params_.values_optional()) {
     // Encode which values exist and which don't.
-    for (absl::optional<uint64_t> value : values_) {
+    for (std::optional<uint64_t> value : values_) {
       writer_->WriteBits(value.has_value() ? 1u : 0u, 1);
     }
   }
 
-  absl::optional<uint64_t> previous = base_;
-  for (absl::optional<uint64_t> value : values_) {
+  std::optional<uint64_t> previous = base_;
+  for (std::optional<uint64_t> value : values_) {
     if (!value.has_value()) {
       RTC_DCHECK(params_.values_optional());
       continue;
@@ -459,7 +459,7 @@
     return values_.size() * params_.delta_width_bits();
   } else {
     RTC_DCHECK_EQ(std::count_if(values_.begin(), values_.end(),
-                                [](absl::optional<uint64_t> val) {
+                                [](std::optional<uint64_t> val) {
                                   return val.has_value();
                                 }),
                   existent_values_count);
@@ -564,9 +564,9 @@
   // original values, this will return the sequence of original values.
   // If an error occurs (can happen if `input` is corrupt), an empty
   // vector will be returned.
-  static std::vector<absl::optional<uint64_t>> DecodeDeltas(
+  static std::vector<std::optional<uint64_t>> DecodeDeltas(
       absl::string_view input,
-      absl::optional<uint64_t> base,
+      std::optional<uint64_t> base,
       size_t num_of_deltas);
 
   FixedLengthDeltaDecoder(const FixedLengthDeltaDecoder&) = delete;
@@ -583,7 +583,7 @@
   // examined and guaranteed.
   static std::unique_ptr<FixedLengthDeltaDecoder> Create(
       absl::string_view input,
-      absl::optional<uint64_t> base,
+      std::optional<uint64_t> base,
       size_t num_of_deltas);
 
   // FixedLengthDeltaDecoder objects are to be created by DecodeDeltas() and
@@ -594,11 +594,11 @@
   // of `reader`'s underlying buffer.
   FixedLengthDeltaDecoder(BitstreamReader reader,
                           const FixedLengthEncodingParameters& params,
-                          absl::optional<uint64_t> base,
+                          std::optional<uint64_t> base,
                           size_t num_of_deltas);
 
   // Perform the decoding using the parameters given to the ctor.
-  std::vector<absl::optional<uint64_t>> Decode();
+  std::vector<std::optional<uint64_t>> Decode();
 
   // Add `delta` to `base` to produce the next value in a sequence.
   // The delta is applied as signed/unsigned depending on the parameters
@@ -621,7 +621,7 @@
   // The encoding scheme assumes that at least one value is transmitted OOB,
   // so that the first value can be encoded as a delta from that OOB value,
   // which is `base_`.
-  const absl::optional<uint64_t> base_;
+  const std::optional<uint64_t> base_;
 
   // The number of values to be known to be decoded.
   const size_t num_of_deltas_;
@@ -641,13 +641,13 @@
              EncodingType::kFixedSizeSignedDeltasEarlyWrapAndOptSupported;
 }
 
-std::vector<absl::optional<uint64_t>> FixedLengthDeltaDecoder::DecodeDeltas(
+std::vector<std::optional<uint64_t>> FixedLengthDeltaDecoder::DecodeDeltas(
     absl::string_view input,
-    absl::optional<uint64_t> base,
+    std::optional<uint64_t> base,
     size_t num_of_deltas) {
   auto decoder = FixedLengthDeltaDecoder::Create(input, base, num_of_deltas);
   if (!decoder) {
-    return std::vector<absl::optional<uint64_t>>();
+    return std::vector<std::optional<uint64_t>>();
   }
 
   return decoder->Decode();
@@ -655,7 +655,7 @@
 
 std::unique_ptr<FixedLengthDeltaDecoder> FixedLengthDeltaDecoder::Create(
     absl::string_view input,
-    absl::optional<uint64_t> base,
+    std::optional<uint64_t> base,
     size_t num_of_deltas) {
   BitstreamReader reader(input);
   // Encoding type
@@ -715,7 +715,7 @@
 FixedLengthDeltaDecoder::FixedLengthDeltaDecoder(
     BitstreamReader reader,
     const FixedLengthEncodingParameters& params,
-    absl::optional<uint64_t> base,
+    std::optional<uint64_t> base,
     size_t num_of_deltas)
     : reader_(reader),
       params_(params),
@@ -724,7 +724,7 @@
   RTC_DCHECK(reader_.Ok());
 }
 
-std::vector<absl::optional<uint64_t>> FixedLengthDeltaDecoder::Decode() {
+std::vector<std::optional<uint64_t>> FixedLengthDeltaDecoder::Decode() {
   RTC_DCHECK(reader_.Ok());
   std::vector<bool> existing_values(num_of_deltas_);
   if (params_.values_optional()) {
@@ -735,8 +735,8 @@
     std::fill(existing_values.begin(), existing_values.end(), true);
   }
 
-  absl::optional<uint64_t> previous = base_;
-  std::vector<absl::optional<uint64_t>> values(num_of_deltas_);
+  std::optional<uint64_t> previous = base_;
+  std::vector<std::optional<uint64_t>> values(num_of_deltas_);
 
   for (size_t i = 0; i < num_of_deltas_; ++i) {
     if (!existing_values[i]) {
@@ -800,22 +800,21 @@
 
 }  // namespace
 
-std::string EncodeDeltas(absl::optional<uint64_t> base,
-                         const std::vector<absl::optional<uint64_t>>& values) {
+std::string EncodeDeltas(std::optional<uint64_t> base,
+                         const std::vector<std::optional<uint64_t>>& values) {
   // TODO(eladalon): Support additional encodings.
   return FixedLengthDeltaEncoder::EncodeDeltas(base, values);
 }
 
-std::vector<absl::optional<uint64_t>> DecodeDeltas(
-    absl::string_view input,
-    absl::optional<uint64_t> base,
-    size_t num_of_deltas) {
+std::vector<std::optional<uint64_t>> DecodeDeltas(absl::string_view input,
+                                                  std::optional<uint64_t> base,
+                                                  size_t num_of_deltas) {
   RTC_DCHECK_GT(num_of_deltas, 0);  // Allows empty vector to indicate error.
 
   // The empty string is a special case indicating that all values were equal
   // to the base.
   if (input.empty()) {
-    std::vector<absl::optional<uint64_t>> result(num_of_deltas);
+    std::vector<std::optional<uint64_t>> result(num_of_deltas);
     std::fill(result.begin(), result.end(), base);
     return result;
   }
@@ -825,7 +824,7 @@
   }
 
   RTC_LOG(LS_WARNING) << "Could not decode delta-encoded stream.";
-  return std::vector<absl::optional<uint64_t>>();
+  return std::vector<std::optional<uint64_t>>();
 }
 
 void SetFixedLengthEncoderDeltaSignednessForTesting(bool signedness) {
diff --git a/logging/rtc_event_log/encoder/delta_encoding.h b/logging/rtc_event_log/encoder/delta_encoding.h
index 779cdc6..d097de7 100644
--- a/logging/rtc_event_log/encoder/delta_encoding.h
+++ b/logging/rtc_event_log/encoder/delta_encoding.h
@@ -14,11 +14,11 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 
 namespace webrtc {
 
@@ -29,8 +29,8 @@
 // be provided separately to the decoder.
 // This function never fails.
 // TODO(eladalon): Split into optional and non-optional variants (efficiency).
-std::string EncodeDeltas(absl::optional<uint64_t> base,
-                         const std::vector<absl::optional<uint64_t>>& values);
+std::string EncodeDeltas(std::optional<uint64_t> base,
+                         const std::vector<std::optional<uint64_t>>& values);
 
 // EncodeDeltas() and DecodeDeltas() are inverse operations;
 // invoking DecodeDeltas() over the output of EncodeDeltas(), will return
@@ -39,10 +39,9 @@
 // of `num_of_deltas` elements based on `base`, the function returns an empty
 // vector, which signals an error.
 // TODO(eladalon): Split into optional and non-optional variants (efficiency).
-std::vector<absl::optional<uint64_t>> DecodeDeltas(
-    absl::string_view input,
-    absl::optional<uint64_t> base,
-    size_t num_of_deltas);
+std::vector<std::optional<uint64_t>> DecodeDeltas(absl::string_view input,
+                                                  std::optional<uint64_t> base,
+                                                  size_t num_of_deltas);
 
 }  // namespace webrtc
 
diff --git a/logging/rtc_event_log/encoder/delta_encoding_unittest.cc b/logging/rtc_event_log/encoder/delta_encoding_unittest.cc
index 3a27b24..6f46ff9 100644
--- a/logging/rtc_event_log/encoder/delta_encoding_unittest.cc
+++ b/logging/rtc_event_log/encoder/delta_encoding_unittest.cc
@@ -16,11 +16,11 @@
 #include <cstring>
 #include <limits>
 #include <numeric>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "rtc_base/arraysize.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/random.h"
@@ -71,53 +71,52 @@
 // that it is equal to the original input.
 // If `encoded_string` is non-null, the encoded result will also be written
 // into it.
-void TestEncodingAndDecoding(
-    absl::optional<uint64_t> base,
-    const std::vector<absl::optional<uint64_t>>& values,
-    std::string* encoded_string = nullptr) {
+void TestEncodingAndDecoding(std::optional<uint64_t> base,
+                             const std::vector<std::optional<uint64_t>>& values,
+                             std::string* encoded_string = nullptr) {
   const std::string encoded = EncodeDeltas(base, values);
   if (encoded_string) {
     *encoded_string = encoded;
   }
 
-  const std::vector<absl::optional<uint64_t>> decoded =
+  const std::vector<std::optional<uint64_t>> decoded =
       DecodeDeltas(encoded, base, values.size());
 
   EXPECT_EQ(decoded, values);
 }
 
-std::vector<absl::optional<uint64_t>> CreateSequenceByFirstValue(
+std::vector<std::optional<uint64_t>> CreateSequenceByFirstValue(
     uint64_t first,
     size_t sequence_length) {
-  std::vector<absl::optional<uint64_t>> sequence(sequence_length);
+  std::vector<std::optional<uint64_t>> sequence(sequence_length);
   std::iota(sequence.begin(), sequence.end(), first);
   return sequence;
 }
 
-std::vector<absl::optional<uint64_t>> CreateSequenceByLastValue(
+std::vector<std::optional<uint64_t>> CreateSequenceByLastValue(
     uint64_t last,
     size_t num_values) {
   const uint64_t first = last - num_values + 1;
-  std::vector<absl::optional<uint64_t>> result(num_values);
+  std::vector<std::optional<uint64_t>> result(num_values);
   std::iota(result.begin(), result.end(), first);
   return result;
 }
 
 // If `sequence_length` is greater than the number of deltas, the sequence of
 // deltas will wrap around.
-std::vector<absl::optional<uint64_t>> CreateSequenceByOptionalDeltas(
+std::vector<std::optional<uint64_t>> CreateSequenceByOptionalDeltas(
     uint64_t first,
-    const std::vector<absl::optional<uint64_t>>& deltas,
+    const std::vector<std::optional<uint64_t>>& deltas,
     size_t sequence_length) {
   RTC_DCHECK_GE(sequence_length, 1);
 
-  std::vector<absl::optional<uint64_t>> sequence(sequence_length);
+  std::vector<std::optional<uint64_t>> sequence(sequence_length);
 
   uint64_t previous = first;
   for (size_t i = 0, next_delta_index = 0; i < sequence.size(); ++i) {
     if (deltas[next_delta_index].has_value()) {
       sequence[i] =
-          absl::optional<uint64_t>(previous + deltas[next_delta_index].value());
+          std::optional<uint64_t>(previous + deltas[next_delta_index].value());
       previous = sequence[i].value();
     }
     next_delta_index = (next_delta_index + 1) % deltas.size();
@@ -129,7 +128,7 @@
 size_t EncodingLengthUpperBound(size_t delta_max_bit_width,
                                 size_t num_of_deltas,
                                 DeltaSignedness signedness_override) {
-  absl::optional<size_t> smallest_header_size_bytes;
+  std::optional<size_t> smallest_header_size_bytes;
   switch (signedness_override) {
     case DeltaSignedness::kNoOverride:
     case DeltaSignedness::kForceUnsigned:
@@ -146,14 +145,14 @@
 
 // If `sequence_length` is greater than the number of deltas, the sequence of
 // deltas will wrap around.
-std::vector<absl::optional<uint64_t>> CreateSequenceByDeltas(
+std::vector<std::optional<uint64_t>> CreateSequenceByDeltas(
     uint64_t first,
     const std::vector<uint64_t>& deltas,
     size_t sequence_length) {
   RTC_DCHECK(!deltas.empty());
-  std::vector<absl::optional<uint64_t>> optional_deltas(deltas.size());
+  std::vector<std::optional<uint64_t>> optional_deltas(deltas.size());
   for (size_t i = 0; i < deltas.size(); ++i) {
-    optional_deltas[i] = absl::optional<uint64_t>(deltas[i]);
+    optional_deltas[i] = std::optional<uint64_t>(deltas[i]);
   }
   return CreateSequenceByOptionalDeltas(first, optional_deltas,
                                         sequence_length);
@@ -190,8 +189,8 @@
 };
 
 TEST_P(DeltaEncodingTest, AllValuesEqualToExistentBaseValue) {
-  const absl::optional<uint64_t> base(3432);
-  std::vector<absl::optional<uint64_t>> values(num_of_values_);
+  const std::optional<uint64_t> base(3432);
+  std::vector<std::optional<uint64_t>> values(num_of_values_);
   std::fill(values.begin(), values.end(), base);
   std::string encoded;
   TestEncodingAndDecoding(base, values, &encoded);
@@ -206,8 +205,8 @@
     return;  // Test irrelevant for this case.
   }
 
-  const absl::optional<uint64_t> base;
-  std::vector<absl::optional<uint64_t>> values(num_of_values_);
+  const std::optional<uint64_t> base;
+  std::vector<std::optional<uint64_t>> values(num_of_values_);
   std::fill(values.begin(), values.end(), base);
   std::string encoded;
   TestEncodingAndDecoding(base, values, &encoded);
@@ -222,8 +221,8 @@
     return;  // Test irrelevant for this case.
   }
 
-  const absl::optional<uint64_t> base;
-  std::vector<absl::optional<uint64_t>> values(num_of_values_);
+  const std::optional<uint64_t> base;
+  std::vector<std::optional<uint64_t>> values(num_of_values_);
 
   Random prng(Seed());
 
@@ -248,7 +247,7 @@
 }
 
 TEST_P(DeltaEncodingTest, MinDeltaNoWrapAround) {
-  const absl::optional<uint64_t> base(3432);
+  const std::optional<uint64_t> base(3432);
 
   auto values = CreateSequenceByFirstValue(base.value() + 1, num_of_values_);
   ASSERT_GT(values[values.size() - 1], base) << "Sanity; must not wrap around";
@@ -256,7 +255,7 @@
   if (optional_values_) {
     // Arbitrarily make one of the values non-existent, to force
     // optional-supporting encoding.
-    values[0] = absl::optional<uint64_t>();
+    values[0] = std::optional<uint64_t>();
   }
 
   TestEncodingAndDecoding(base, values);
@@ -264,7 +263,7 @@
 
 TEST_P(DeltaEncodingTest, BigDeltaNoWrapAround) {
   const uint64_t kBigDelta = 132828;
-  const absl::optional<uint64_t> base(3432);
+  const std::optional<uint64_t> base(3432);
 
   auto values =
       CreateSequenceByFirstValue(base.value() + kBigDelta, num_of_values_);
@@ -273,14 +272,14 @@
   if (optional_values_) {
     // Arbitrarily make one of the values non-existent, to force
     // optional-supporting encoding.
-    values[0] = absl::optional<uint64_t>();
+    values[0] = std::optional<uint64_t>();
   }
 
   TestEncodingAndDecoding(base, values);
 }
 
 TEST_P(DeltaEncodingTest, MaxDeltaNoWrapAround) {
-  const absl::optional<uint64_t> base(3432);
+  const std::optional<uint64_t> base(3432);
 
   auto values = CreateSequenceByLastValue(std::numeric_limits<uint64_t>::max(),
                                           num_of_values_);
@@ -289,7 +288,7 @@
   if (optional_values_) {
     // Arbitrarily make one of the values non-existent, to force
     // optional-supporting encoding.
-    values[0] = absl::optional<uint64_t>();
+    values[0] = std::optional<uint64_t>();
   }
 
   TestEncodingAndDecoding(base, values);
@@ -300,7 +299,7 @@
     return;  // Inapplicable
   }
 
-  const absl::optional<uint64_t> base(std::numeric_limits<uint64_t>::max());
+  const std::optional<uint64_t> base(std::numeric_limits<uint64_t>::max());
 
   auto values = CreateSequenceByDeltas(*base, {1, 10, 3}, num_of_values_);
   ASSERT_LT(values[0], base) << "Sanity; must wrap around";
@@ -308,7 +307,7 @@
   if (optional_values_) {
     // Arbitrarily make one of the values non-existent, to force
     // optional-supporting encoding.
-    values[1] = absl::optional<uint64_t>();
+    values[1] = std::optional<uint64_t>();
   }
 
   TestEncodingAndDecoding(base, values);
@@ -319,7 +318,7 @@
     return;  // Inapplicable.
   }
 
-  const absl::optional<uint64_t> base(std::numeric_limits<uint64_t>::max() - 2);
+  const std::optional<uint64_t> base(std::numeric_limits<uint64_t>::max() - 2);
 
   auto values = CreateSequenceByDeltas(*base, {1, 10, 3}, num_of_values_);
   ASSERT_LT(values[values.size() - 1], values[0]) << "Sanity; must wrap around";
@@ -328,7 +327,7 @@
     // Arbitrarily make one of the values non-existent, to force
     // optional-supporting encoding.
     RTC_DCHECK_GT(values.size() - 1, 1u);  // Wrap around not cancelled.
-    values[1] = absl::optional<uint64_t>();
+    values[1] = std::optional<uint64_t>();
   }
 
   TestEncodingAndDecoding(base, values);
@@ -345,8 +344,8 @@
   }
 
   const uint64_t kBigDelta = 132828;
-  const absl::optional<uint64_t> base(std::numeric_limits<uint64_t>::max() -
-                                      kBigDelta + 3);
+  const std::optional<uint64_t> base(std::numeric_limits<uint64_t>::max() -
+                                     kBigDelta + 3);
 
   auto values =
       CreateSequenceByFirstValue(base.value() + kBigDelta, num_of_values_);
@@ -355,7 +354,7 @@
   if (optional_values_) {
     // Arbitrarily make one of the values non-existent, to force
     // optional-supporting encoding.
-    values[1] = absl::optional<uint64_t>();
+    values[1] = std::optional<uint64_t>();
   }
 
   TestEncodingAndDecoding(base, values);
@@ -367,8 +366,8 @@
   }
 
   const uint64_t kBigDelta = 132828;
-  const absl::optional<uint64_t> base(std::numeric_limits<uint64_t>::max() -
-                                      kBigDelta + 3);
+  const std::optional<uint64_t> base(std::numeric_limits<uint64_t>::max() -
+                                     kBigDelta + 3);
 
   auto values = CreateSequenceByFirstValue(std::numeric_limits<uint64_t>::max(),
                                            num_of_values_);
@@ -378,7 +377,7 @@
     // Arbitrarily make one of the values non-existent, to force
     // optional-supporting encoding.
     RTC_DCHECK_GT(values.size() - 1, 1u);  // Wrap around not cancelled.
-    values[1] = absl::optional<uint64_t>();
+    values[1] = std::optional<uint64_t>();
   }
 
   TestEncodingAndDecoding(base, values);
@@ -392,13 +391,13 @@
     return;  // Inapplicable
   }
 
-  const absl::optional<uint64_t> base(3432);
+  const std::optional<uint64_t> base(3432);
   auto values = CreateSequenceByFirstValue(*base - 1, num_of_values_);
 
   if (optional_values_) {
     // Arbitrarily make one of the values non-existent, to force
     // optional-supporting encoding.
-    values[1] = absl::optional<uint64_t>();
+    values[1] = std::optional<uint64_t>();
   }
 
   TestEncodingAndDecoding(base, values);
@@ -409,7 +408,7 @@
     return;  // Inapplicable.
   }
 
-  const absl::optional<uint64_t> base(3432);
+  const std::optional<uint64_t> base(3432);
 
   auto values = CreateSequenceByDeltas(
       *base, {0, std::numeric_limits<uint64_t>::max(), 3}, num_of_values_);
@@ -419,7 +418,7 @@
     // Arbitrarily make one of the values non-existent, to force
     // optional-supporting encoding.
     RTC_DCHECK_GT(values.size() - 1, 1u);  // Wrap around not cancelled.
-    values[1] = absl::optional<uint64_t>();
+    values[1] = std::optional<uint64_t>();
   }
 
   TestEncodingAndDecoding(base, values);
@@ -429,7 +428,7 @@
 // already covered by AllValuesEqualToExistentBaseValue, but it doesn't hurt to
 // test again. For all other cases, we have a new test.
 TEST_P(DeltaEncodingTest, ZeroDelta) {
-  const absl::optional<uint64_t> base(3432);
+  const std::optional<uint64_t> base(3432);
 
   // Arbitrary sequence of deltas with intentional zero deltas, as well as
   // consecutive zeros.
@@ -440,7 +439,7 @@
   if (optional_values_) {
     // Arbitrarily make one of the values non-existent, to force
     // optional-supporting encoding.
-    values[0] = absl::optional<uint64_t>();
+    values[0] = std::optional<uint64_t>();
   }
 
   TestEncodingAndDecoding(base, values);
@@ -604,10 +603,10 @@
 };
 
 TEST_P(DeltaEncodingFuzzerLikeTest, Test) {
-  const absl::optional<uint64_t> base(3432);
+  const std::optional<uint64_t> base(3432);
 
   Random prng(Seed());
-  std::vector<absl::optional<uint64_t>> deltas(num_of_values_);
+  std::vector<std::optional<uint64_t>> deltas(num_of_values_);
   for (size_t i = 0; i < deltas.size(); ++i) {
     if (!optional_values_ || prng.Rand<bool>()) {
       deltas[i] = RandomWithMaxBitWidth(&prng, delta_max_bit_width_);
@@ -646,10 +645,10 @@
 TEST_F(DeltaEncodingSpecificEdgeCasesTest, SignedDeltaWithOnlyTopBitOn) {
   MaybeSetSignedness(DeltaSignedness::kForceSigned);
 
-  const absl::optional<uint64_t> base(3432);
+  const std::optional<uint64_t> base(3432);
 
   const uint64_t delta = static_cast<uint64_t>(1) << 63;
-  const std::vector<absl::optional<uint64_t>> values = {base.value() + delta};
+  const std::vector<std::optional<uint64_t>> values = {base.value() + delta};
 
   TestEncodingAndDecoding(base, values);
 }
@@ -657,9 +656,9 @@
 TEST_F(DeltaEncodingSpecificEdgeCasesTest, MaximumUnsignedDelta) {
   MaybeSetSignedness(DeltaSignedness::kForceUnsigned);
 
-  const absl::optional<uint64_t> base((static_cast<uint64_t>(1) << 63) + 0x123);
+  const std::optional<uint64_t> base((static_cast<uint64_t>(1) << 63) + 0x123);
 
-  const std::vector<absl::optional<uint64_t>> values = {base.value() - 1};
+  const std::vector<std::optional<uint64_t>> values = {base.value() - 1};
 
   TestEncodingAndDecoding(base, values);
 }
@@ -675,7 +674,7 @@
                                   : ((static_cast<uint64_t>(1) << width) - 1);
 
   const uint64_t base = wrap_around ? 1u : (0xf82d3 & value_mask);
-  const std::vector<absl::optional<uint64_t>> values = {
+  const std::vector<std::optional<uint64_t>> values = {
       (base - 1u) & value_mask, (base - 2u) & value_mask,
       (base - 3u) & value_mask};
 
diff --git a/logging/rtc_event_log/encoder/optional_blob_encoding.cc b/logging/rtc_event_log/encoder/optional_blob_encoding.cc
index a0078ee..f93d3ad 100644
--- a/logging/rtc_event_log/encoder/optional_blob_encoding.cc
+++ b/logging/rtc_event_log/encoder/optional_blob_encoding.cc
@@ -12,11 +12,11 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "rtc_base/bit_buffer.h"
 #include "rtc_base/bitstream_reader.h"
 #include "rtc_base/checks.h"
@@ -24,7 +24,7 @@
 namespace webrtc {
 
 std::string EncodeOptionalBlobs(
-    const std::vector<absl::optional<std::string>>& blobs) {
+    const std::vector<std::optional<std::string>>& blobs) {
   if (blobs.empty()) {
     return {};
   }
@@ -79,10 +79,10 @@
   return std::string(buffer.data(), buffer.data() + bytes_written);
 }
 
-std::vector<absl::optional<std::string>> DecodeOptionalBlobs(
+std::vector<std::optional<std::string>> DecodeOptionalBlobs(
     absl::string_view encoded_blobs,
     size_t num_of_blobs) {
-  std::vector<absl::optional<std::string>> res(num_of_blobs);
+  std::vector<std::optional<std::string>> res(num_of_blobs);
   if (encoded_blobs.empty() || num_of_blobs == 0) {
     return res;
   }
diff --git a/logging/rtc_event_log/encoder/optional_blob_encoding.h b/logging/rtc_event_log/encoder/optional_blob_encoding.h
index 32f5278..cd40523 100644
--- a/logging/rtc_event_log/encoder/optional_blob_encoding.h
+++ b/logging/rtc_event_log/encoder/optional_blob_encoding.h
@@ -13,11 +13,11 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 
 namespace webrtc {
 
@@ -26,12 +26,12 @@
 // in a way that would allow us to separate them again on the decoding side.
 // EncodeOptionalBlobs() may not fail but may return an empty string
 std::string EncodeOptionalBlobs(
-    const std::vector<absl::optional<std::string>>& blobs);
+    const std::vector<std::optional<std::string>>& blobs);
 
 // Calling DecodeOptionalBlobs() on an empty string, or with `num_of_blobs` set
 // to 0, is an error. DecodeOptionalBlobs() returns an empty vector if it fails,
 // which can happen if `encoded_blobs` is corrupted.
-std::vector<absl::optional<std::string>> DecodeOptionalBlobs(
+std::vector<std::optional<std::string>> DecodeOptionalBlobs(
     absl::string_view encoded_blobs,
     size_t num_of_blobs);
 
diff --git a/logging/rtc_event_log/encoder/optional_blob_encoding_unittest.cc b/logging/rtc_event_log/encoder/optional_blob_encoding_unittest.cc
index 8f0e484..7e7bccd 100644
--- a/logging/rtc_event_log/encoder/optional_blob_encoding_unittest.cc
+++ b/logging/rtc_event_log/encoder/optional_blob_encoding_unittest.cc
@@ -11,10 +11,10 @@
 #include "logging/rtc_event_log/encoder/optional_blob_encoding.h"
 
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
 
@@ -72,7 +72,7 @@
 }
 
 TEST(OptionalBlobEncoding, SomeBlobsPresent) {
-  std::string encoded = EncodeOptionalBlobs({"a", absl::nullopt, "c"});
+  std::string encoded = EncodeOptionalBlobs({"a", std::nullopt, "c"});
   std::string expected = BitBuilder()
                              .Bit(0)
                              .Bit(1)
@@ -87,12 +87,12 @@
 
 TEST(OptionalBlobEncoding, NoBlobsPresent) {
   std::string encoded =
-      EncodeOptionalBlobs({absl::nullopt, absl::nullopt, absl::nullopt});
+      EncodeOptionalBlobs({std::nullopt, std::nullopt, std::nullopt});
   EXPECT_THAT(encoded, IsEmpty());
 }
 
 TEST(OptionalBlobEncoding, EmptyBlobsPresent) {
-  std::string encoded = EncodeOptionalBlobs({absl::nullopt, "", absl::nullopt});
+  std::string encoded = EncodeOptionalBlobs({std::nullopt, "", std::nullopt});
   std::string expected = BitBuilder()
                              .Bit(0)
                              .Bit(0)
@@ -148,13 +148,12 @@
                             .Bytes({0x01, 'c'})
                             .AsString();
   auto decoded = DecodeOptionalBlobs(encoded, 3);
-  EXPECT_THAT(decoded, ElementsAre("a", absl::nullopt, "c"));
+  EXPECT_THAT(decoded, ElementsAre("a", std::nullopt, "c"));
 }
 
 TEST(OptionalBlobDecoding, NoBlobsPresent) {
   auto decoded = DecodeOptionalBlobs("", 3);
-  EXPECT_THAT(decoded,
-              ElementsAre(absl::nullopt, absl::nullopt, absl::nullopt));
+  EXPECT_THAT(decoded, ElementsAre(std::nullopt, std::nullopt, std::nullopt));
 }
 
 TEST(OptionalBlobDecoding, EmptyBlobsPresent) {
@@ -167,7 +166,7 @@
                             .Bytes({0x0})
                             .AsString();
   auto decoded = DecodeOptionalBlobs(encoded, 3);
-  EXPECT_THAT(decoded, ElementsAre(absl::nullopt, "", absl::nullopt));
+  EXPECT_THAT(decoded, ElementsAre(std::nullopt, "", std::nullopt));
 }
 
 TEST(OptionalBlobDecoding, ZeroBlobs) {
diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc
index 44ef8b3..506abf4 100644
--- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc
+++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc
@@ -15,10 +15,10 @@
 #include <cstdint>
 #include <deque>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/candidate.h"
 #include "api/rtc_event_log/rtc_event.h"
diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc
index 6c57328..ce3b71b 100644
--- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc
+++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc
@@ -16,11 +16,11 @@
 #include <deque>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/candidate.h"
 #include "api/dtls_transport_interface.h"
@@ -366,7 +366,7 @@
 
   // Delta encoding
   proto_batch->set_number_of_deltas(batch.size() - 1);
-  std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
+  std::vector<std::optional<uint64_t>> values(batch.size() - 1);
   std::string encoded_deltas;
 
   // timestamp_ms
@@ -417,7 +417,7 @@
   proto_batch->set_padding_size(base_event->padding_length());
 
   // Add header extensions (base event).
-  absl::optional<uint64_t> base_transport_sequence_number;
+  std::optional<uint64_t> base_transport_sequence_number;
   {
     uint16_t seqnum;
     if (base_event->template GetExtension<TransportSequenceNumber>(&seqnum)) {
@@ -426,7 +426,7 @@
     }
   }
 
-  absl::optional<uint64_t> unsigned_base_transmission_time_offset;
+  std::optional<uint64_t> unsigned_base_transmission_time_offset;
   {
     int32_t offset;
     if (base_event->template GetExtension<TransmissionOffset>(&offset)) {
@@ -435,7 +435,7 @@
     }
   }
 
-  absl::optional<uint64_t> base_absolute_send_time;
+  std::optional<uint64_t> base_absolute_send_time;
   {
     uint32_t sendtime;
     if (base_event->template GetExtension<AbsoluteSendTime>(&sendtime)) {
@@ -444,7 +444,7 @@
     }
   }
 
-  absl::optional<uint64_t> base_video_rotation;
+  std::optional<uint64_t> base_video_rotation;
   {
     VideoRotation video_rotation;
     if (base_event->template GetExtension<VideoOrientation>(&video_rotation)) {
@@ -454,8 +454,8 @@
     }
   }
 
-  absl::optional<uint64_t> base_audio_level;
-  absl::optional<uint64_t> base_voice_activity;
+  std::optional<uint64_t> base_audio_level;
+  std::optional<uint64_t> base_voice_activity;
   {
     AudioLevel audio_level;
     if (base_event->template GetExtension<AudioLevelExtension>(&audio_level)) {
@@ -496,7 +496,7 @@
 
   // Delta encoding
   proto_batch->set_number_of_deltas(batch.size() - 1);
-  std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
+  std::vector<std::optional<uint64_t>> values(batch.size() - 1);
   std::string encoded_deltas;
 
   // timestamp_ms (event)
@@ -998,7 +998,7 @@
     proto_batch->set_frame_length_ms(
         base_event->config().frame_length_ms.value());
   }
-  absl::optional<uint64_t> base_uplink_packet_loss_fraction;
+  std::optional<uint64_t> base_uplink_packet_loss_fraction;
   if (base_event->config().uplink_packet_loss_fraction.has_value()) {
     base_uplink_packet_loss_fraction = ConvertPacketLossFractionToProtoFormat(
         base_event->config().uplink_packet_loss_fraction.value());
@@ -1020,7 +1020,7 @@
 
   // Delta encoding
   proto_batch->set_number_of_deltas(batch.size() - 1);
-  std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
+  std::vector<std::optional<uint64_t>> values(batch.size() - 1);
   std::string encoded_deltas;
 
   // timestamp_ms
@@ -1042,10 +1042,10 @@
       values[i].reset();
     }
   }
-  const absl::optional<uint64_t> unsigned_base_bitrate_bps =
+  const std::optional<uint64_t> unsigned_base_bitrate_bps =
       base_event->config().bitrate_bps.has_value()
           ? ToUnsigned(base_event->config().bitrate_bps.value())
-          : absl::optional<uint64_t>();
+          : std::optional<uint64_t>();
   encoded_deltas = EncodeDeltas(unsigned_base_bitrate_bps, values);
   if (!encoded_deltas.empty()) {
     proto_batch->set_bitrate_bps_deltas(encoded_deltas);
@@ -1060,10 +1060,10 @@
       values[i].reset();
     }
   }
-  const absl::optional<uint64_t> unsigned_base_frame_length_ms =
+  const std::optional<uint64_t> unsigned_base_frame_length_ms =
       base_event->config().frame_length_ms.has_value()
           ? ToUnsigned(base_event->config().frame_length_ms.value())
-          : absl::optional<uint64_t>();
+          : std::optional<uint64_t>();
   encoded_deltas = EncodeDeltas(unsigned_base_frame_length_ms, values);
   if (!encoded_deltas.empty()) {
     proto_batch->set_frame_length_ms_deltas(encoded_deltas);
@@ -1107,7 +1107,7 @@
   // num_channels
   for (size_t i = 0; i < values.size(); ++i) {
     const RtcEventAudioNetworkAdaptation* event = batch[i + 1];
-    const absl::optional<size_t> num_channels = event->config().num_channels;
+    const std::optional<size_t> num_channels = event->config().num_channels;
     if (num_channels.has_value()) {
       // Since the number of channels is always greater than 0, we can encode
       // N channels as N-1, thereby making sure that we get smaller deltas.
@@ -1122,7 +1122,7 @@
   }
   // In the base event, N channels encoded as N channels, but for delta
   // compression purposes, also shifted down by 1.
-  absl::optional<size_t> shifted_base_num_channels;
+  std::optional<size_t> shifted_base_num_channels;
   if (base_event->config().num_channels.has_value()) {
     RTC_DCHECK_GT(base_event->config().num_channels.value(), 0u);
     shifted_base_num_channels = base_event->config().num_channels.value() - 1;
@@ -1151,7 +1151,7 @@
 
   // Delta encoding
   proto_batch->set_number_of_deltas(batch.size() - 1);
-  std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
+  std::vector<std::optional<uint64_t>> values(batch.size() - 1);
   std::string encoded_deltas;
 
   // timestamp_ms
@@ -1198,7 +1198,7 @@
 
   // Delta encoding
   proto_batch->set_number_of_deltas(batch.size() - 1);
-  std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
+  std::vector<std::optional<uint64_t>> values(batch.size() - 1);
   std::string encoded_deltas;
 
   // timestamp_ms
@@ -1290,7 +1290,7 @@
 
   // Delta encoding
   proto_batch->set_number_of_deltas(batch.size() - 1);
-  std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
+  std::vector<std::optional<uint64_t>> values(batch.size() - 1);
   std::string encoded_deltas;
 
   // timestamp_ms
@@ -1347,7 +1347,7 @@
 
   // Delta encoding
   proto_batch->set_number_of_deltas(batch.size() - 1);
-  std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
+  std::vector<std::optional<uint64_t>> values(batch.size() - 1);
   std::string encoded_deltas;
 
   // timestamp_ms
@@ -1478,13 +1478,13 @@
 
   proto_batch->set_timestamp_ms(base_event->timestamp_ms());
 
-  absl::optional<uint64_t> base_link_capacity_lower;
+  std::optional<uint64_t> base_link_capacity_lower;
   if (base_event->link_capacity_lower_.IsFinite()) {
     base_link_capacity_lower =
         base_event->link_capacity_lower_.kbps<uint32_t>();
     proto_batch->set_link_capacity_lower_kbps(*base_link_capacity_lower);
   }
-  absl::optional<uint64_t> base_link_capacity_upper;
+  std::optional<uint64_t> base_link_capacity_upper;
   if (base_event->link_capacity_upper_.IsFinite()) {
     base_link_capacity_upper =
         base_event->link_capacity_upper_.kbps<uint32_t>();
@@ -1496,7 +1496,7 @@
 
   // Delta encoding
   proto_batch->set_number_of_deltas(batch.size() - 1);
-  std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
+  std::vector<std::optional<uint64_t>> values(batch.size() - 1);
   std::string encoded_deltas;
 
   // timestamp_ms
@@ -1589,7 +1589,7 @@
 
   // Delta encoding
   proto_batch->set_number_of_deltas(batch.size() - 1);
-  std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
+  std::vector<std::optional<uint64_t>> values(batch.size() - 1);
   std::string encoded_deltas;
 
   // timestamp_ms
@@ -1682,7 +1682,7 @@
 
   // Delta encoding
   proto_batch->set_number_of_deltas(batch.size() - 1);
-  std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
+  std::vector<std::optional<uint64_t>> values(batch.size() - 1);
   std::string encoded_deltas;
 
   if (batch.size() == 1) {
@@ -1756,7 +1756,7 @@
 
   // Delta encoding
   proto_batch->set_number_of_deltas(batch.size() - 1);
-  std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
+  std::vector<std::optional<uint64_t>> values(batch.size() - 1);
   std::string encoded_deltas;
 
   if (batch.size() == 1) {
@@ -1807,7 +1807,7 @@
   proto_batch->set_timestamp_ms(base_event->timestamp_ms());
   proto_batch->set_packet_number(base_event->packet_number());
   proto_batch->set_acked_packet_number(base_event->acked_packet_number());
-  absl::optional<uint64_t> base_receive_timestamp;
+  std::optional<uint64_t> base_receive_timestamp;
   if (base_event->receive_acked_packet_time_ms()) {
     int64_t receive_acked_packet_time_ms =
         base_event->receive_acked_packet_time_ms().value();
@@ -1817,7 +1817,7 @@
 
   // Delta encoding
   proto_batch->set_number_of_deltas(batch.size() - 1);
-  std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
+  std::vector<std::optional<uint64_t>> values(batch.size() - 1);
   std::string encoded_deltas;
 
   if (batch.size() == 1) {
@@ -1862,7 +1862,7 @@
     if (event->receive_acked_packet_time_ms()) {
       values[i] = ToUnsigned(event->receive_acked_packet_time_ms().value());
     } else {
-      values[i] = absl::nullopt;
+      values[i] = std::nullopt;
     }
   }
   encoded_deltas = EncodeDeltas(base_receive_timestamp, values);
diff --git a/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.cc b/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.cc
index 0ad49df..166dedd 100644
--- a/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.cc
+++ b/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.cc
@@ -12,8 +12,8 @@
 
 #include <algorithm>
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
 #include "rtc_base/checks.h"
@@ -110,7 +110,7 @@
   return header;
 }
 
-absl::optional<FixedLengthEncodingParametersV3>
+std::optional<FixedLengthEncodingParametersV3>
 FixedLengthEncodingParametersV3::ParseDeltaHeader(uint64_t header,
                                                   uint64_t value_bit_width) {
   uint64_t delta_bit_width = (header & ((1u << 6) - 1)) + 1;
@@ -119,7 +119,7 @@
 
   if (header >= (1u << 8)) {
     RTC_LOG(LS_ERROR) << "Failed to parse delta header; unread bits remaining.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (!ValidParameters(delta_bit_width, signed_deltas, values_optional,
@@ -129,7 +129,7 @@
                       << delta_bit_width << " signed_deltas=" << signed_deltas
                       << " values_optional=" << values_optional
                       << " value_bit_width=" << value_bit_width;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return FixedLengthEncodingParametersV3(delta_bit_width, signed_deltas,
diff --git a/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.h b/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.h
index ce227a0..3640b20 100644
--- a/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.h
+++ b/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.h
@@ -12,8 +12,8 @@
 #define LOGGING_RTC_EVENT_LOG_EVENTS_FIXED_LENGTH_ENCODING_PARAMETERS_V3_H_
 
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
 
@@ -38,7 +38,7 @@
       rtc::ArrayView<const uint64_t> values,
       uint64_t value_bit_width,
       bool values_optional);
-  static absl::optional<FixedLengthEncodingParametersV3> ParseDeltaHeader(
+  static std::optional<FixedLengthEncodingParametersV3> ParseDeltaHeader(
       uint64_t header,
       uint64_t value_bit_width);
 
diff --git a/logging/rtc_event_log/events/rtc_event_field_encoding.cc b/logging/rtc_event_log/events/rtc_event_field_encoding.cc
index 87132c9..08f7e84 100644
--- a/logging/rtc_event_log/events/rtc_event_field_encoding.cc
+++ b/logging/rtc_event_log/events/rtc_event_field_encoding.cc
@@ -13,11 +13,11 @@
 #include <cstddef>
 #include <cstdint>
 #include <limits>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/rtc_event_log/rtc_event.h"
 #include "logging/rtc_event_log/encoder/bit_writer.h"
@@ -88,7 +88,7 @@
   return std::string();
 }
 
-absl::optional<FieldType> ConvertFieldType(uint64_t value) {
+std::optional<FieldType> ConvertFieldType(uint64_t value) {
   switch (value) {
     case static_cast<uint64_t>(FieldType::kFixed8):
       return FieldType::kFixed8;
@@ -101,7 +101,7 @@
     case static_cast<uint64_t>(FieldType::kString):
       return FieldType::kString;
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
diff --git a/logging/rtc_event_log/events/rtc_event_field_encoding.h b/logging/rtc_event_log/events/rtc_event_field_encoding.h
index 21a4b41..26c7f15 100644
--- a/logging/rtc_event_log/events/rtc_event_field_encoding.h
+++ b/logging/rtc_event_log/events/rtc_event_field_encoding.h
@@ -13,12 +13,12 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/rtc_event_log/rtc_event.h"
 #include "logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.h"
@@ -130,13 +130,13 @@
           typename E,
           std::enable_if_t<std::is_integral<T>::value, bool> = true>
 ValuesWithPositions ExtractRtcEventMember(rtc::ArrayView<const RtcEvent*> batch,
-                                          const absl::optional<T> E::*member) {
+                                          const std::optional<T> E::*member) {
   ValuesWithPositions result;
   result.position_mask.reserve(batch.size());
   result.values.reserve(batch.size());
   for (const RtcEvent* event : batch) {
     RTC_CHECK_EQ(event->GetType(), E::kType);
-    absl::optional<T> field = static_cast<const E*>(event)->*member;
+    std::optional<T> field = static_cast<const E*>(event)->*member;
     result.position_mask.push_back(field.has_value());
     if (field.has_value()) {
       result.values.push_back(EncodeAsUnsigned(field.value()));
diff --git a/logging/rtc_event_log/events/rtc_event_field_encoding_parser.cc b/logging/rtc_event_log/events/rtc_event_field_encoding_parser.cc
index f55b25d..f4e1bb1 100644
--- a/logging/rtc_event_log/events/rtc_event_field_encoding_parser.cc
+++ b/logging/rtc_event_log/events/rtc_event_field_encoding_parser.cc
@@ -14,10 +14,10 @@
 #include <algorithm>
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 #include <tuple>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "logging/rtc_event_log/encoder/var_int.h"
 #include "logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.h"
@@ -28,7 +28,7 @@
 #include "rtc_base/checks.h"
 
 namespace {
-absl::optional<webrtc::FieldType> ConvertFieldType(uint64_t value) {
+std::optional<webrtc::FieldType> ConvertFieldType(uint64_t value) {
   switch (value) {
     case static_cast<uint64_t>(webrtc::FieldType::kFixed8):
       return webrtc::FieldType::kFixed8;
@@ -41,7 +41,7 @@
     case static_cast<uint64_t>(webrtc::FieldType::kString):
       return webrtc::FieldType::kString;
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 }  // namespace
@@ -209,7 +209,7 @@
                                            __FILE__, __LINE__);
     // NB: value_bit_width may be incorrect for the field, if this isn't the
     // field we are looking for.
-    absl::optional<FixedLengthEncodingParametersV3> delta_header =
+    std::optional<FixedLengthEncodingParametersV3> delta_header =
         FixedLengthEncodingParametersV3::ParseDeltaHeader(header_value,
                                                           value_bit_width);
     if (!delta_header.has_value()) {
@@ -318,7 +318,7 @@
                                              __FILE__, __LINE__);
       // Split tag into field ID and field type.
       field_id = field_tag >> 3;
-      absl::optional<FieldType> conversion = ConvertFieldType(field_tag & 7u);
+      std::optional<FieldType> conversion = ConvertFieldType(field_tag & 7u);
       if (!conversion.has_value())
         return RtcEventLogParseStatus::Error("Failed to parse field type",
                                              __FILE__, __LINE__);
diff --git a/logging/rtc_event_log/events/rtc_event_field_encoding_parser.h b/logging/rtc_event_log/events/rtc_event_field_encoding_parser.h
index a47cc3c..de95160 100644
--- a/logging/rtc_event_log/events/rtc_event_field_encoding_parser.h
+++ b/logging/rtc_event_log/events/rtc_event_field_encoding_parser.h
@@ -13,13 +13,13 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
 #include "absl/base/attributes.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/units/timestamp.h"
 #include "logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.h"
@@ -140,7 +140,7 @@
 ABSL_MUST_USE_RESULT RtcEventLogParseStatus
 PopulateRtcEventMember(const rtc::ArrayView<uint8_t> positions,
                        const rtc::ArrayView<uint64_t> values,
-                       absl::optional<T> E::*member,
+                       std::optional<T> E::*member,
                        rtc::ArrayView<E> output) {
   size_t batch_size = positions.size();
   RTC_CHECK_EQ(output.size(), batch_size);
@@ -152,7 +152,7 @@
       output[i].*member = DecodeFromUnsignedToType<T>(value_it);
       ++value_it;
     } else {
-      output[i].*member = absl::nullopt;
+      output[i].*member = std::nullopt;
     }
   }
   RTC_CHECK(value_it == values.end());
diff --git a/logging/rtc_event_log/events/rtc_event_field_encoding_unittest.cc b/logging/rtc_event_log/events/rtc_event_field_encoding_unittest.cc
index 62004e8..5fd6928 100644
--- a/logging/rtc_event_log/events/rtc_event_field_encoding_unittest.cc
+++ b/logging/rtc_event_log/events/rtc_event_field_encoding_unittest.cc
@@ -12,13 +12,13 @@
 #include <cstdint>
 #include <cstdio>
 #include <limits>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <type_traits>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/rtc_event_log/rtc_event.h"
 #include "logging/rtc_event_log/encoder/var_int.h"
@@ -93,12 +93,12 @@
 
 template <typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
 size_t ExpectedEncodingSize(const FieldParameters& params,
-                            const std::vector<absl::optional<T>>& v,
+                            const std::vector<std::optional<T>>& v,
                             size_t expected_bits_per_delta) {
   size_t num_existing_values =
-      v.size() - std::count(v.begin(), v.end(), absl::nullopt);
+      v.size() - std::count(v.begin(), v.end(), std::nullopt);
   auto first_existing_value = std::find_if(
-      v.begin(), v.end(), [](absl::optional<T> x) { return x.has_value(); });
+      v.begin(), v.end(), [](std::optional<T> x) { return x.has_value(); });
   if (num_existing_values == 0)
     return 0;
 
@@ -116,7 +116,7 @@
       (num_existing_values == v.size() ? 0 : (v.size() + 7) / 8);
   // Check if there is an element *not* equal to base.
   if (std::all_of(v.begin(), v.end(),
-                  [base](absl::optional<T> x) { return x == base; })) {
+                  [base](std::optional<T> x) { return x == base; })) {
     return tag_size + base_size + delta_header_size + positions_size;
   }
 
@@ -164,8 +164,8 @@
                uint32_t unsigned32,
                int64_t signed64,
                uint64_t unsigned64,
-               absl::optional<int32_t> optional_signed32,
-               absl::optional<int64_t> optional_signed64,
+               std::optional<int32_t> optional_signed32,
+               std::optional<int64_t> optional_signed64,
                uint32_t wrapping21,
                absl::string_view string)
       : b_(b),
@@ -211,8 +211,8 @@
   const uint32_t unsigned32_;
   const int64_t signed64_;
   const uint64_t unsigned64_;
-  const absl::optional<int32_t> optional_signed32_ = absl::nullopt;
-  const absl::optional<int64_t> optional_signed64_ = absl::nullopt;
+  const std::optional<int32_t> optional_signed32_ = std::nullopt;
+  const std::optional<int64_t> optional_signed64_ = std::nullopt;
   const uint32_t wrapping21_ = 0;
   const std::string string_;
 };
@@ -242,8 +242,8 @@
       const std::vector<uint32_t>& unsigned32_values,
       const std::vector<int64_t>& signed64_values,
       const std::vector<uint64_t>& unsigned64_values,
-      const std::vector<absl::optional<int32_t>>& optional32_values,
-      const std::vector<absl::optional<int64_t>>& optional64_values,
+      const std::vector<std::optional<int32_t>>& optional32_values,
+      const std::vector<std::optional<int64_t>>& optional64_values,
       const std::vector<uint32_t>& wrapping21_values,
       const std::vector<std::string>& string_values) {
     size_t size = bool_values.size();
@@ -340,7 +340,7 @@
   template <typename T>
   void ParseAndVerifyOptionalField(
       const FieldParameters& params,
-      const std::vector<absl::optional<T>>& expected_values,
+      const std::vector<std::optional<T>>& expected_values,
       size_t expected_bits_per_delta,
       size_t expected_skipped_bytes = 0) {
     size_t expected_size =
@@ -361,7 +361,7 @@
                   expected_values[i].value());
         ++value_it;
       } else {
-        EXPECT_EQ(absl::nullopt, expected_values[i]);
+        EXPECT_EQ(std::nullopt, expected_values[i]);
       }
     }
     EXPECT_EQ(value_it, values.end());
@@ -409,8 +409,8 @@
   std::vector<uint32_t> unsigned32_values = {123456789};
   std::vector<int64_t> signed64_values = {-9876543210};
   std::vector<uint64_t> unsigned64_values = {9876543210};
-  std::vector<absl::optional<int32_t>> optional32_values = {kInt32Min};
-  std::vector<absl::optional<int64_t>> optional64_values = {kInt64Max};
+  std::vector<std::optional<int32_t>> optional32_values = {kInt32Min};
+  std::vector<std::optional<int64_t>> optional64_values = {kInt64Max};
   std::vector<uint32_t> wrapping21_values = {(1 << 21) - 1};
   std::vector<std::string> string_values = {"foo"};
 
@@ -478,9 +478,9 @@
                                           -9876543210};
   std::vector<uint64_t> unsigned64_values = {9876543210, 9876543210, 9876543210,
                                              9876543210};
-  std::vector<absl::optional<int32_t>> optional32_values = {
+  std::vector<std::optional<int32_t>> optional32_values = {
       kInt32Min, kInt32Min, kInt32Min, kInt32Min};
-  std::vector<absl::optional<int64_t>> optional64_values = {
+  std::vector<std::optional<int64_t>> optional64_values = {
       kInt64Max, kInt64Max, kInt64Max, kInt64Max};
   std::vector<uint32_t> wrapping21_values = {(1 << 21) - 1, (1 << 21) - 1,
                                              (1 << 21) - 1, (1 << 21) - 1};
@@ -547,9 +547,9 @@
   std::vector<int64_t> signed64_values = {kInt64Max - 1, kInt64Max, kInt64Min,
                                           kInt64Min + 1};
   std::vector<uint64_t> unsigned64_values = {kUint64Max - 1, kUint64Max, 0, 1};
-  std::vector<absl::optional<int32_t>> optional32_values = {
+  std::vector<std::optional<int32_t>> optional32_values = {
       kInt32Max - 1, kInt32Max, kInt32Min, kInt32Min + 1};
-  std::vector<absl::optional<int64_t>> optional64_values = {
+  std::vector<std::optional<int64_t>> optional64_values = {
       kInt64Max - 1, kInt64Max, kInt64Min, kInt64Min + 1};
   std::vector<uint32_t> wrapping21_values = {(1 << 21) - 2, (1 << 21) - 1, 0,
                                              1};
@@ -618,9 +618,9 @@
   std::vector<int64_t> signed64_values = {kInt64Min + 1, kInt64Min, kInt64Max,
                                           kInt64Max - 1};
   std::vector<uint64_t> unsigned64_values = {1, 0, kUint64Max, kUint64Max - 1};
-  std::vector<absl::optional<int32_t>> optional32_values = {
+  std::vector<std::optional<int32_t>> optional32_values = {
       kInt32Min + 1, kInt32Min, kInt32Max, kInt32Max - 1};
-  std::vector<absl::optional<int64_t>> optional64_values = {
+  std::vector<std::optional<int64_t>> optional64_values = {
       kInt64Min + 1, kInt64Min, kInt64Max, kInt64Max - 1};
   std::vector<uint32_t> wrapping21_values = {1, 0, (1 << 21) - 1,
                                              (1 << 21) - 2};
@@ -690,10 +690,10 @@
   std::vector<uint32_t> unsigned32_values = {0, kUint32Max / 2};
   std::vector<int64_t> signed64_values = {kInt64Min / 2, kInt64Max / 2};
   std::vector<uint64_t> unsigned64_values = {0, kUint64Max / 2};
-  std::vector<absl::optional<int32_t>> optional32_values = {kInt32Max / 2,
-                                                            kInt32Min / 2};
-  std::vector<absl::optional<int64_t>> optional64_values = {kInt64Min / 2,
-                                                            kInt64Max / 2};
+  std::vector<std::optional<int32_t>> optional32_values = {kInt32Max / 2,
+                                                           kInt32Min / 2};
+  std::vector<std::optional<int64_t>> optional64_values = {kInt64Min / 2,
+                                                           kInt64Max / 2};
   std::vector<uint32_t> wrapping21_values = {0, 1 << 20};
   std::vector<std::string> string_values = {"foo", "bar"};
 
@@ -769,10 +769,10 @@
   std::vector<uint32_t> unsigned32_values = {0, kUint32Max / 2};
   std::vector<int64_t> signed64_values = {kInt64Min / 2, kInt64Max / 2};
   std::vector<uint64_t> unsigned64_values = {0, kUint64Max / 2};
-  std::vector<absl::optional<int32_t>> optional32_values = {kInt32Max / 2,
-                                                            kInt32Min / 2};
-  std::vector<absl::optional<int64_t>> optional64_values = {kInt64Min / 2,
-                                                            kInt64Max / 2};
+  std::vector<std::optional<int32_t>> optional32_values = {kInt32Max / 2,
+                                                           kInt32Min / 2};
+  std::vector<std::optional<int64_t>> optional64_values = {kInt64Min / 2,
+                                                           kInt64Max / 2};
   std::vector<uint32_t> wrapping21_values = {0, 1 << 20};
   std::vector<std::string> string_values = {"foo", "foo"};
 
@@ -821,10 +821,10 @@
 }
 
 TEST_F(RtcEventFieldTest, OptionalFields) {
-  std::vector<absl::optional<int32_t>> optional32_values = {
-      2, absl::nullopt, 4, absl::nullopt, 6, absl::nullopt};
-  std::vector<absl::optional<int64_t>> optional64_values = {
-      absl::nullopt, 1024, absl::nullopt, 1025, absl::nullopt, 1026};
+  std::vector<std::optional<int32_t>> optional32_values = {
+      2, std::nullopt, 4, std::nullopt, 6, std::nullopt};
+  std::vector<std::optional<int64_t>> optional64_values = {
+      std::nullopt, 1024, std::nullopt, 1025, std::nullopt, 1026};
   std::vector<uint32_t> wrapping21_values = {(1 << 21) - 3, 0, 2, 5, 5, 6};
 
   for (size_t i = 0; i < optional32_values.size(); i++) {
@@ -860,11 +860,11 @@
 }
 
 TEST_F(RtcEventFieldTest, AllNulloptTreatedAsMissing) {
-  std::vector<absl::optional<int32_t>> optional32_values = {
-      absl::nullopt, absl::nullopt, absl::nullopt,
-      absl::nullopt, absl::nullopt, absl::nullopt};
-  std::vector<absl::optional<int64_t>> optional64_values = {
-      absl::nullopt, 1024, absl::nullopt, 1025, absl::nullopt, 1026};
+  std::vector<std::optional<int32_t>> optional32_values = {
+      std::nullopt, std::nullopt, std::nullopt,
+      std::nullopt, std::nullopt, std::nullopt};
+  std::vector<std::optional<int64_t>> optional64_values = {
+      std::nullopt, 1024, std::nullopt, 1025, std::nullopt, 1026};
 
   for (size_t i = 0; i < optional32_values.size(); i++) {
     batch_.push_back(new RtcTestEvent(0, 0, 0, 0, 0, optional32_values[i],
diff --git a/logging/rtc_event_log/events/rtc_event_generic_ack_received.cc b/logging/rtc_event_log/events/rtc_event_generic_ack_received.cc
index e5aa375..39dda3d 100644
--- a/logging/rtc_event_log/events/rtc_event_generic_ack_received.cc
+++ b/logging/rtc_event_log/events/rtc_event_generic_ack_received.cc
@@ -12,10 +12,10 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "absl/memory/memory.h"
-#include "absl/types/optional.h"
 #include "api/rtc_event_log/rtc_event.h"
 #include "rtc_base/time_utils.h"
 
@@ -40,7 +40,7 @@
     int64_t timestamp_us,
     int64_t packet_number,
     int64_t acked_packet_number,
-    absl::optional<int64_t> receive_acked_packet_time_ms)
+    std::optional<int64_t> receive_acked_packet_time_ms)
     : RtcEvent(timestamp_us),
       packet_number_(packet_number),
       acked_packet_number_(acked_packet_number),
diff --git a/logging/rtc_event_log/events/rtc_event_generic_ack_received.h b/logging/rtc_event_log/events/rtc_event_generic_ack_received.h
index 16b2a9e..62ee5c0 100644
--- a/logging/rtc_event_log/events/rtc_event_generic_ack_received.h
+++ b/logging/rtc_event_log/events/rtc_event_generic_ack_received.h
@@ -13,11 +13,11 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/rtc_event_log/rtc_event.h"
 #include "api/units/timestamp.h"
@@ -30,7 +30,7 @@
   LoggedGenericAckReceived(Timestamp timestamp,
                            int64_t packet_number,
                            int64_t acked_packet_number,
-                           absl::optional<int64_t> receive_acked_packet_time_ms)
+                           std::optional<int64_t> receive_acked_packet_time_ms)
       : timestamp(timestamp),
         packet_number(packet_number),
         acked_packet_number(acked_packet_number),
@@ -43,7 +43,7 @@
   Timestamp timestamp = Timestamp::MinusInfinity();
   int64_t packet_number;
   int64_t acked_packet_number;
-  absl::optional<int64_t> receive_acked_packet_time_ms;
+  std::optional<int64_t> receive_acked_packet_time_ms;
 };
 
 struct AckedPacket {
@@ -52,7 +52,7 @@
 
   // The time where the packet was received. Not every ACK will
   // include the receive timestamp.
-  absl::optional<int64_t> receive_acked_packet_time_ms;
+  std::optional<int64_t> receive_acked_packet_time_ms;
 };
 
 class RtcEventGenericAckReceived final : public RtcEvent {
@@ -79,7 +79,7 @@
   int64_t acked_packet_number() const { return acked_packet_number_; }
 
   // Timestamp when the `acked_packet_number` was received by the remote side.
-  absl::optional<int64_t> receive_acked_packet_time_ms() const {
+  std::optional<int64_t> receive_acked_packet_time_ms() const {
     return receive_acked_packet_time_ms_;
   }
 
@@ -108,11 +108,11 @@
       int64_t timestamp_us,
       int64_t packet_number,
       int64_t acked_packet_number,
-      absl::optional<int64_t> receive_acked_packet_time_ms);
+      std::optional<int64_t> receive_acked_packet_time_ms);
 
   const int64_t packet_number_;
   const int64_t acked_packet_number_;
-  const absl::optional<int64_t> receive_acked_packet_time_ms_;
+  const std::optional<int64_t> receive_acked_packet_time_ms_;
 };
 
 }  // namespace webrtc
diff --git a/logging/rtc_event_log/events/rtc_event_remote_estimate.h b/logging/rtc_event_log/events/rtc_event_remote_estimate.h
index 78366aa..d01abe7 100644
--- a/logging/rtc_event_log/events/rtc_event_remote_estimate.h
+++ b/logging/rtc_event_log/events/rtc_event_remote_estimate.h
@@ -11,11 +11,11 @@
 #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_REMOTE_ESTIMATE_H_
 
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/rtc_event_log/rtc_event.h"
 #include "api/units/data_rate.h"
@@ -32,8 +32,8 @@
   Timestamp log_time() const { return timestamp; }
 
   Timestamp timestamp = Timestamp::MinusInfinity();
-  absl::optional<DataRate> link_capacity_lower;
-  absl::optional<DataRate> link_capacity_upper;
+  std::optional<DataRate> link_capacity_lower;
+  std::optional<DataRate> link_capacity_upper;
 };
 
 class RtcEventRemoteEstimate final : public RtcEvent {
diff --git a/logging/rtc_event_log/rtc_event_log2rtp_dump.cc b/logging/rtc_event_log/rtc_event_log2rtp_dump.cc
index df30fe3..aac5fff 100644
--- a/logging/rtc_event_log/rtc_event_log2rtp_dump.cc
+++ b/logging/rtc_event_log/rtc_event_log2rtp_dump.cc
@@ -13,6 +13,7 @@
 
 #include <iostream>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -20,7 +21,6 @@
 #include "absl/flags/parse.h"
 #include "absl/flags/usage.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/rtp_headers.h"
 #include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
@@ -75,14 +75,14 @@
 // The empty string must be validated as true, because it is the default value
 // of the command-line flag. In this case, no value is written to the output
 // variable.
-absl::optional<uint32_t> ParseSsrc(absl::string_view str) {
+std::optional<uint32_t> ParseSsrc(absl::string_view str) {
   // Set `base` to 0 to allow detection of the "0x" prefix in case hex is used.
   return rtc::StringToNumber<uint32_t>(str, 0);
 }
 
 bool ShouldSkipStream(MediaType media_type,
                       uint32_t ssrc,
-                      absl::optional<uint32_t> ssrc_filter) {
+                      std::optional<uint32_t> ssrc_filter) {
   if (!absl::GetFlag(FLAGS_audio) && media_type == MediaType::AUDIO)
     return true;
   if (!absl::GetFlag(FLAGS_video) && media_type == MediaType::VIDEO)
@@ -167,7 +167,7 @@
   std::string input_file = args[1];
   std::string output_file = args[2];
 
-  absl::optional<uint32_t> ssrc_filter;
+  std::optional<uint32_t> ssrc_filter;
   if (!absl::GetFlag(FLAGS_ssrc).empty()) {
     ssrc_filter = ParseSsrc(absl::GetFlag(FLAGS_ssrc));
     RTC_CHECK(ssrc_filter.has_value()) << "Failed to read SSRC filter flag.";
diff --git a/logging/rtc_event_log/rtc_event_log_parser.cc b/logging/rtc_event_log/rtc_event_log_parser.cc
index f1e4878..7197c97 100644
--- a/logging/rtc_event_log/rtc_event_log_parser.cc
+++ b/logging/rtc_event_log/rtc_event_log_parser.cc
@@ -16,6 +16,7 @@
 #include <algorithm>
 #include <limits>
 #include <map>
+#include <optional>
 #include <set>
 #include <string>
 #include <tuple>
@@ -23,7 +24,6 @@
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/candidate.h"
 #include "api/dtls_transport_interface.h"
 #include "api/rtc_event_log/rtc_event.h"
@@ -431,59 +431,59 @@
   }
 
   // timestamp_ms (event)
-  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
+  std::vector<std::optional<uint64_t>> timestamp_ms_values =
       DecodeDeltas(proto.timestamp_ms_deltas(),
                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
 
   // marker (RTP base)
-  std::vector<absl::optional<uint64_t>> marker_values =
+  std::vector<std::optional<uint64_t>> marker_values =
       DecodeDeltas(proto.marker_deltas(), proto.marker(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(marker_values.size(), number_of_deltas);
 
   // payload_type (RTP base)
-  std::vector<absl::optional<uint64_t>> payload_type_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> payload_type_values = DecodeDeltas(
       proto.payload_type_deltas(), proto.payload_type(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(payload_type_values.size(), number_of_deltas);
 
   // sequence_number (RTP base)
-  std::vector<absl::optional<uint64_t>> sequence_number_values =
+  std::vector<std::optional<uint64_t>> sequence_number_values =
       DecodeDeltas(proto.sequence_number_deltas(), proto.sequence_number(),
                    number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(sequence_number_values.size(), number_of_deltas);
 
   // rtp_timestamp (RTP base)
-  std::vector<absl::optional<uint64_t>> rtp_timestamp_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> rtp_timestamp_values = DecodeDeltas(
       proto.rtp_timestamp_deltas(), proto.rtp_timestamp(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(rtp_timestamp_values.size(), number_of_deltas);
 
   // ssrc (RTP base)
-  std::vector<absl::optional<uint64_t>> ssrc_values =
+  std::vector<std::optional<uint64_t>> ssrc_values =
       DecodeDeltas(proto.ssrc_deltas(), proto.ssrc(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(ssrc_values.size(), number_of_deltas);
 
   // payload_size (RTP base)
-  std::vector<absl::optional<uint64_t>> payload_size_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> payload_size_values = DecodeDeltas(
       proto.payload_size_deltas(), proto.payload_size(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(payload_size_values.size(), number_of_deltas);
 
   // header_size (RTP base)
-  std::vector<absl::optional<uint64_t>> header_size_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> header_size_values = DecodeDeltas(
       proto.header_size_deltas(), proto.header_size(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(header_size_values.size(), number_of_deltas);
 
   // padding_size (RTP base)
-  std::vector<absl::optional<uint64_t>> padding_size_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> padding_size_values = DecodeDeltas(
       proto.padding_size_deltas(), proto.padding_size(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(padding_size_values.size(), number_of_deltas);
 
   // transport_sequence_number (RTP extension)
-  std::vector<absl::optional<uint64_t>> transport_sequence_number_values;
+  std::vector<std::optional<uint64_t>> transport_sequence_number_values;
   {
-    const absl::optional<uint64_t> base_transport_sequence_number =
+    const std::optional<uint64_t> base_transport_sequence_number =
         proto.has_transport_sequence_number()
             ? proto.transport_sequence_number()
-            : absl::optional<uint64_t>();
+            : std::optional<uint64_t>();
     transport_sequence_number_values =
         DecodeDeltas(proto.transport_sequence_number_deltas(),
                      base_transport_sequence_number, number_of_deltas);
@@ -492,12 +492,12 @@
   }
 
   // transmission_time_offset (RTP extension)
-  std::vector<absl::optional<uint64_t>> transmission_time_offset_values;
+  std::vector<std::optional<uint64_t>> transmission_time_offset_values;
   {
-    const absl::optional<uint64_t> unsigned_base_transmission_time_offset =
+    const std::optional<uint64_t> unsigned_base_transmission_time_offset =
         proto.has_transmission_time_offset()
             ? ToUnsigned(proto.transmission_time_offset())
-            : absl::optional<uint64_t>();
+            : std::optional<uint64_t>();
     transmission_time_offset_values =
         DecodeDeltas(proto.transmission_time_offset_deltas(),
                      unsigned_base_transmission_time_offset, number_of_deltas);
@@ -506,11 +506,11 @@
   }
 
   // absolute_send_time (RTP extension)
-  std::vector<absl::optional<uint64_t>> absolute_send_time_values;
+  std::vector<std::optional<uint64_t>> absolute_send_time_values;
   {
-    const absl::optional<uint64_t> base_absolute_send_time =
+    const std::optional<uint64_t> base_absolute_send_time =
         proto.has_absolute_send_time() ? proto.absolute_send_time()
-                                       : absl::optional<uint64_t>();
+                                       : std::optional<uint64_t>();
     absolute_send_time_values =
         DecodeDeltas(proto.absolute_send_time_deltas(), base_absolute_send_time,
                      number_of_deltas);
@@ -519,11 +519,11 @@
   }
 
   // video_rotation (RTP extension)
-  std::vector<absl::optional<uint64_t>> video_rotation_values;
+  std::vector<std::optional<uint64_t>> video_rotation_values;
   {
-    const absl::optional<uint64_t> base_video_rotation =
+    const std::optional<uint64_t> base_video_rotation =
         proto.has_video_rotation() ? proto.video_rotation()
-                                   : absl::optional<uint64_t>();
+                                   : std::optional<uint64_t>();
     video_rotation_values = DecodeDeltas(proto.video_rotation_deltas(),
                                          base_video_rotation, number_of_deltas);
     RTC_PARSE_CHECK_OR_RETURN_EQ(video_rotation_values.size(),
@@ -531,22 +531,22 @@
   }
 
   // audio_level (RTP extension)
-  std::vector<absl::optional<uint64_t>> audio_level_values;
+  std::vector<std::optional<uint64_t>> audio_level_values;
   {
-    const absl::optional<uint64_t> base_audio_level =
+    const std::optional<uint64_t> base_audio_level =
         proto.has_audio_level() ? proto.audio_level()
-                                : absl::optional<uint64_t>();
+                                : std::optional<uint64_t>();
     audio_level_values = DecodeDeltas(proto.audio_level_deltas(),
                                       base_audio_level, number_of_deltas);
     RTC_PARSE_CHECK_OR_RETURN_EQ(audio_level_values.size(), number_of_deltas);
   }
 
   // voice_activity (RTP extension)
-  std::vector<absl::optional<uint64_t>> voice_activity_values;
+  std::vector<std::optional<uint64_t>> voice_activity_values;
   {
-    const absl::optional<uint64_t> base_voice_activity =
+    const std::optional<uint64_t> base_voice_activity =
         proto.has_voice_activity() ? proto.voice_activity()
-                                   : absl::optional<uint64_t>();
+                                   : std::optional<uint64_t>();
     voice_activity_values = DecodeDeltas(proto.voice_activity_deltas(),
                                          base_voice_activity, number_of_deltas);
     RTC_PARSE_CHECK_OR_RETURN_EQ(voice_activity_values.size(),
@@ -659,7 +659,7 @@
   }
 
   // timestamp_ms
-  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
+  std::vector<std::optional<uint64_t>> timestamp_ms_values =
       DecodeDeltas(proto.timestamp_ms_deltas(),
                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
@@ -1178,7 +1178,7 @@
   }
 
   // Compute file size.
-  absl::optional<size_t> file_size = file.FileSize();
+  std::optional<size_t> file_size = file.FileSize();
   RTC_PARSE_CHECK_OR_RETURN(file_size.has_value());
   RTC_PARSE_CHECK_OR_RETURN_GE(*file_size, 0u);
   RTC_PARSE_CHECK_OR_RETURN_LE(*file_size, kMaxLogSize);
@@ -2685,14 +2685,14 @@
   LoggedRemoteEstimateEvent base_event;
   base_event.timestamp = Timestamp::Millis(proto.timestamp_ms());
 
-  absl::optional<uint64_t> base_link_capacity_lower_kbps;
+  std::optional<uint64_t> base_link_capacity_lower_kbps;
   if (proto.has_link_capacity_lower_kbps()) {
     base_link_capacity_lower_kbps = proto.link_capacity_lower_kbps();
     base_event.link_capacity_lower =
         DataRate::KilobitsPerSec(proto.link_capacity_lower_kbps());
   }
 
-  absl::optional<uint64_t> base_link_capacity_upper_kbps;
+  std::optional<uint64_t> base_link_capacity_upper_kbps;
   if (proto.has_link_capacity_upper_kbps()) {
     base_link_capacity_upper_kbps = proto.link_capacity_upper_kbps();
     base_event.link_capacity_upper =
@@ -2759,13 +2759,13 @@
   }
 
   // timestamp_ms
-  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
+  std::vector<std::optional<uint64_t>> timestamp_ms_values =
       DecodeDeltas(proto.timestamp_ms_deltas(),
                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
 
   // local_ssrc
-  std::vector<absl::optional<uint64_t>> local_ssrc_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> local_ssrc_values = DecodeDeltas(
       proto.local_ssrc_deltas(), proto.local_ssrc(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(local_ssrc_values.size(), number_of_deltas);
 
@@ -2806,18 +2806,18 @@
   }
 
   // timestamp_ms
-  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
+  std::vector<std::optional<uint64_t>> timestamp_ms_values =
       DecodeDeltas(proto.timestamp_ms_deltas(),
                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
 
   // remote_ssrc
-  std::vector<absl::optional<uint64_t>> remote_ssrc_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> remote_ssrc_values = DecodeDeltas(
       proto.remote_ssrc_deltas(), proto.remote_ssrc(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(remote_ssrc_values.size(), number_of_deltas);
 
   // minimum_delay_ms
-  std::vector<absl::optional<uint64_t>> minimum_delay_ms_values =
+  std::vector<std::optional<uint64_t>> minimum_delay_ms_values =
       DecodeDeltas(proto.minimum_delay_ms_deltas(),
                    ToUnsigned(proto.minimum_delay_ms()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(minimum_delay_ms_values.size(),
@@ -2910,23 +2910,23 @@
   }
 
   // timestamp_ms
-  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
+  std::vector<std::optional<uint64_t>> timestamp_ms_values =
       DecodeDeltas(proto.timestamp_ms_deltas(),
                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
 
   // bitrate_bps
-  std::vector<absl::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
       proto.bitrate_bps_deltas(), proto.bitrate_bps(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(bitrate_bps_values.size(), number_of_deltas);
 
   // fraction_loss
-  std::vector<absl::optional<uint64_t>> fraction_loss_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> fraction_loss_values = DecodeDeltas(
       proto.fraction_loss_deltas(), proto.fraction_loss(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(fraction_loss_values.size(), number_of_deltas);
 
   // total_packets
-  std::vector<absl::optional<uint64_t>> total_packets_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> total_packets_values = DecodeDeltas(
       proto.total_packets_deltas(), proto.total_packets(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(total_packets_values.size(), number_of_deltas);
 
@@ -2980,18 +2980,18 @@
   }
 
   // timestamp_ms
-  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
+  std::vector<std::optional<uint64_t>> timestamp_ms_values =
       DecodeDeltas(proto.timestamp_ms_deltas(),
                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
 
   // bitrate_bps
-  std::vector<absl::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
       proto.bitrate_bps_deltas(), proto.bitrate_bps(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(bitrate_bps_values.size(), number_of_deltas);
 
   // detector_state
-  std::vector<absl::optional<uint64_t>> detector_state_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> detector_state_values = DecodeDeltas(
       proto.detector_state_deltas(),
       static_cast<uint64_t>(proto.detector_state()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(detector_state_values.size(), number_of_deltas);
@@ -3103,40 +3103,40 @@
   }
 
   // timestamp_ms
-  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
+  std::vector<std::optional<uint64_t>> timestamp_ms_values =
       DecodeDeltas(proto.timestamp_ms_deltas(),
                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
 
   // SSRC
-  std::vector<absl::optional<uint64_t>> ssrc_values =
+  std::vector<std::optional<uint64_t>> ssrc_values =
       DecodeDeltas(proto.ssrc_deltas(), proto.ssrc(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(ssrc_values.size(), number_of_deltas);
 
   // render_time_ms
-  std::vector<absl::optional<uint64_t>> render_time_ms_values =
+  std::vector<std::optional<uint64_t>> render_time_ms_values =
       DecodeDeltas(proto.render_time_ms_deltas(),
                    ToUnsigned(proto.render_time_ms()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(render_time_ms_values.size(), number_of_deltas);
 
   // width
-  std::vector<absl::optional<uint64_t>> width_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> width_values = DecodeDeltas(
       proto.width_deltas(), ToUnsigned(proto.width()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(width_values.size(), number_of_deltas);
 
   // height
-  std::vector<absl::optional<uint64_t>> height_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> height_values = DecodeDeltas(
       proto.height_deltas(), ToUnsigned(proto.height()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(height_values.size(), number_of_deltas);
 
   // codec
-  std::vector<absl::optional<uint64_t>> codec_values =
+  std::vector<std::optional<uint64_t>> codec_values =
       DecodeDeltas(proto.codec_deltas(), static_cast<uint64_t>(proto.codec()),
                    number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(codec_values.size(), number_of_deltas);
 
   // qp
-  std::vector<absl::optional<uint64_t>> qp_values =
+  std::vector<std::optional<uint64_t>> qp_values =
       DecodeDeltas(proto.qp_deltas(), proto.qp(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(qp_values.size(), number_of_deltas);
 
@@ -3187,7 +3187,7 @@
   RTC_PARSE_CHECK_OR_RETURN(proto.has_acked_packet_number());
   // receive_acked_packet_time_ms is optional.
 
-  absl::optional<int64_t> base_receive_acked_packet_time_ms;
+  std::optional<int64_t> base_receive_acked_packet_time_ms;
   if (proto.has_receive_acked_packet_time_ms()) {
     base_receive_acked_packet_time_ms = proto.receive_acked_packet_time_ms();
   }
@@ -3202,31 +3202,31 @@
   }
 
   // timestamp_ms
-  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
+  std::vector<std::optional<uint64_t>> timestamp_ms_values =
       DecodeDeltas(proto.timestamp_ms_deltas(),
                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
 
   // packet_number
-  std::vector<absl::optional<uint64_t>> packet_number_values =
+  std::vector<std::optional<uint64_t>> packet_number_values =
       DecodeDeltas(proto.packet_number_deltas(),
                    ToUnsigned(proto.packet_number()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(packet_number_values.size(), number_of_deltas);
 
   // acked_packet_number
-  std::vector<absl::optional<uint64_t>> acked_packet_number_values =
+  std::vector<std::optional<uint64_t>> acked_packet_number_values =
       DecodeDeltas(proto.acked_packet_number_deltas(),
                    ToUnsigned(proto.acked_packet_number()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(acked_packet_number_values.size(),
                                number_of_deltas);
 
   // optional receive_acked_packet_time_ms
-  const absl::optional<uint64_t> unsigned_receive_acked_packet_time_ms_base =
+  const std::optional<uint64_t> unsigned_receive_acked_packet_time_ms_base =
       proto.has_receive_acked_packet_time_ms()
-          ? absl::optional<uint64_t>(
+          ? std::optional<uint64_t>(
                 ToUnsigned(proto.receive_acked_packet_time_ms()))
-          : absl::optional<uint64_t>();
-  std::vector<absl::optional<uint64_t>> receive_acked_packet_time_ms_values =
+          : std::optional<uint64_t>();
+  std::vector<std::optional<uint64_t>> receive_acked_packet_time_ms_values =
       DecodeDeltas(proto.receive_acked_packet_time_ms_deltas(),
                    unsigned_receive_acked_packet_time_ms_base,
                    number_of_deltas);
@@ -3243,7 +3243,7 @@
     int64_t acked_packet_number;
     RTC_PARSE_CHECK_OR_RETURN(
         ToSigned(acked_packet_number_values[i].value(), &acked_packet_number));
-    absl::optional<int64_t> receive_acked_packet_time_ms;
+    std::optional<int64_t> receive_acked_packet_time_ms;
 
     if (receive_acked_packet_time_ms_values[i].has_value()) {
       int64_t value;
@@ -3281,27 +3281,27 @@
   }
 
   // timestamp_ms
-  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
+  std::vector<std::optional<uint64_t>> timestamp_ms_values =
       DecodeDeltas(proto.timestamp_ms_deltas(),
                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
 
   // packet_number
-  std::vector<absl::optional<uint64_t>> packet_number_values =
+  std::vector<std::optional<uint64_t>> packet_number_values =
       DecodeDeltas(proto.packet_number_deltas(),
                    ToUnsigned(proto.packet_number()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(packet_number_values.size(), number_of_deltas);
 
-  std::vector<absl::optional<uint64_t>> overhead_length_values =
+  std::vector<std::optional<uint64_t>> overhead_length_values =
       DecodeDeltas(proto.overhead_length_deltas(), proto.overhead_length(),
                    number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(overhead_length_values.size(), number_of_deltas);
 
-  std::vector<absl::optional<uint64_t>> payload_length_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> payload_length_values = DecodeDeltas(
       proto.payload_length_deltas(), proto.payload_length(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(payload_length_values.size(), number_of_deltas);
 
-  std::vector<absl::optional<uint64_t>> padding_length_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> padding_length_values = DecodeDeltas(
       proto.padding_length_deltas(), proto.padding_length(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(padding_length_values.size(), number_of_deltas);
 
@@ -3344,18 +3344,18 @@
   }
 
   // timestamp_ms
-  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
+  std::vector<std::optional<uint64_t>> timestamp_ms_values =
       DecodeDeltas(proto.timestamp_ms_deltas(),
                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
 
   // packet_number
-  std::vector<absl::optional<uint64_t>> packet_number_values =
+  std::vector<std::optional<uint64_t>> packet_number_values =
       DecodeDeltas(proto.packet_number_deltas(),
                    ToUnsigned(proto.packet_number()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(packet_number_values.size(), number_of_deltas);
 
-  std::vector<absl::optional<uint64_t>> packet_length_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> packet_length_values = DecodeDeltas(
       proto.packet_length_deltas(), proto.packet_length(), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(packet_length_values.size(), number_of_deltas);
 
@@ -3417,54 +3417,54 @@
   }
 
   // timestamp_ms
-  std::vector<absl::optional<uint64_t>> timestamp_ms_values =
+  std::vector<std::optional<uint64_t>> timestamp_ms_values =
       DecodeDeltas(proto.timestamp_ms_deltas(),
                    ToUnsigned(proto.timestamp_ms()), number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(timestamp_ms_values.size(), number_of_deltas);
 
   // bitrate_bps
-  const absl::optional<uint64_t> unsigned_base_bitrate_bps =
+  const std::optional<uint64_t> unsigned_base_bitrate_bps =
       proto.has_bitrate_bps()
-          ? absl::optional<uint64_t>(ToUnsigned(proto.bitrate_bps()))
-          : absl::optional<uint64_t>();
-  std::vector<absl::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
+          ? std::optional<uint64_t>(ToUnsigned(proto.bitrate_bps()))
+          : std::optional<uint64_t>();
+  std::vector<std::optional<uint64_t>> bitrate_bps_values = DecodeDeltas(
       proto.bitrate_bps_deltas(), unsigned_base_bitrate_bps, number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(bitrate_bps_values.size(), number_of_deltas);
 
   // frame_length_ms
-  const absl::optional<uint64_t> unsigned_base_frame_length_ms =
+  const std::optional<uint64_t> unsigned_base_frame_length_ms =
       proto.has_frame_length_ms()
-          ? absl::optional<uint64_t>(ToUnsigned(proto.frame_length_ms()))
-          : absl::optional<uint64_t>();
-  std::vector<absl::optional<uint64_t>> frame_length_ms_values =
+          ? std::optional<uint64_t>(ToUnsigned(proto.frame_length_ms()))
+          : std::optional<uint64_t>();
+  std::vector<std::optional<uint64_t>> frame_length_ms_values =
       DecodeDeltas(proto.frame_length_ms_deltas(),
                    unsigned_base_frame_length_ms, number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(frame_length_ms_values.size(), number_of_deltas);
 
   // uplink_packet_loss_fraction
-  const absl::optional<uint64_t> uplink_packet_loss_fraction =
+  const std::optional<uint64_t> uplink_packet_loss_fraction =
       proto.has_uplink_packet_loss_fraction()
-          ? absl::optional<uint64_t>(proto.uplink_packet_loss_fraction())
-          : absl::optional<uint64_t>();
-  std::vector<absl::optional<uint64_t>> uplink_packet_loss_fraction_values =
+          ? std::optional<uint64_t>(proto.uplink_packet_loss_fraction())
+          : std::optional<uint64_t>();
+  std::vector<std::optional<uint64_t>> uplink_packet_loss_fraction_values =
       DecodeDeltas(proto.uplink_packet_loss_fraction_deltas(),
                    uplink_packet_loss_fraction, number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(uplink_packet_loss_fraction_values.size(),
                                number_of_deltas);
 
   // enable_fec
-  const absl::optional<uint64_t> enable_fec =
-      proto.has_enable_fec() ? absl::optional<uint64_t>(proto.enable_fec())
-                             : absl::optional<uint64_t>();
-  std::vector<absl::optional<uint64_t>> enable_fec_values =
+  const std::optional<uint64_t> enable_fec =
+      proto.has_enable_fec() ? std::optional<uint64_t>(proto.enable_fec())
+                             : std::optional<uint64_t>();
+  std::vector<std::optional<uint64_t>> enable_fec_values =
       DecodeDeltas(proto.enable_fec_deltas(), enable_fec, number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(enable_fec_values.size(), number_of_deltas);
 
   // enable_dtx
-  const absl::optional<uint64_t> enable_dtx =
-      proto.has_enable_dtx() ? absl::optional<uint64_t>(proto.enable_dtx())
-                             : absl::optional<uint64_t>();
-  std::vector<absl::optional<uint64_t>> enable_dtx_values =
+  const std::optional<uint64_t> enable_dtx =
+      proto.has_enable_dtx() ? std::optional<uint64_t>(proto.enable_dtx())
+                             : std::optional<uint64_t>();
+  std::vector<std::optional<uint64_t>> enable_dtx_values =
       DecodeDeltas(proto.enable_dtx_deltas(), enable_dtx, number_of_deltas);
   RTC_PARSE_CHECK_OR_RETURN_EQ(enable_dtx_values.size(), number_of_deltas);
 
@@ -3474,12 +3474,12 @@
   // We likewise shift the base event down by one, to get the same base as
   // encoding had, but then shift all of the values (except the base) back up
   // to their original value.
-  absl::optional<uint64_t> shifted_base_num_channels;
+  std::optional<uint64_t> shifted_base_num_channels;
   if (proto.has_num_channels()) {
     shifted_base_num_channels =
-        absl::optional<uint64_t>(proto.num_channels() - 1);
+        std::optional<uint64_t>(proto.num_channels() - 1);
   }
-  std::vector<absl::optional<uint64_t>> num_channels_values = DecodeDeltas(
+  std::vector<std::optional<uint64_t>> num_channels_values = DecodeDeltas(
       proto.num_channels_deltas(), shifted_base_num_channels, number_of_deltas);
   for (size_t i = 0; i < num_channels_values.size(); ++i) {
     if (num_channels_values[i].has_value()) {
diff --git a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc
index 337f7ee..06baf5d 100644
--- a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc
+++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc
@@ -17,12 +17,12 @@
 #include <limits>
 #include <memory>
 #include <numeric>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/candidate.h"
 #include "api/dtls_transport_interface.h"
@@ -136,13 +136,13 @@
   }
 }
 
-absl::optional<int> GetExtensionId(const std::vector<RtpExtension>& extensions,
-                                   absl::string_view uri) {
+std::optional<int> GetExtensionId(const std::vector<RtpExtension>& extensions,
+                                  absl::string_view uri) {
   for (const auto& extension : extensions) {
     if (extension.uri == uri)
       return extension.id;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace
@@ -629,7 +629,7 @@
 }
 std::unique_ptr<RtcEventGenericAckReceived>
 EventGenerator::NewGenericAckReceived() {
-  absl::optional<int64_t> receive_timestamp = absl::nullopt;
+  std::optional<int64_t> receive_timestamp = std::nullopt;
   if (prng_.Rand(0, 2) > 0) {
     receive_timestamp = prng_.Rand(0, 100000);
   }
diff --git a/logging/rtc_event_log/rtc_event_processor.cc b/logging/rtc_event_log/rtc_event_processor.cc
index 433b487..07671cc 100644
--- a/logging/rtc_event_log/rtc_event_processor.cc
+++ b/logging/rtc_event_log/rtc_event_processor.cc
@@ -11,8 +11,8 @@
 
 #include <algorithm>
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "rtc_base/numerics/sequence_number_util.h"
 
 namespace webrtc {
@@ -47,8 +47,8 @@
   if (a->GetTypeOrder() != b->GetTypeOrder())
     return a->GetTypeOrder() > b->GetTypeOrder();
 
-  absl::optional<uint16_t> wrapped_seq_num_a = a->GetTransportSeqNum();
-  absl::optional<uint16_t> wrapped_seq_num_b = b->GetTransportSeqNum();
+  std::optional<uint16_t> wrapped_seq_num_a = a->GetTransportSeqNum();
+  std::optional<uint16_t> wrapped_seq_num_b = b->GetTransportSeqNum();
   if (wrapped_seq_num_a && wrapped_seq_num_b) {
     return AheadOf<uint16_t>(*wrapped_seq_num_a, *wrapped_seq_num_b);
   } else if (wrapped_seq_num_a.has_value() != wrapped_seq_num_b.has_value()) {
diff --git a/logging/rtc_event_log/rtc_event_processor.h b/logging/rtc_event_log/rtc_event_processor.h
index 0dac1c5..846fbb8 100644
--- a/logging/rtc_event_log/rtc_event_processor.h
+++ b/logging/rtc_event_log/rtc_event_processor.h
@@ -15,10 +15,10 @@
 
 #include <functional>
 #include <memory>
+#include <optional>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "logging/rtc_event_log/rtc_event_log_parser.h"
 #include "logging/rtc_event_log/rtc_event_processor_order.h"
 #include "rtc_base/checks.h"
@@ -42,7 +42,7 @@
   virtual bool IsEmpty() const = 0;
   virtual int64_t GetNextTime() const = 0;
   virtual int GetTypeOrder() const = 0;
-  virtual absl::optional<uint16_t> GetTransportSeqNum() const = 0;
+  virtual std::optional<uint16_t> GetTransportSeqNum() const = 0;
   virtual int GetInsertionOrder() const = 0;
 };
 
@@ -55,7 +55,7 @@
                        Iterator end,
                        std::function<void(const T&)> f,
                        int type_order,
-                       std::function<absl::optional<uint16_t>(const T&)>
+                       std::function<std::optional<uint16_t>(const T&)>
                            transport_seq_num_accessor,
                        int insertion_order)
       : begin_(begin),
@@ -80,7 +80,7 @@
 
   int GetTypeOrder() const override { return type_order_; }
 
-  absl::optional<uint16_t> GetTransportSeqNum() const override {
+  std::optional<uint16_t> GetTransportSeqNum() const override {
     RTC_DCHECK(!IsEmpty());
     return transport_seq_num_accessor_(*begin_);
   }
@@ -92,7 +92,7 @@
   Iterator end_;
   std::function<void(const T&)> f_;
   int type_order_;
-  std::function<absl::optional<uint16_t>(const T&)> transport_seq_num_accessor_;
+  std::function<std::optional<uint16_t>(const T&)> transport_seq_num_accessor_;
   int insertion_order_;
 };
 
@@ -152,7 +152,7 @@
       const Iterable& iterable,
       std::function<void(const typename Iterable::value_type&)> handler,
       int type_order,
-      std::function<absl::optional<uint16_t>(
+      std::function<std::optional<uint16_t>(
           const typename Iterable::value_type&)> transport_seq_num_accessor,
       int insertion_order) {
     if (iterable.begin() == iterable.end())
diff --git a/logging/rtc_event_log/rtc_event_processor_order.h b/logging/rtc_event_log/rtc_event_processor_order.h
index 5ee1244..262bd10 100644
--- a/logging/rtc_event_log/rtc_event_processor_order.h
+++ b/logging/rtc_event_log/rtc_event_processor_order.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
 #include "logging/rtc_event_log/events/rtc_event_alr_state.h"
 #include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
@@ -101,9 +102,9 @@
 class TieBreaker<LoggedStartEvent> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::Start);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedStartEvent&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -111,9 +112,9 @@
 class TieBreaker<LoggedStopEvent> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::Stop);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedStopEvent&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -121,9 +122,9 @@
 class TieBreaker<LoggedAudioRecvConfig> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::StreamConfig);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedAudioRecvConfig&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -131,9 +132,9 @@
 class TieBreaker<LoggedAudioSendConfig> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::StreamConfig);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedAudioSendConfig&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -141,9 +142,9 @@
 class TieBreaker<LoggedVideoRecvConfig> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::StreamConfig);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedVideoRecvConfig&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -151,9 +152,9 @@
 class TieBreaker<LoggedVideoSendConfig> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::StreamConfig);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedVideoSendConfig&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -162,9 +163,9 @@
  public:
   static constexpr int type_order =
       static_cast<int>(TypeOrder::IceCondidateConfig);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedIceCandidatePairConfig&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -173,9 +174,9 @@
  public:
   static constexpr int type_order =
       static_cast<int>(TypeOrder::IceCandidateEvent);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedIceCandidatePairEvent&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -184,9 +185,9 @@
  public:
   static constexpr int type_order =
       static_cast<int>(TypeOrder::DtlsTransportState);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedDtlsTransportState&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -194,9 +195,9 @@
 class TieBreaker<LoggedDtlsWritableState> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::DtlsWritable);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedDtlsWritableState&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -204,9 +205,9 @@
 class TieBreaker<LoggedRouteChangeEvent> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::RouteChange);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedRouteChangeEvent&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -215,9 +216,9 @@
  public:
   static constexpr int type_order =
       static_cast<int>(TypeOrder::BweRemoteEstimate);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedRemoteEstimateEvent&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -226,9 +227,9 @@
  public:
   static constexpr int type_order =
       static_cast<int>(TypeOrder::BweProbeFailure);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedBweProbeFailureEvent&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -237,9 +238,9 @@
  public:
   static constexpr int type_order =
       static_cast<int>(TypeOrder::BweProbeSuccess);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedBweProbeSuccessEvent&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -247,9 +248,9 @@
 class TieBreaker<LoggedBweDelayBasedUpdate> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::BweDelayBased);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedBweDelayBasedUpdate&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -257,9 +258,9 @@
 class TieBreaker<LoggedBweLossBasedUpdate> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::BweLossBased);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedBweLossBasedUpdate&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -268,9 +269,9 @@
  public:
   static constexpr int type_order =
       static_cast<int>(TypeOrder::BweProbeCreated);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedBweProbeClusterCreatedEvent&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -279,9 +280,9 @@
  public:
   static constexpr int type_order =
       static_cast<int>(TypeOrder::AudioNetworkAdaptation);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedAudioNetworkAdaptationEvent&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -290,9 +291,9 @@
  public:
   static constexpr int type_order =
       static_cast<int>(TypeOrder::NetEqSetMinDelay);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedNetEqSetMinimumDelayEvent&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -300,9 +301,9 @@
 class TieBreaker<LoggedAudioPlayoutEvent> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::AudioPlayout);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedAudioPlayoutEvent&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -310,9 +311,9 @@
 class TieBreaker<LoggedFrameDecoded> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::FrameDecoded);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedFrameDecoded&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -321,9 +322,9 @@
  public:
   static constexpr int type_order =
       static_cast<int>(TypeOrder::GenericPacketIn);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedGenericPacketReceived&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -331,9 +332,9 @@
 class TieBreaker<LoggedGenericAckReceived> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::GenericAckIn);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedGenericAckReceived&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -342,9 +343,9 @@
  public:
   static constexpr int type_order =
       static_cast<int>(TypeOrder::GenericPacketOut);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedGenericPacketSent&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -356,11 +357,11 @@
                                 ? TypeOrder::RtpIn
                                 : TypeOrder::RtpOut);
   }
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedRtpPacket& p) {
     return p.header.extension.hasTransportSequenceNumber
                ? p.header.extension.transportSequenceNumber
-               : absl::optional<uint16_t>();
+               : std::optional<uint16_t>();
   }
 };
 
@@ -372,10 +373,10 @@
                                 ? TypeOrder::RtpIn
                                 : TypeOrder::RtpOut);
   }
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedPacketInfo& p) {
     return p.has_transport_seq_no ? p.transport_seq_no
-                                  : absl::optional<uint16_t>();
+                                  : std::optional<uint16_t>();
   }
 };
 
@@ -383,11 +384,11 @@
 class TieBreaker<LoggedRtpPacketIncoming> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::RtpIn);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedRtpPacketIncoming& p) {
     return p.rtp.header.extension.hasTransportSequenceNumber
                ? p.rtp.header.extension.transportSequenceNumber
-               : absl::optional<uint16_t>();
+               : std::optional<uint16_t>();
   }
 };
 
@@ -395,11 +396,11 @@
 class TieBreaker<LoggedRtpPacketOutgoing> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::RtpOut);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedRtpPacketOutgoing& p) {
     return p.rtp.header.extension.hasTransportSequenceNumber
                ? p.rtp.header.extension.transportSequenceNumber
-               : absl::optional<uint16_t>();
+               : std::optional<uint16_t>();
   }
 };
 
@@ -407,9 +408,9 @@
 class TieBreaker<LoggedRtcpPacketIncoming> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::RtcpIn);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedRtcpPacketIncoming&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -417,9 +418,9 @@
 class TieBreaker<LoggedRtcpPacketOutgoing> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::RtcpOut);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedRtcpPacketOutgoing&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -431,9 +432,9 @@
                                 ? TypeOrder::RtcpIn
                                 : TypeOrder::RtcpOut);
   }
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedRtcpPacketTransportFeedback&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -445,9 +446,9 @@
                                 ? TypeOrder::RtcpIn
                                 : TypeOrder::RtcpOut);
   }
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedRtcpPacketReceiverReport&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
@@ -455,9 +456,9 @@
 class TieBreaker<LoggedAlrStateEvent> {
  public:
   static constexpr int type_order = static_cast<int>(TypeOrder::AlrState);
-  static absl::optional<uint16_t> transport_seq_num_accessor(
+  static std::optional<uint16_t> transport_seq_num_accessor(
       const LoggedAlrStateEvent&) {
-    return absl::optional<uint16_t>();
+    return std::optional<uint16_t>();
   }
 };
 
diff --git a/logging/rtc_event_log/rtc_event_processor_unittest.cc b/logging/rtc_event_log/rtc_event_processor_unittest.cc
index 53948ad..2427f15 100644
--- a/logging/rtc_event_log/rtc_event_processor_unittest.cc
+++ b/logging/rtc_event_log/rtc_event_processor_unittest.cc
@@ -16,10 +16,10 @@
 #include <initializer_list>
 #include <limits>
 #include <numeric>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/rtp_headers.h"
 #include "api/units/timestamp.h"
 #include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
@@ -69,7 +69,7 @@
 
 LoggedRtpPacket CreateRtpPacket(int64_t time_ms,
                                 uint32_t ssrc,
-                                absl::optional<uint16_t> transport_seq_num) {
+                                std::optional<uint16_t> transport_seq_num) {
   RTPHeader header;
   header.ssrc = ssrc;
   header.timestamp = static_cast<uint32_t>(time_ms);
@@ -237,8 +237,8 @@
 
 TEST(RtcEventProcessor, RtpPacketsInTransportSeqNumOrder) {
   std::vector<LoggedRtpPacket> ssrc_1234{
-      CreateRtpPacket(1, 1234, absl::nullopt),
-      CreateRtpPacket(1, 1234, absl::nullopt)};
+      CreateRtpPacket(1, 1234, std::nullopt),
+      CreateRtpPacket(1, 1234, std::nullopt)};
   std::vector<LoggedRtpPacket> ssrc_2345{CreateRtpPacket(1, 2345, 2),
                                          CreateRtpPacket(1, 2345, 3),
                                          CreateRtpPacket(1, 2345, 6)};
@@ -247,9 +247,9 @@
                                          CreateRtpPacket(1, 3456, 5)};
 
   // Store SSRC and transport sequence number for each processed packet.
-  std::vector<std::pair<uint32_t, absl::optional<uint16_t>>> results;
+  std::vector<std::pair<uint32_t, std::optional<uint16_t>>> results;
   auto get_packet = [&results](const LoggedRtpPacket& packet) {
-    absl::optional<uint16_t> transport_seq_num;
+    std::optional<uint16_t> transport_seq_num;
     if (packet.header.extension.hasTransportSequenceNumber)
       transport_seq_num = packet.header.extension.transportSequenceNumber;
     results.emplace_back(packet.header.ssrc, transport_seq_num);
@@ -261,9 +261,9 @@
   processor.AddEvents(ssrc_3456, get_packet, PacketDirection::kIncomingPacket);
   processor.ProcessEventsInOrder();
 
-  std::vector<std::pair<uint32_t, absl::optional<uint16_t>>> expected{
-      {1234, absl::nullopt},
-      {1234, absl::nullopt},
+  std::vector<std::pair<uint32_t, std::optional<uint16_t>>> expected{
+      {1234, std::nullopt},
+      {1234, std::nullopt},
       {3456, 1},
       {2345, 2},
       {2345, 3},
@@ -282,9 +282,9 @@
       CreateRtpPacket(1, 2345, 0), CreateRtpPacket(1, 2345, 3)};
 
   // Store SSRC and transport sequence number for each processed packet.
-  std::vector<std::pair<uint32_t, absl::optional<uint16_t>>> results;
+  std::vector<std::pair<uint32_t, std::optional<uint16_t>>> results;
   auto get_packet = [&results](const LoggedRtpPacket& packet) {
-    absl::optional<uint16_t> transport_seq_num;
+    std::optional<uint16_t> transport_seq_num;
     if (packet.header.extension.hasTransportSequenceNumber)
       transport_seq_num = packet.header.extension.transportSequenceNumber;
     results.emplace_back(packet.header.ssrc, transport_seq_num);
@@ -295,7 +295,7 @@
   processor.AddEvents(ssrc_2345, get_packet, PacketDirection::kOutgoingPacket);
   processor.ProcessEventsInOrder();
 
-  std::vector<std::pair<uint32_t, absl::optional<uint16_t>>> expected{
+  std::vector<std::pair<uint32_t, std::optional<uint16_t>>> expected{
       {1234, std::numeric_limits<uint16_t>::max() - 1},
       {2345, std::numeric_limits<uint16_t>::max()},
       {2345, 0},
diff --git a/media/BUILD.gn b/media/BUILD.gn
index 79662b0..ddf33dc 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -42,7 +42,6 @@
     "../rtc_base:checks",
     "../rtc_base:stringutils",
     "//third_party/abseil-cpp/absl/algorithm:container",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -126,7 +125,6 @@
     "../rtc_base/system:rtc_export",
     "../rtc_base/third_party/sigslot",
     "../video/config:encoder_config",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -147,13 +145,11 @@
     "../rtc_base:timeutils",
     "../rtc_base/synchronization:mutex",
     "../rtc_base/system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
 rtc_source_set("audio_source") {
   sources = [ "base/audio_source.h" ]
-  deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
 }
 
 rtc_library("video_adapter") {
@@ -173,7 +169,6 @@
     "../rtc_base/synchronization:mutex",
     "../rtc_base/system:rtc_export",
     "../system_wrappers:field_trial",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -208,7 +203,6 @@
     "../rtc_base:logging",
     "../rtc_base:macromagic",
     "../rtc_base/synchronization:mutex",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -297,7 +291,6 @@
     "../rtc_base/network:sent_packet",
     "//third_party/abseil-cpp/absl/functional:any_invocable",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -345,7 +338,6 @@
     "../rtc_base:stringutils",
     "../rtc_base/network:sent_packet",
     "../video/config:encoder_config",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -368,7 +360,6 @@
     "//third_party/abseil-cpp/absl/container:inlined_vector",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -475,7 +466,6 @@
     "../system_wrappers",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/base:nullability",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -511,7 +501,6 @@
     "../system_wrappers:field_trial",
     "../test:fake_video_codecs",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 
   if (enable_libaom) {
@@ -652,7 +641,6 @@
     "//third_party/abseil-cpp/absl/functional:bind_front",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 
   sources = [
@@ -733,7 +721,6 @@
       "../rtc_base/third_party/sigslot:sigslot",
       "../system_wrappers",
       "//third_party/abseil-cpp/absl/strings:strings",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
@@ -836,7 +823,6 @@
       "//third_party/abseil-cpp/absl/functional:any_invocable",
       "//third_party/abseil-cpp/absl/strings",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
     sources = [
       "base/fake_frame_source.cc",
@@ -983,7 +969,6 @@
         "//third_party/abseil-cpp/absl/memory",
         "//third_party/abseil-cpp/absl/strings",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
 
       if (enable_libaom) {
diff --git a/media/base/adapted_video_track_source.h b/media/base/adapted_video_track_source.h
index 1c3e0b6..670331d 100644
--- a/media/base/adapted_video_track_source.h
+++ b/media/base/adapted_video_track_source.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/media_stream_interface.h"
 #include "api/notifier.h"
 #include "api/video/video_frame.h"
@@ -94,7 +95,7 @@
   cricket::VideoAdapter video_adapter_;
 
   webrtc::Mutex stats_mutex_;
-  absl::optional<Stats> stats_ RTC_GUARDED_BY(stats_mutex_);
+  std::optional<Stats> stats_ RTC_GUARDED_BY(stats_mutex_);
 
   VideoBroadcaster broadcaster_;
 };
diff --git a/media/base/audio_source.h b/media/base/audio_source.h
index 51fe0e1..3cc0bc4 100644
--- a/media/base/audio_source.h
+++ b/media/base/audio_source.h
@@ -12,8 +12,7 @@
 #define MEDIA_BASE_AUDIO_SOURCE_H_
 
 #include <cstddef>
-
-#include "absl/types/optional.h"
+#include <optional>
 
 namespace cricket {
 
@@ -31,7 +30,7 @@
         int sample_rate,
         size_t number_of_channels,
         size_t number_of_frames,
-        absl::optional<int64_t> absolute_capture_timestamp_ms) = 0;
+        std::optional<int64_t> absolute_capture_timestamp_ms) = 0;
 
     // Called when the AudioSource is going away.
     virtual void OnClose() = 0;
diff --git a/media/base/codec.cc b/media/base/codec.cc
index 820cb97..e994f0e 100644
--- a/media/base/codec.cc
+++ b/media/base/codec.cc
@@ -13,12 +13,12 @@
 #include <algorithm>
 #include <cstddef>
 #include <iterator>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_format.h"
 #include "api/media_types.h"
 #include "api/rtp_parameters.h"
@@ -498,7 +498,7 @@
   for (auto it = supported_formats->cbegin(); it != supported_formats->cend();
        ++it) {
     if (it->name == cricket::kH264CodecName) {
-      const absl::optional<webrtc::H264ProfileLevelId> profile_level_id =
+      const std::optional<webrtc::H264ProfileLevelId> profile_level_id =
           webrtc::ParseSdpForH264ProfileLevelId(it->parameters);
       if (profile_level_id &&
           profile_level_id->profile !=
diff --git a/media/base/codec.h b/media/base/codec.h
index 5230779..583a14e 100644
--- a/media/base/codec.h
+++ b/media/base/codec.h
@@ -12,12 +12,12 @@
 #define MEDIA_BASE_CODEC_H_
 
 #include <cstddef>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/container/inlined_vector.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_format.h"
 #include "api/rtp_parameters.h"
 #include "api/video_codecs/scalability_mode.h"
@@ -92,12 +92,12 @@
   size_t channels;
 
   // Video only
-  absl::optional<std::string> packetization;
+  std::optional<std::string> packetization;
   absl::InlinedVector<webrtc::ScalabilityMode, webrtc::kScalabilityModeCount>
       scalability_modes;
 
   // H.265 only
-  absl::optional<std::string> tx_mode;
+  std::optional<std::string> tx_mode;
 
   // Non key-value parameters such as the telephone-event "0‐15" are
   // represented using an empty string as key, i.e. {"": "0-15"}.
diff --git a/media/base/codec_unittest.cc b/media/base/codec_unittest.cc
index 08b37fb..62fbd76 100644
--- a/media/base/codec_unittest.cc
+++ b/media/base/codec_unittest.cc
@@ -555,7 +555,7 @@
   EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, codec_params_1.kind);
   EXPECT_EQ("V", codec_params_1.name);
   EXPECT_EQ(cricket::kVideoCodecClockrate, codec_params_1.clock_rate);
-  EXPECT_EQ(absl::nullopt, codec_params_1.num_channels);
+  EXPECT_EQ(std::nullopt, codec_params_1.num_channels);
   ASSERT_EQ(1u, codec_params_1.parameters.size());
   EXPECT_EQ("p1", codec_params_1.parameters.begin()->first);
   EXPECT_EQ("v1", codec_params_1.parameters.begin()->second);
diff --git a/media/base/fake_media_engine.cc b/media/base/fake_media_engine.cc
index d5c0e02..6cdf64b 100644
--- a/media/base/fake_media_engine.cc
+++ b/media/base/fake_media_engine.cc
@@ -11,11 +11,11 @@
 #include "media/base/fake_media_engine.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "media/base/media_channel.h"
 #include "rtc_base/checks.h"
 
@@ -43,7 +43,7 @@
     int sample_rate,
     size_t number_of_channels,
     size_t number_of_frames,
-    absl::optional<int64_t> absolute_capture_timestamp_ms) {}
+    std::optional<int64_t> absolute_capture_timestamp_ms) {}
 void FakeVoiceMediaReceiveChannel::VoiceChannelAudioSink::OnClose() {
   source_ = nullptr;
 }
@@ -133,13 +133,13 @@
     return true;
   }
 }
-absl::optional<int> FakeVoiceMediaReceiveChannel::GetBaseMinimumPlayoutDelayMs(
+std::optional<int> FakeVoiceMediaReceiveChannel::GetBaseMinimumPlayoutDelayMs(
     uint32_t ssrc) const {
   const auto it = output_delays_.find(ssrc);
   if (it != output_delays_.end()) {
     return it->second;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 bool FakeVoiceMediaReceiveChannel::GetStats(VoiceMediaReceiveInfo* info,
                                             bool get_and_clear_legacy_stats) {
@@ -198,7 +198,7 @@
     int sample_rate,
     size_t number_of_channels,
     size_t number_of_frames,
-    absl::optional<int64_t> absolute_capture_timestamp_ms) {}
+    std::optional<int64_t> absolute_capture_timestamp_ms) {}
 void FakeVoiceMediaSendChannel::VoiceChannelAudioSink::OnClose() {
   source_ = nullptr;
 }
@@ -218,11 +218,11 @@
 const std::vector<Codec>& FakeVoiceMediaSendChannel::send_codecs() const {
   return send_codecs_;
 }
-absl::optional<Codec> FakeVoiceMediaSendChannel::GetSendCodec() const {
+std::optional<Codec> FakeVoiceMediaSendChannel::GetSendCodec() const {
   if (!send_codecs_.empty()) {
     return send_codecs_.front();
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 const std::vector<FakeVoiceMediaSendChannel::DtmfInfo>&
 FakeVoiceMediaSendChannel::dtmf_info_queue() const {
@@ -362,9 +362,9 @@
           SetSendRtpHeaderExtensions(params.extensions) &&
           SetMaxSendBandwidth(params.max_bandwidth_bps));
 }
-absl::optional<Codec> FakeVideoMediaSendChannel::GetSendCodec() const {
+std::optional<Codec> FakeVideoMediaSendChannel::GetSendCodec() const {
   if (send_codecs_.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return send_codecs_[0];
 }
@@ -492,13 +492,13 @@
     return true;
   }
 }
-absl::optional<int> FakeVideoMediaReceiveChannel::GetBaseMinimumPlayoutDelayMs(
+std::optional<int> FakeVideoMediaReceiveChannel::GetBaseMinimumPlayoutDelayMs(
     uint32_t ssrc) const {
   const auto it = output_delays_.find(ssrc);
   if (it != output_delays_.end()) {
     return it->second;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 bool FakeVideoMediaReceiveChannel::SetRecvCodecs(
     const std::vector<Codec>& codecs) {
@@ -587,9 +587,9 @@
                                    int64_t max_size_bytes) {
   return false;
 }
-absl::optional<webrtc::AudioDeviceModule::Stats>
+std::optional<webrtc::AudioDeviceModule::Stats>
 FakeVoiceEngine::GetAudioDeviceStats() {
-  return absl::nullopt;
+  return std::nullopt;
 }
 void FakeVoiceEngine::StopAecDump() {}
 
diff --git a/media/base/fake_media_engine.h b/media/base/fake_media_engine.h
index 64af78d..4b07a4a 100644
--- a/media/base/fake_media_engine.h
+++ b/media/base/fake_media_engine.h
@@ -92,8 +92,8 @@
   bool CheckNoRtcp() { return rtcp_packets_.empty(); }
   void set_fail_set_recv_codecs(bool fail) { fail_set_recv_codecs_ = fail; }
   void ResetUnsignaledRecvStream() override {}
-  absl::optional<uint32_t> GetUnsignaledSsrc() const override {
-    return absl::nullopt;
+  std::optional<uint32_t> GetUnsignaledSsrc() const override {
+    return std::nullopt;
   }
   void ChooseReceiverReportSsrc(const std::set<uint32_t>& choices) override {}
 
@@ -481,8 +481,7 @@
   bool GetOutputVolume(uint32_t ssrc, double* volume);
 
   bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) override;
-  absl::optional<int> GetBaseMinimumPlayoutDelayMs(
-      uint32_t ssrc) const override;
+  std::optional<int> GetBaseMinimumPlayoutDelayMs(uint32_t ssrc) const override;
 
   bool GetStats(VoiceMediaReceiveInfo* info,
                 bool get_and_clear_legacy_stats) override;
@@ -508,7 +507,7 @@
                 int sample_rate,
                 size_t number_of_channels,
                 size_t number_of_frames,
-                absl::optional<int64_t> absolute_capture_timestamp_ms) override;
+                std::optional<int64_t> absolute_capture_timestamp_ms) override;
     void OnClose() override;
     int NumPreferredChannels() const override { return -1; }
     AudioSource* source() const;
@@ -577,7 +576,7 @@
   bool SendCodecHasNack() const override { return false; }
   void SetSendCodecChangedCallback(
       absl::AnyInvocable<void()> callback) override {}
-  absl::optional<Codec> GetSendCodec() const override;
+  std::optional<Codec> GetSendCodec() const override;
 
   bool GetStats(VoiceMediaSendInfo* stats) override;
 
@@ -591,7 +590,7 @@
                 int sample_rate,
                 size_t number_of_channels,
                 size_t number_of_frames,
-                absl::optional<int64_t> absolute_capture_timestamp_ms) override;
+                std::optional<int64_t> absolute_capture_timestamp_ms) override;
     void OnClose() override;
     int NumPreferredChannels() const override { return -1; }
     AudioSource* source() const;
@@ -662,8 +661,7 @@
   std::vector<webrtc::RtpSource> GetSources(uint32_t ssrc) const override;
 
   bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) override;
-  absl::optional<int> GetBaseMinimumPlayoutDelayMs(
-      uint32_t ssrc) const override;
+  std::optional<int> GetBaseMinimumPlayoutDelayMs(uint32_t ssrc) const override;
 
   void SetRecordableEncodedFrameCallback(
       uint32_t ssrc,
@@ -674,7 +672,7 @@
   void SetReceiverFeedbackParameters(bool lntf_enabled,
                                      bool nack_enabled,
                                      webrtc::RtcpMode rtcp_mode,
-                                     absl::optional<int> rtx_time) override {}
+                                     std::optional<int> rtx_time) override {}
   bool GetStats(VideoMediaReceiveInfo* info) override;
 
   bool AddDefaultRecvStreamForTesting(const StreamParams& sp) override {
@@ -720,7 +718,7 @@
   int max_bps() const;
   bool SetSenderParameters(const VideoSenderParameters& params) override;
 
-  absl::optional<Codec> GetSendCodec() const override;
+  std::optional<Codec> GetSendCodec() const override;
 
   bool SetSend(bool send) override;
   bool SetVideoSend(
@@ -744,9 +742,7 @@
 
   bool SendCodecHasLntf() const override { return false; }
   bool SendCodecHasNack() const override { return false; }
-  absl::optional<int> SendCodecRtxTime() const override {
-    return absl::nullopt;
-  }
+  std::optional<int> SendCodecRtxTime() const override { return std::nullopt; }
   bool GetStats(VideoMediaSendInfo* info) override;
 
  private:
@@ -789,7 +785,7 @@
   int GetInputLevel();
   bool StartAecDump(webrtc::FileWrapper file, int64_t max_size_bytes) override;
   void StopAecDump() override;
-  absl::optional<webrtc::AudioDeviceModule::Stats> GetAudioDeviceStats()
+  std::optional<webrtc::AudioDeviceModule::Stats> GetAudioDeviceStats()
       override;
   std::vector<webrtc::RtpHeaderExtensionCapability> GetRtpHeaderExtensions()
       const override;
diff --git a/media/base/media_channel.h b/media/base/media_channel.h
index d656304..ed69c6b 100644
--- a/media/base/media_channel.h
+++ b/media/base/media_channel.h
@@ -13,12 +13,12 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_processing_statistics.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_options.h"
@@ -85,8 +85,7 @@
 const int kScreencastDefaultFps = 5;
 
 template <class T>
-static std::string ToStringIfSet(const char* key,
-                                 const absl::optional<T>& val) {
+static std::string ToStringIfSet(const char* key, const std::optional<T>& val) {
   std::string str;
   if (val) {
     str = key;
@@ -146,23 +145,23 @@
   // Enable denoising? This flag comes from the getUserMedia
   // constraint 'googNoiseReduction', and WebRtcVideoEngine passes it
   // on to the codec options. Disabled by default.
-  absl::optional<bool> video_noise_reduction;
+  std::optional<bool> video_noise_reduction;
   // Force screencast to use a minimum bitrate. This flag comes from
   // the PeerConnection constraint 'googScreencastMinBitrate'. It is
   // copied to the encoder config by WebRtcVideoChannel.
   // TODO(https://crbug.com/1315155): Remove the ability to set it in Chromium
   // and delete this flag (it should default to 100 kbps).
-  absl::optional<int> screencast_min_bitrate_kbps;
+  std::optional<int> screencast_min_bitrate_kbps;
   // Set by screencast sources. Implies selection of encoding settings
   // suitable for screencast. Most likely not the right way to do
   // things, e.g., screencast of a text document and screencast of a
   // youtube video have different needs.
-  absl::optional<bool> is_screencast;
+  std::optional<bool> is_screencast;
   webrtc::VideoTrackInterface::ContentHint content_hint;
 
  private:
   template <typename T>
-  static void SetFrom(absl::optional<T>* s, const absl::optional<T>& o) {
+  static void SetFrom(std::optional<T>* s, const std::optional<T>& o) {
     if (o) {
       *s = o;
     }
@@ -192,7 +191,7 @@
   virtual cricket::MediaType media_type() const = 0;
 
   // Gets the currently set codecs/payload types to be used for outgoing media.
-  virtual absl::optional<Codec> GetSendCodec() const = 0;
+  virtual std::optional<Codec> GetSendCodec() const = 0;
 
   // Creates a new outgoing media stream with SSRCs and CNAME as described
   // by sp.
@@ -282,7 +281,7 @@
   // Called on the network when an RTP packet is received.
   virtual void OnPacketReceived(const webrtc::RtpPacketReceived& packet) = 0;
   // Gets the current unsignaled receive stream's SSRC, if there is one.
-  virtual absl::optional<uint32_t> GetUnsignaledSsrc() const = 0;
+  virtual std::optional<uint32_t> GetUnsignaledSsrc() const = 0;
   // Sets the local SSRC for listening to incoming RTCP reports.
   virtual void ChooseReceiverReportSsrc(const std::set<uint32_t>& choices) = 0;
   // This is currently a workaround because of the demuxer state being managed
@@ -318,7 +317,7 @@
   virtual bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) = 0;
 
   // Returns current value of base minimum delay in milliseconds.
-  virtual absl::optional<int> GetBaseMinimumPlayoutDelayMs(
+  virtual std::optional<int> GetBaseMinimumPlayoutDelayMs(
       uint32_t ssrc) const = 0;
 };
 
@@ -385,12 +384,12 @@
   // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-nackcount
   uint32_t nacks_received = 0;
   // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-targetbitrate
-  absl::optional<double> target_bitrate;
+  std::optional<double> target_bitrate;
   int packets_lost = 0;
   float fraction_lost = 0.0f;
   int64_t rtt_ms = 0;
   std::string codec_name;
-  absl::optional<int> codec_payload_type;
+  std::optional<int> codec_payload_type;
   std::vector<SsrcSenderInfo> local_stats;
   std::vector<SsrcReceiverInfo> remote_stats;
   // A snapshot of the most recent Report Block with additional data of interest
@@ -398,7 +397,7 @@
   // this list, the `ReportBlockData::source_ssrc()`, which is the SSRC of the
   // corresponding outbound RTP stream, is unique.
   std::vector<webrtc::ReportBlockData> report_block_datas;
-  absl::optional<bool> active;
+  std::optional<bool> active;
   // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-totalpacketsenddelay
   webrtc::TimeDelta total_packet_send_delay = webrtc::TimeDelta::Zero();
 };
@@ -445,9 +444,9 @@
   int packets_received = 0;
   int packets_lost = 0;
 
-  absl::optional<uint64_t> retransmitted_bytes_received;
-  absl::optional<uint64_t> retransmitted_packets_received;
-  absl::optional<uint32_t> nacks_sent;
+  std::optional<uint64_t> retransmitted_bytes_received;
+  std::optional<uint64_t> retransmitted_packets_received;
+  std::optional<uint32_t> nacks_sent;
   // Jitter (network-related) latency (cumulative).
   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-jitterbufferdelay
   double jitter_buffer_delay_seconds = 0.0;
@@ -463,32 +462,32 @@
   // The timestamp at which the last packet was received, i.e. the time of the
   // local clock when it was received - not the RTP timestamp of that packet.
   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-lastpacketreceivedtimestamp
-  absl::optional<webrtc::Timestamp> last_packet_received;
+  std::optional<webrtc::Timestamp> last_packet_received;
   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-estimatedplayouttimestamp
-  absl::optional<int64_t> estimated_playout_ntp_timestamp_ms;
+  std::optional<int64_t> estimated_playout_ntp_timestamp_ms;
   std::string codec_name;
-  absl::optional<int> codec_payload_type;
+  std::optional<int> codec_payload_type;
   std::vector<SsrcReceiverInfo> local_stats;
   std::vector<SsrcSenderInfo> remote_stats;
   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-fecpacketsreceived
-  absl::optional<uint64_t> fec_packets_received;
+  std::optional<uint64_t> fec_packets_received;
   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-fecpacketsdiscarded
-  absl::optional<uint64_t> fec_packets_discarded;
+  std::optional<uint64_t> fec_packets_discarded;
   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-fecbytesreceived
-  absl::optional<uint64_t> fec_bytes_received;
+  std::optional<uint64_t> fec_bytes_received;
   // https://www.w3.org/TR/webrtc-stats/#dom-rtcinboundrtpstreamstats-totalprocessingdelay
   double total_processing_delay_seconds = 0.0;
 
   // Remote outbound stats derived by the received RTCP sender reports.
   // https://w3c.github.io/webrtc-stats/#remoteoutboundrtpstats-dict*
-  absl::optional<int64_t> last_sender_report_timestamp_ms;
-  absl::optional<int64_t> last_sender_report_remote_timestamp_ms;
+  std::optional<int64_t> last_sender_report_timestamp_ms;
+  std::optional<int64_t> last_sender_report_remote_timestamp_ms;
   uint64_t sender_reports_packets_sent = 0;
   uint64_t sender_reports_bytes_sent = 0;
   uint64_t sender_reports_reports_count = 0;
   // These require a DLRR block, see
   // https://w3c.github.io/webrtc-stats/#dom-rtcremoteoutboundrtpstreamstats-roundtriptime
-  absl::optional<webrtc::TimeDelta> round_trip_time;
+  std::optional<webrtc::TimeDelta> round_trip_time;
   webrtc::TimeDelta total_round_trip_time = webrtc::TimeDelta::Zero();
   int round_trip_time_measurements = 0;
 };
@@ -572,7 +571,7 @@
   VideoSenderInfo();
   ~VideoSenderInfo();
   std::vector<SsrcGroup> ssrc_groups;
-  absl::optional<std::string> encoder_implementation_name;
+  std::optional<std::string> encoder_implementation_name;
   int firs_received = 0;
   int plis_received = 0;
   int send_frame_width = 0;
@@ -601,23 +600,23 @@
   // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-totalencodedbytestarget
   uint64_t total_encoded_bytes_target = 0;
   bool has_entered_low_resolution = false;
-  absl::optional<uint64_t> qp_sum;
+  std::optional<uint64_t> qp_sum;
   webrtc::VideoContentType content_type = webrtc::VideoContentType::UNSPECIFIED;
   uint32_t frames_sent = 0;
   // https://w3c.github.io/webrtc-stats/#dom-rtcvideosenderstats-hugeframessent
   uint32_t huge_frames_sent = 0;
   uint32_t aggregated_huge_frames_sent = 0;
-  absl::optional<std::string> rid;
-  absl::optional<bool> power_efficient_encoder;
-  absl::optional<webrtc::ScalabilityMode> scalability_mode;
+  std::optional<std::string> rid;
+  std::optional<bool> power_efficient_encoder;
+  std::optional<webrtc::ScalabilityMode> scalability_mode;
 };
 
 struct VideoReceiverInfo : public MediaReceiverInfo {
   VideoReceiverInfo();
   ~VideoReceiverInfo();
   std::vector<SsrcGroup> ssrc_groups;
-  absl::optional<std::string> decoder_implementation_name;
-  absl::optional<bool> power_efficient_decoder;
+  std::optional<std::string> decoder_implementation_name;
+  std::optional<bool> power_efficient_decoder;
   int packets_concealed = 0;
   int firs_sent = 0;
   int plis_sent = 0;
@@ -635,7 +634,7 @@
   uint32_t frames_decoded = 0;
   uint32_t key_frames_decoded = 0;
   uint32_t frames_rendered = 0;
-  absl::optional<uint64_t> qp_sum;
+  std::optional<uint64_t> qp_sum;
   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totaldecodetime
   webrtc::TimeDelta total_decode_time = webrtc::TimeDelta::Zero();
   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totalprocessingdelay
@@ -681,7 +680,7 @@
 
   // Timing frame info: all important timestamps for a full lifetime of a
   // single 'timing frame'.
-  absl::optional<webrtc::TimingFrameInfo> timing_frame_info;
+  std::optional<webrtc::TimingFrameInfo> timing_frame_info;
 };
 
 struct BandwidthEstimationInfo {
@@ -971,7 +970,7 @@
   // Information queries to support SetReceiverFeedbackParameters
   virtual webrtc::RtcpMode SendCodecRtcpMode() const = 0;
   virtual bool SendCodecHasLntf() const = 0;
-  virtual absl::optional<int> SendCodecRtxTime() const = 0;
+  virtual std::optional<int> SendCodecRtxTime() const = 0;
 };
 
 class VideoMediaReceiveChannelInterface : public MediaReceiveChannelInterface {
@@ -1006,7 +1005,7 @@
   virtual void SetReceiverFeedbackParameters(bool lntf_enabled,
                                              bool nack_enabled,
                                              webrtc::RtcpMode rtcp_mode,
-                                             absl::optional<int> rtx_time) = 0;
+                                             std::optional<int> rtx_time) = 0;
   virtual bool AddDefaultRecvStreamForTesting(const StreamParams& sp) = 0;
 };
 
diff --git a/media/base/media_channel_impl.h b/media/base/media_channel_impl.h
index eda47af..70bfe28 100644
--- a/media/base/media_channel_impl.h
+++ b/media/base/media_channel_impl.h
@@ -16,6 +16,7 @@
 
 #include <functional>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
@@ -23,7 +24,6 @@
 
 #include "absl/functional/any_invocable.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/audio_options.h"
 #include "api/call/audio_sink.h"
 #include "api/call/transport.h"
diff --git a/media/base/media_engine.cc b/media/base/media_engine.cc
index c551a58..37ec552 100644
--- a/media/base/media_engine.cc
+++ b/media/base/media_engine.cc
@@ -68,7 +68,7 @@
 webrtc::RTCError CheckScalabilityModeValues(
     const webrtc::RtpParameters& rtp_parameters,
     rtc::ArrayView<cricket::Codec> send_codecs,
-    absl::optional<cricket::Codec> send_codec) {
+    std::optional<cricket::Codec> send_codec) {
   using webrtc::RTCErrorType;
 
   if (send_codecs.empty()) {
@@ -140,7 +140,7 @@
 webrtc::RTCError CheckRtpParametersValues(
     const webrtc::RtpParameters& rtp_parameters,
     rtc::ArrayView<cricket::Codec> send_codecs,
-    absl::optional<cricket::Codec> send_codec) {
+    std::optional<cricket::Codec> send_codec) {
   using webrtc::RTCErrorType;
 
   for (size_t i = 0; i < rtp_parameters.encodings.size(); ++i) {
@@ -203,14 +203,14 @@
     const webrtc::RtpParameters& old_rtp_parameters,
     const webrtc::RtpParameters& rtp_parameters) {
   return CheckRtpParametersInvalidModificationAndValues(
-      old_rtp_parameters, rtp_parameters, {}, absl::nullopt);
+      old_rtp_parameters, rtp_parameters, {}, std::nullopt);
 }
 
 webrtc::RTCError CheckRtpParametersInvalidModificationAndValues(
     const webrtc::RtpParameters& old_rtp_parameters,
     const webrtc::RtpParameters& rtp_parameters,
     rtc::ArrayView<cricket::Codec> send_codecs,
-    absl::optional<cricket::Codec> send_codec) {
+    std::optional<cricket::Codec> send_codec) {
   using webrtc::RTCErrorType;
   if (rtp_parameters.encodings.size() != old_rtp_parameters.encodings.size()) {
     LOG_AND_RETURN_ERROR(
diff --git a/media/base/media_engine.h b/media/base/media_engine.h
index 3deda09..f3a7a9c 100644
--- a/media/base/media_engine.h
+++ b/media/base/media_engine.h
@@ -41,14 +41,14 @@
 webrtc::RTCError CheckScalabilityModeValues(
     const webrtc::RtpParameters& new_parameters,
     rtc::ArrayView<cricket::Codec> send_codecs,
-    absl::optional<cricket::Codec> send_codec);
+    std::optional<cricket::Codec> send_codec);
 
 // Checks the parameters have valid and supported values, and checks parameters
 // with CheckScalabilityModeValues().
 webrtc::RTCError CheckRtpParametersValues(
     const webrtc::RtpParameters& new_parameters,
     rtc::ArrayView<cricket::Codec> send_codecs,
-    absl::optional<cricket::Codec> send_codec);
+    std::optional<cricket::Codec> send_codec);
 
 // Checks that the immutable values have not changed in new_parameters and
 // checks all parameters with CheckRtpParametersValues().
@@ -56,7 +56,7 @@
     const webrtc::RtpParameters& old_parameters,
     const webrtc::RtpParameters& new_parameters,
     rtc::ArrayView<cricket::Codec> send_codecs,
-    absl::optional<cricket::Codec> send_codec);
+    std::optional<cricket::Codec> send_codec);
 
 // Checks that the immutable values have not changed in new_parameters and
 // checks parameters (except SVC) with CheckRtpParametersValues(). It should
@@ -130,7 +130,7 @@
   // Stops recording AEC dump.
   virtual void StopAecDump() = 0;
 
-  virtual absl::optional<webrtc::AudioDeviceModule::Stats>
+  virtual std::optional<webrtc::AudioDeviceModule::Stats>
   GetAudioDeviceStats() = 0;
 };
 
diff --git a/media/base/media_engine_unittest.cc b/media/base/media_engine_unittest.cc
index 6f78d61..a223254 100644
--- a/media/base/media_engine_unittest.cc
+++ b/media/base/media_engine_unittest.cc
@@ -77,7 +77,7 @@
               (webrtc::FileWrapper file, int64_t max_size_bytes),
               (override));
   MOCK_METHOD(void, StopAecDump, (), (override));
-  MOCK_METHOD(absl::optional<webrtc::AudioDeviceModule::Stats>,
+  MOCK_METHOD(std::optional<webrtc::AudioDeviceModule::Stats>,
               GetAudioDeviceStats,
               (),
               (override));
diff --git a/media/base/sdp_video_format_utils.cc b/media/base/sdp_video_format_utils.cc
index 81ddb7b..c76afad 100644
--- a/media/base/sdp_video_format_utils.cc
+++ b/media/base/sdp_video_format_utils.cc
@@ -57,17 +57,17 @@
   return H264LevelIsLess(a, b) ? a : b;
 }
 
-absl::optional<int> ParsePositiveNumberFromParams(
+std::optional<int> ParsePositiveNumberFromParams(
     const CodecParameterMap& params,
     const char* parameter_name) {
   const auto max_frame_rate_it = params.find(parameter_name);
   if (max_frame_rate_it == params.end())
-    return absl::nullopt;
+    return std::nullopt;
 
-  const absl::optional<int> i =
+  const std::optional<int> i =
       rtc::StringToNumber<int>(max_frame_rate_it->second);
   if (!i.has_value() || i.value() <= 0)
-    return absl::nullopt;
+    return std::nullopt;
   return i;
 }
 
@@ -102,9 +102,9 @@
   }
 
   // Parse profile-tier-level.
-  const absl::optional<H265ProfileTierLevel> local_profile_tier_level =
+  const std::optional<H265ProfileTierLevel> local_profile_tier_level =
       ParseSdpForH265ProfileTierLevel(local_supported_params);
-  const absl::optional<H265ProfileTierLevel> remote_profile_tier_level =
+  const std::optional<H265ProfileTierLevel> remote_profile_tier_level =
       ParseSdpForH265ProfileTierLevel(remote_offered_params);
   // Profile and tier for local and remote codec must be valid and equal.
   RTC_DCHECK(local_profile_tier_level);
@@ -138,9 +138,9 @@
   }
 
   // Parse profile-level-ids.
-  const absl::optional<H264ProfileLevelId> local_profile_level_id =
+  const std::optional<H264ProfileLevelId> local_profile_level_id =
       ParseSdpForH264ProfileLevelId(local_supported_params);
-  const absl::optional<H264ProfileLevelId> remote_profile_level_id =
+  const std::optional<H264ProfileLevelId> remote_profile_level_id =
       ParseSdpForH264ProfileLevelId(remote_offered_params);
   // The local and remote codec must have valid and equal H264 Profiles.
   RTC_DCHECK(local_profile_level_id);
@@ -167,17 +167,15 @@
       H264ProfileLevelId(local_profile_level_id->profile, answer_level));
 }
 
-absl::optional<int> ParseSdpForVPxMaxFrameRate(
-    const CodecParameterMap& params) {
+std::optional<int> ParseSdpForVPxMaxFrameRate(const CodecParameterMap& params) {
   return ParsePositiveNumberFromParams(params, kVPxFmtpMaxFrameRate);
 }
 
-absl::optional<int> ParseSdpForVPxMaxFrameSize(
-    const CodecParameterMap& params) {
-  const absl::optional<int> i =
+std::optional<int> ParseSdpForVPxMaxFrameSize(const CodecParameterMap& params) {
+  const std::optional<int> i =
       ParsePositiveNumberFromParams(params, kVPxFmtpMaxFrameSize);
-  return i ? absl::make_optional(i.value() * kVPxFmtpFrameSizeSubBlockPixels)
-           : absl::nullopt;
+  return i ? std::make_optional(i.value() * kVPxFmtpFrameSizeSubBlockPixels)
+           : std::nullopt;
 }
 
 bool SupportsPerLayerPictureLossIndication(const CodecParameterMap& params) {
diff --git a/media/base/sdp_video_format_utils.h b/media/base/sdp_video_format_utils.h
index e6a4ca7..75b8f71 100644
--- a/media/base/sdp_video_format_utils.h
+++ b/media/base/sdp_video_format_utils.h
@@ -11,7 +11,8 @@
 #ifndef MEDIA_BASE_SDP_VIDEO_FORMAT_UTILS_H_
 #define MEDIA_BASE_SDP_VIDEO_FORMAT_UTILS_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/video_codecs/sdp_video_format.h"
 
 namespace webrtc {
@@ -48,14 +49,14 @@
     CodecParameterMap* answer_params);
 #endif
 
-// Parse max frame rate from SDP FMTP line. absl::nullopt is returned if the
+// Parse max frame rate from SDP FMTP line. std::nullopt is returned if the
 // field is missing or not a number.
-absl::optional<int> ParseSdpForVPxMaxFrameRate(const CodecParameterMap& params);
+std::optional<int> ParseSdpForVPxMaxFrameRate(const CodecParameterMap& params);
 
-// Parse max frame size from SDP FMTP line. absl::nullopt is returned if the
+// Parse max frame size from SDP FMTP line. std::nullopt is returned if the
 // field is missing or not a number. Please note that the value is stored in sub
 // blocks but the returned value is in total number of pixels.
-absl::optional<int> ParseSdpForVPxMaxFrameSize(const CodecParameterMap& params);
+std::optional<int> ParseSdpForVPxMaxFrameSize(const CodecParameterMap& params);
 
 // Determines whether the non-standard x-google-per-layer-pli fmtp is present
 // in the parameters and has a value of "1".
diff --git a/media/base/sdp_video_format_utils_unittest.cc b/media/base/sdp_video_format_utils_unittest.cc
index 04327d3..d9a0600 100644
--- a/media/base/sdp_video_format_utils_unittest.cc
+++ b/media/base/sdp_video_format_utils_unittest.cc
@@ -106,7 +106,7 @@
 
 TEST(SdpVideoFormatUtilsTest, MaxFrameRateIsMissingOrInvalid) {
   CodecParameterMap params;
-  absl::optional<int> empty = ParseSdpForVPxMaxFrameRate(params);
+  std::optional<int> empty = ParseSdpForVPxMaxFrameRate(params);
   EXPECT_FALSE(empty);
   params[kVPxFmtpMaxFrameRate] = "-1";
   EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params));
@@ -126,7 +126,7 @@
 
 TEST(SdpVideoFormatUtilsTest, MaxFrameSizeIsMissingOrInvalid) {
   CodecParameterMap params;
-  absl::optional<int> empty = ParseSdpForVPxMaxFrameSize(params);
+  std::optional<int> empty = ParseSdpForVPxMaxFrameSize(params);
   EXPECT_FALSE(empty);
   params[kVPxFmtpMaxFrameSize] = "-1";
   EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params));
diff --git a/media/base/video_adapter.cc b/media/base/video_adapter.cc
index 5eadbf8..1d0beb5 100644
--- a/media/base/video_adapter.cc
+++ b/media/base/video_adapter.cc
@@ -15,9 +15,9 @@
 #include <cstdint>
 #include <cstdlib>
 #include <limits>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "media/base/video_common.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
@@ -121,10 +121,10 @@
   return best_scale;
 }
 
-absl::optional<std::pair<int, int>> Swap(
-    const absl::optional<std::pair<int, int>>& in) {
+std::optional<std::pair<int, int>> Swap(
+    const std::optional<std::pair<int, int>>& in) {
   if (!in) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return std::make_pair(in->second, in->first);
 }
@@ -175,7 +175,7 @@
 
   // Select target aspect ratio and max pixel count depending on input frame
   // orientation.
-  absl::optional<std::pair<int, int>> target_aspect_ratio;
+  std::optional<std::pair<int, int>> target_aspect_ratio;
   if (in_width > in_height) {
     target_aspect_ratio = output_format_request_.target_landscape_aspect_ratio;
     if (output_format_request_.max_landscape_pixel_count)
@@ -268,10 +268,10 @@
 }
 
 void VideoAdapter::OnOutputFormatRequest(
-    const absl::optional<VideoFormat>& format) {
-  absl::optional<std::pair<int, int>> target_aspect_ratio;
-  absl::optional<int> max_pixel_count;
-  absl::optional<int> max_fps;
+    const std::optional<VideoFormat>& format) {
+  std::optional<std::pair<int, int>> target_aspect_ratio;
+  std::optional<int> max_pixel_count;
+  std::optional<int> max_fps;
   if (format) {
     target_aspect_ratio = std::make_pair(format->width, format->height);
     max_pixel_count = format->width * format->height;
@@ -282,11 +282,11 @@
 }
 
 void VideoAdapter::OnOutputFormatRequest(
-    const absl::optional<std::pair<int, int>>& target_aspect_ratio,
-    const absl::optional<int>& max_pixel_count,
-    const absl::optional<int>& max_fps) {
-  absl::optional<std::pair<int, int>> target_landscape_aspect_ratio;
-  absl::optional<std::pair<int, int>> target_portrait_aspect_ratio;
+    const std::optional<std::pair<int, int>>& target_aspect_ratio,
+    const std::optional<int>& max_pixel_count,
+    const std::optional<int>& max_fps) {
+  std::optional<std::pair<int, int>> target_landscape_aspect_ratio;
+  std::optional<std::pair<int, int>> target_portrait_aspect_ratio;
   if (target_aspect_ratio && target_aspect_ratio->first > 0 &&
       target_aspect_ratio->second > 0) {
     // Maintain input orientation.
@@ -302,11 +302,11 @@
 }
 
 void VideoAdapter::OnOutputFormatRequest(
-    const absl::optional<std::pair<int, int>>& target_landscape_aspect_ratio,
-    const absl::optional<int>& max_landscape_pixel_count,
-    const absl::optional<std::pair<int, int>>& target_portrait_aspect_ratio,
-    const absl::optional<int>& max_portrait_pixel_count,
-    const absl::optional<int>& max_fps) {
+    const std::optional<std::pair<int, int>>& target_landscape_aspect_ratio,
+    const std::optional<int>& max_landscape_pixel_count,
+    const std::optional<std::pair<int, int>>& target_portrait_aspect_ratio,
+    const std::optional<int>& max_portrait_pixel_count,
+    const std::optional<int>& max_fps) {
   webrtc::MutexLock lock(&mutex_);
 
   OutputFormatRequest request = {
diff --git a/media/base/video_adapter.h b/media/base/video_adapter.h
index c1d311d..35ed672 100644
--- a/media/base/video_adapter.h
+++ b/media/base/video_adapter.h
@@ -13,10 +13,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/video/video_source_interface.h"
 #include "common_video/framerate_controller.h"
 #include "media/base/video_common.h"
@@ -62,7 +62,7 @@
   // maintain the input orientation, so it doesn't matter if e.g. 1280x720 or
   // 720x1280 is requested.
   // Note: Should be called from the source only.
-  void OnOutputFormatRequest(const absl::optional<VideoFormat>& format)
+  void OnOutputFormatRequest(const std::optional<VideoFormat>& format)
       RTC_LOCKS_EXCLUDED(mutex_);
 
   // Requests output frame size and frame interval from `AdaptFrameResolution`.
@@ -74,20 +74,20 @@
   // `max_fps`: The maximum output framerate.
   // Note: Should be called from the source only.
   void OnOutputFormatRequest(
-      const absl::optional<std::pair<int, int>>& target_aspect_ratio,
-      const absl::optional<int>& max_pixel_count,
-      const absl::optional<int>& max_fps) RTC_LOCKS_EXCLUDED(mutex_);
+      const std::optional<std::pair<int, int>>& target_aspect_ratio,
+      const std::optional<int>& max_pixel_count,
+      const std::optional<int>& max_fps) RTC_LOCKS_EXCLUDED(mutex_);
 
   // Same as above, but allows setting two different target aspect ratios
   // depending on incoming frame orientation. This gives more fine-grained
   // control and can e.g. be used to force landscape video to be cropped to
   // portrait video.
   void OnOutputFormatRequest(
-      const absl::optional<std::pair<int, int>>& target_landscape_aspect_ratio,
-      const absl::optional<int>& max_landscape_pixel_count,
-      const absl::optional<std::pair<int, int>>& target_portrait_aspect_ratio,
-      const absl::optional<int>& max_portrait_pixel_count,
-      const absl::optional<int>& max_fps) RTC_LOCKS_EXCLUDED(mutex_);
+      const std::optional<std::pair<int, int>>& target_landscape_aspect_ratio,
+      const std::optional<int>& max_landscape_pixel_count,
+      const std::optional<std::pair<int, int>>& target_portrait_aspect_ratio,
+      const std::optional<int>& max_portrait_pixel_count,
+      const std::optional<int>& max_fps) RTC_LOCKS_EXCLUDED(mutex_);
 
   // Requests the output frame size from `AdaptFrameResolution` to have as close
   // as possible to `sink_wants.target_pixel_count` pixels (if set)
@@ -134,11 +134,11 @@
   // OnResolutionFramerateRequest respectively.
   // The adapted output format is the minimum of these.
   struct OutputFormatRequest {
-    absl::optional<std::pair<int, int>> target_landscape_aspect_ratio;
-    absl::optional<int> max_landscape_pixel_count;
-    absl::optional<std::pair<int, int>> target_portrait_aspect_ratio;
-    absl::optional<int> max_portrait_pixel_count;
-    absl::optional<int> max_fps;
+    std::optional<std::pair<int, int>> target_landscape_aspect_ratio;
+    std::optional<int> max_landscape_pixel_count;
+    std::optional<std::pair<int, int>> target_portrait_aspect_ratio;
+    std::optional<int> max_portrait_pixel_count;
+    std::optional<int> max_fps;
 
     // For logging.
     std::string ToString() const;
@@ -157,7 +157,7 @@
   // frame). This allows for an application to only use
   // RtpEncodingParameters::request_resolution and get the same behavior as if
   // it had used VideoAdapter::OnOutputFormatRequest.
-  absl::optional<OutputFormatRequest> stashed_output_format_request_
+  std::optional<OutputFormatRequest> stashed_output_format_request_
       RTC_GUARDED_BY(mutex_);
 
   webrtc::FramerateController framerate_controller_ RTC_GUARDED_BY(mutex_);
diff --git a/media/base/video_adapter_unittest.cc b/media/base/video_adapter_unittest.cc
index 778e61e..aab96dc 100644
--- a/media/base/video_adapter_unittest.cc
+++ b/media/base/video_adapter_unittest.cc
@@ -36,7 +36,7 @@
 using ::testing::Pair;
 using webrtc::Resolution;
 
-rtc::VideoSinkWants BuildSinkWants(absl::optional<int> target_pixel_count,
+rtc::VideoSinkWants BuildSinkWants(std::optional<int> target_pixel_count,
                                    int max_pixel_count,
                                    int max_framerate_fps,
                                    int sink_alignment = 1) {
@@ -52,7 +52,7 @@
 }
 
 rtc::VideoSinkWants BuildSinkWants(
-    absl::optional<webrtc::Resolution> requested_resolution,
+    std::optional<webrtc::Resolution> requested_resolution,
     bool any_active_without_requested_resolution) {
   rtc::VideoSinkWants wants;
   wants.max_framerate_fps = kDefaultFps;
@@ -153,12 +153,12 @@
 
   void OnOutputFormatRequest(int width,
                              int height,
-                             const absl::optional<int>& fps) {
+                             const std::optional<int>& fps) {
     if (use_new_format_request_) {
-      absl::optional<std::pair<int, int>> target_aspect_ratio =
+      std::optional<std::pair<int, int>> target_aspect_ratio =
           std::make_pair(width, height);
-      absl::optional<int> max_pixel_count = width * height;
-      absl::optional<int> max_fps = fps;
+      std::optional<int> max_pixel_count = width * height;
+      std::optional<int> max_fps = fps;
       adapter_.OnOutputFormatRequest(target_aspect_ratio, max_pixel_count,
                                      max_fps);
       return;
@@ -211,7 +211,7 @@
 }
 
 TEST_P(VideoAdapterTest, AdaptZeroInterval) {
-  OnOutputFormatRequest(kWidth, kHeight, absl::nullopt);
+  OnOutputFormatRequest(kWidth, kHeight, std::nullopt);
   for (int i = 0; i < 40; ++i)
     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
 
@@ -265,7 +265,7 @@
 // Expect the number of dropped frames to be half of the number the captured
 // frames.
 TEST_P(VideoAdapterTest, AdaptFramerateToHalfWithNoPixelLimit) {
-  adapter_.OnOutputFormatRequest(absl::nullopt, absl::nullopt, kDefaultFps / 2);
+  adapter_.OnOutputFormatRequest(std::nullopt, std::nullopt, kDefaultFps / 2);
 
   // Capture 10 frames and verify that every other frame is dropped. The first
   // frame should not be dropped.
@@ -305,7 +305,7 @@
 // Do not adapt the frame rate or the resolution. Expect no frame drop, no
 // cropping, and no resolution change.
 TEST_P(VideoAdapterTest, AdaptFramerateRequestMax) {
-  adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
+  adapter_.OnSinkWants(BuildSinkWants(std::nullopt,
                                       std::numeric_limits<int>::max(),
                                       std::numeric_limits<int>::max()));
 
@@ -322,7 +322,7 @@
 
 TEST_P(VideoAdapterTest, AdaptFramerateRequestZero) {
   adapter_.OnSinkWants(
-      BuildSinkWants(absl::nullopt, std::numeric_limits<int>::max(), 0));
+      BuildSinkWants(std::nullopt, std::numeric_limits<int>::max(), 0));
   for (int i = 0; i < 10; ++i)
     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
 
@@ -336,7 +336,7 @@
 // the number of dropped frames to be half of the number the captured frames.
 TEST_P(VideoAdapterTest, AdaptFramerateRequestHalf) {
   adapter_.OnSinkWants(BuildSinkWants(
-      absl::nullopt, std::numeric_limits<int>::max(), kDefaultFps / 2));
+      std::nullopt, std::numeric_limits<int>::max(), kDefaultFps / 2));
   for (int i = 0; i < 10; ++i)
     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
 
@@ -451,7 +451,7 @@
   EXPECT_EQ(400, out_height_);
 
   // Format request 640x400.
-  OnOutputFormatRequest(640, 400, absl::nullopt);
+  OnOutputFormatRequest(640, 400, std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -462,7 +462,7 @@
 
   // Request 1280x720, higher than input, but aspect 16:9. Expect cropping but
   // no scaling.
-  OnOutputFormatRequest(1280, 720, absl::nullopt);
+  OnOutputFormatRequest(1280, 720, std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -472,13 +472,13 @@
   EXPECT_EQ(360, out_height_);
 
   // Request 0x0.
-  OnOutputFormatRequest(0, 0, absl::nullopt);
+  OnOutputFormatRequest(0, 0, std::nullopt);
   EXPECT_FALSE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
                                              &cropped_height_, &out_width_,
                                              &out_height_));
 
   // Request 320x200. Expect scaling, but no cropping.
-  OnOutputFormatRequest(320, 200, absl::nullopt);
+  OnOutputFormatRequest(320, 200, std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -490,7 +490,7 @@
   // Request resolution close to 2/3 scale. Expect adapt down. Scaling to 2/3
   // is not optimized and not allowed, therefore 1/2 scaling will be used
   // instead.
-  OnOutputFormatRequest(424, 265, absl::nullopt);
+  OnOutputFormatRequest(424, 265, std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -500,7 +500,7 @@
   EXPECT_EQ(200, out_height_);
 
   // Request resolution of 3 / 8. Expect adapt down.
-  OnOutputFormatRequest(640 * 3 / 8, 400 * 3 / 8, absl::nullopt);
+  OnOutputFormatRequest(640 * 3 / 8, 400 * 3 / 8, std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -510,7 +510,7 @@
   EXPECT_EQ(400 * 3 / 8, out_height_);
 
   // Switch back up. Expect adapt.
-  OnOutputFormatRequest(320, 200, absl::nullopt);
+  OnOutputFormatRequest(320, 200, std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -520,7 +520,7 @@
   EXPECT_EQ(200, out_height_);
 
   // Format request 480x300.
-  OnOutputFormatRequest(480, 300, absl::nullopt);
+  OnOutputFormatRequest(480, 300, std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -541,7 +541,7 @@
   EXPECT_EQ(720, out_height_);
 
   // Format request for VGA.
-  OnOutputFormatRequest(640, 360, absl::nullopt);
+  OnOutputFormatRequest(640, 360, std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -562,7 +562,7 @@
 
   // And another view request comes in for 640x360, which should have no
   // real impact.
-  OnOutputFormatRequest(640, 360, absl::nullopt);
+  OnOutputFormatRequest(640, 360, std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -574,7 +574,7 @@
 
 TEST_P(VideoAdapterTest, TestVgaWidth) {
   // Requested output format is 640x360.
-  OnOutputFormatRequest(640, 360, absl::nullopt);
+  OnOutputFormatRequest(640, 360, std::nullopt);
 
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
@@ -613,7 +613,7 @@
   EXPECT_EQ(720, out_height_);
 
   // Adapt down one step.
-  adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 1280 * 720 - 1,
+  adapter_.OnSinkWants(BuildSinkWants(std::nullopt, 1280 * 720 - 1,
                                       std::numeric_limits<int>::max()));
   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
@@ -624,7 +624,7 @@
   EXPECT_EQ(540, out_height_);
 
   // Adapt down one step more.
-  adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 960 * 540 - 1,
+  adapter_.OnSinkWants(BuildSinkWants(std::nullopt, 960 * 540 - 1,
                                       std::numeric_limits<int>::max()));
   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
@@ -635,7 +635,7 @@
   EXPECT_EQ(360, out_height_);
 
   // Adapt down one step more.
-  adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
+  adapter_.OnSinkWants(BuildSinkWants(std::nullopt, 640 * 360 - 1,
                                       std::numeric_limits<int>::max()));
   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
@@ -689,7 +689,7 @@
   EXPECT_EQ(720, out_height_);
 
   adapter_.OnSinkWants(
-      BuildSinkWants(absl::nullopt, 0, std::numeric_limits<int>::max()));
+      BuildSinkWants(std::nullopt, 0, std::numeric_limits<int>::max()));
   EXPECT_FALSE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
                                              &cropped_height_, &out_width_,
                                              &out_height_));
@@ -697,7 +697,7 @@
 
 TEST_P(VideoAdapterTest, TestOnResolutionRequestInLargeSteps) {
   // Large step down.
-  adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
+  adapter_.OnSinkWants(BuildSinkWants(std::nullopt, 640 * 360 - 1,
                                       std::numeric_limits<int>::max()));
   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
@@ -720,7 +720,7 @@
 }
 
 TEST_P(VideoAdapterTest, TestOnOutputFormatRequestCapsMaxResolution) {
-  adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
+  adapter_.OnSinkWants(BuildSinkWants(std::nullopt, 640 * 360 - 1,
                                       std::numeric_limits<int>::max()));
   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
@@ -730,7 +730,7 @@
   EXPECT_EQ(480, out_width_);
   EXPECT_EQ(270, out_height_);
 
-  OnOutputFormatRequest(640, 360, absl::nullopt);
+  OnOutputFormatRequest(640, 360, std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -739,8 +739,8 @@
   EXPECT_EQ(480, out_width_);
   EXPECT_EQ(270, out_height_);
 
-  adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 960 * 720,
-                                      std::numeric_limits<int>::max()));
+  adapter_.OnSinkWants(
+      BuildSinkWants(std::nullopt, 960 * 720, std::numeric_limits<int>::max()));
   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -759,7 +759,7 @@
   EXPECT_EQ(1280, out_width_);
   EXPECT_EQ(720, out_height_);
 
-  adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
+  adapter_.OnSinkWants(BuildSinkWants(std::nullopt, 640 * 360 - 1,
                                       std::numeric_limits<int>::max()));
   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
@@ -769,7 +769,7 @@
   EXPECT_EQ(480, out_width_);
   EXPECT_EQ(270, out_height_);
 
-  adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
+  adapter_.OnSinkWants(BuildSinkWants(std::nullopt,
                                       std::numeric_limits<int>::max(),
                                       std::numeric_limits<int>::max()));
   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
@@ -790,7 +790,7 @@
   EXPECT_EQ(1280, out_width_);
   EXPECT_EQ(720, out_height_);
 
-  adapter_.OnOutputFormatRequest(absl::nullopt, 640 * 360 - 1, absl::nullopt);
+  adapter_.OnOutputFormatRequest(std::nullopt, 640 * 360 - 1, std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -799,7 +799,7 @@
   EXPECT_EQ(480, out_width_);
   EXPECT_EQ(270, out_height_);
 
-  adapter_.OnOutputFormatRequest(absl::nullopt, absl::nullopt, absl::nullopt);
+  adapter_.OnOutputFormatRequest(std::nullopt, std::nullopt, std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -819,7 +819,7 @@
   EXPECT_GT(dropped_frames, 0);
 
   // Reset frame rate.
-  OnOutputFormatRequest(kWidth, kHeight, absl::nullopt);
+  OnOutputFormatRequest(kWidth, kHeight, std::nullopt);
   for (int i = 0; i < 20; ++i)
     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
 
@@ -830,8 +830,8 @@
 TEST_P(VideoAdapterTest, RequestAspectRatio) {
   // Request aspect ratio 320/180 (16:9), smaller than input, but no resolution
   // limit. Expect cropping but no scaling.
-  adapter_.OnOutputFormatRequest(std::make_pair(320, 180), absl::nullopt,
-                                 absl::nullopt);
+  adapter_.OnOutputFormatRequest(std::make_pair(320, 180), std::nullopt,
+                                 std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -841,7 +841,7 @@
   EXPECT_EQ(360, out_height_);
 
   adapter_.OnOutputFormatRequest(std::make_pair(1280, 720), 1280 * 720 - 1,
-                                 absl::nullopt);
+                                 std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(2592, 1944, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -854,7 +854,7 @@
 TEST_P(VideoAdapterTest, RequestAspectRatioWithDifferentOrientation) {
   // Request 720x1280, higher than input, but aspect 16:9. Orientation should
   // not matter, expect cropping but no scaling.
-  OnOutputFormatRequest(720, 1280, absl::nullopt);
+  OnOutputFormatRequest(720, 1280, std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -866,8 +866,8 @@
 
 TEST_P(VideoAdapterTest, InvalidAspectRatioIgnored) {
   // Request aspect ratio 320/0. Expect no cropping.
-  adapter_.OnOutputFormatRequest(std::make_pair(320, 0), absl::nullopt,
-                                 absl::nullopt);
+  adapter_.OnOutputFormatRequest(std::make_pair(320, 0), std::nullopt,
+                                 std::nullopt);
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
                                             &out_height_));
@@ -879,7 +879,7 @@
 
 TEST_P(VideoAdapterTest, TestCroppingWithResolutionRequest) {
   // Ask for 640x360 (16:9 aspect).
-  OnOutputFormatRequest(640, 360, absl::nullopt);
+  OnOutputFormatRequest(640, 360, std::nullopt);
   // Send 640x480 (4:3 aspect).
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
                                             &cropped_height_, &out_width_,
@@ -891,7 +891,7 @@
   EXPECT_EQ(360, out_height_);
 
   // Adapt down one step.
-  adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
+  adapter_.OnSinkWants(BuildSinkWants(std::nullopt, 640 * 360 - 1,
                                       std::numeric_limits<int>::max()));
   // Expect cropping to 16:9 format and 3/4 scaling.
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
@@ -903,7 +903,7 @@
   EXPECT_EQ(270, out_height_);
 
   // Adapt down one step more.
-  adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 480 * 270 - 1,
+  adapter_.OnSinkWants(BuildSinkWants(std::nullopt, 480 * 270 - 1,
                                       std::numeric_limits<int>::max()));
   // Expect cropping to 16:9 format and 1/2 scaling.
   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
@@ -953,9 +953,8 @@
 
 TEST_P(VideoAdapterTest, TestCroppingOddResolution) {
   // Ask for 640x360 (16:9 aspect), with 3/16 scaling.
-  OnOutputFormatRequest(640, 360, absl::nullopt);
-  adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
-                                      640 * 360 * 3 / 16 * 3 / 16,
+  OnOutputFormatRequest(640, 360, std::nullopt);
+  adapter_.OnSinkWants(BuildSinkWants(std::nullopt, 640 * 360 * 3 / 16 * 3 / 16,
                                       std::numeric_limits<int>::max()));
 
   // Send 640x480 (4:3 aspect).
@@ -975,8 +974,8 @@
   // Ask for 1920x1080 (16:9 aspect), with 1/16 scaling.
   const int w = 1920;
   const int h = 1080;
-  OnOutputFormatRequest(w, h, absl::nullopt);
-  adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, w * h * 1 / 16 * 1 / 16,
+  OnOutputFormatRequest(w, h, std::nullopt);
+  adapter_.OnSinkWants(BuildSinkWants(std::nullopt, w * h * 1 / 16 * 1 / 16,
                                       std::numeric_limits<int>::max()));
 
   // Send 1920x1080 (16:9 aspect).
@@ -1018,7 +1017,7 @@
                                              &cropped_width_, &cropped_height_,
                                              &out_width_, &out_height_));
 
-  adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 480 - 1,
+  adapter_.OnSinkWants(BuildSinkWants(std::nullopt, 640 * 480 - 1,
                                       std::numeric_limits<int>::max()));
 
   // Still expect all frames to be dropped
@@ -1100,7 +1099,7 @@
 TEST_P(VideoAdapterTest, AdaptResolutionInStepsFirst3_4) {
   const int kWidth = 1280;
   const int kHeight = 720;
-  OnOutputFormatRequest(kWidth, kHeight, absl::nullopt);  // 16:9 aspect.
+  OnOutputFormatRequest(kWidth, kHeight, std::nullopt);  // 16:9 aspect.
 
   // Scale factors: 3/4, 2/3, 3/4, 2/3, ...
   // Scale        : 3/4, 1/2, 3/8, 1/4, 3/16, 1/8.
@@ -1112,7 +1111,7 @@
 
   for (size_t i = 0; i < arraysize(kExpectedWidths); ++i) {
     // Adapt down one step.
-    adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
+    adapter_.OnSinkWants(BuildSinkWants(std::nullopt,
                                         request_width * request_height - 1,
                                         std::numeric_limits<int>::max()));
     EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
@@ -1128,7 +1127,7 @@
 TEST_P(VideoAdapterTest, AdaptResolutionInStepsFirst2_3) {
   const int kWidth = 1920;
   const int kHeight = 1080;
-  OnOutputFormatRequest(kWidth, kHeight, absl::nullopt);  // 16:9 aspect.
+  OnOutputFormatRequest(kWidth, kHeight, std::nullopt);  // 16:9 aspect.
 
   // Scale factors: 2/3, 3/4, 2/3, 3/4, ...
   // Scale:         2/3, 1/2, 1/3, 1/4, 1/6, 1/8, 1/12.
@@ -1140,7 +1139,7 @@
 
   for (size_t i = 0; i < arraysize(kExpectedWidths); ++i) {
     // Adapt down one step.
-    adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
+    adapter_.OnSinkWants(BuildSinkWants(std::nullopt,
                                         request_width * request_height - 1,
                                         std::numeric_limits<int>::max()));
     EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
@@ -1156,7 +1155,7 @@
 TEST_P(VideoAdapterTest, AdaptResolutionInStepsFirst2x2_3) {
   const int kWidth = 1440;
   const int kHeight = 1080;
-  OnOutputFormatRequest(kWidth, kHeight, absl::nullopt);  // 4:3 aspect.
+  OnOutputFormatRequest(kWidth, kHeight, std::nullopt);  // 4:3 aspect.
 
   // Scale factors: 2/3, 2/3, 3/4, 2/3, 3/4, ...
   // Scale        : 2/3, 4/9, 1/3, 2/9, 1/6, 1/9, 1/12, 1/18, 1/24, 1/36.
@@ -1168,7 +1167,7 @@
 
   for (size_t i = 0; i < arraysize(kExpectedWidths); ++i) {
     // Adapt down one step.
-    adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
+    adapter_.OnSinkWants(BuildSinkWants(std::nullopt,
                                         request_width * request_height - 1,
                                         std::numeric_limits<int>::max()));
     EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
@@ -1194,7 +1193,7 @@
   int frame_num = 1;
   for (const int sink_alignment : {2, 3, 4, 5}) {
     adapter_.OnSinkWants(
-        BuildSinkWants(absl::nullopt, std::numeric_limits<int>::max(),
+        BuildSinkWants(std::nullopt, std::numeric_limits<int>::max(),
                        std::numeric_limits<int>::max(), sink_alignment));
     EXPECT_TRUE(adapter_.AdaptFrameResolution(
         kSourceWidth, kSourceHeight,
@@ -1240,7 +1239,7 @@
     // New API inactive, old API inactive, use OnOutputFormatRequest.
     OnOutputFormatRequest(640, 360, kDefaultFps);
     adapter_.OnSinkWants(
-        BuildSinkWants(absl::nullopt,
+        BuildSinkWants(std::nullopt,
                        /* any_active_without_requested_resolution= */ false));
 
     EXPECT_THAT(
@@ -1272,7 +1271,7 @@
 
     // Disable new API => fallback to last OnOutputFormatRequest.
     adapter_.OnSinkWants(
-        BuildSinkWants(absl::nullopt,
+        BuildSinkWants(std::nullopt,
                        /* any_active_without_requested_resolution= */ false));
 
     EXPECT_THAT(
@@ -1318,7 +1317,7 @@
   OnOutputFormatRequest(kRequestedWidth, kRequestedHeight, kRequestedFramerate);
 
   adapter_.OnSinkWants(BuildSinkWants(
-      absl::nullopt, std::numeric_limits<int>::max(),
+      std::nullopt, std::numeric_limits<int>::max(),
       std::numeric_limits<int>::max(), kSinkResolutionAlignment));
   EXPECT_TRUE(adapter_.AdaptFrameResolution(
       kSourceWidth, kSourceHeight, /*in_timestamp_ns=*/0, &cropped_width_,
diff --git a/media/base/video_broadcaster.cc b/media/base/video_broadcaster.cc
index 43c1773..b34b8db 100644
--- a/media/base/video_broadcaster.cc
+++ b/media/base/video_broadcaster.cc
@@ -11,9 +11,9 @@
 #include "media/base/video_broadcaster.h"
 
 #include <algorithm>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/video/i420_buffer.h"
 #include "api/video/video_rotation.h"
 #include "media/base/video_common.h"
diff --git a/media/base/video_broadcaster.h b/media/base/video_broadcaster.h
index c253d44..6b37cd7 100644
--- a/media/base/video_broadcaster.h
+++ b/media/base/video_broadcaster.h
@@ -73,7 +73,7 @@
   rtc::scoped_refptr<webrtc::VideoFrameBuffer> black_frame_buffer_;
   bool previous_frame_sent_to_all_sinks_ RTC_GUARDED_BY(sinks_and_wants_lock_) =
       true;
-  absl::optional<webrtc::VideoTrackSourceConstraints> last_constraints_
+  std::optional<webrtc::VideoTrackSourceConstraints> last_constraints_
       RTC_GUARDED_BY(sinks_and_wants_lock_);
 };
 
diff --git a/media/base/video_broadcaster_unittest.cc b/media/base/video_broadcaster_unittest.cc
index bb80c11..7ab122d 100644
--- a/media/base/video_broadcaster_unittest.cc
+++ b/media/base/video_broadcaster_unittest.cc
@@ -11,8 +11,8 @@
 #include "media/base/video_broadcaster.h"
 
 #include <limits>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/video/i420_buffer.h"
 #include "api/video/video_frame.h"
 #include "api/video/video_rotation.h"
@@ -297,21 +297,21 @@
 
   EXPECT_CALL(sink, OnConstraintsChanged(AllOf(
                         Field(&webrtc::VideoTrackSourceConstraints::min_fps,
-                              Eq(absl::nullopt)),
+                              Eq(std::nullopt)),
                         Field(&webrtc::VideoTrackSourceConstraints::max_fps,
-                              Eq(absl::nullopt)))));
+                              Eq(std::nullopt)))));
   broadcaster.ProcessConstraints(
-      webrtc::VideoTrackSourceConstraints{absl::nullopt, absl::nullopt});
+      webrtc::VideoTrackSourceConstraints{std::nullopt, std::nullopt});
   Mock::VerifyAndClearExpectations(&sink);
 
   EXPECT_CALL(
       sink,
       OnConstraintsChanged(AllOf(
           Field(&webrtc::VideoTrackSourceConstraints::min_fps,
-                Eq(absl::nullopt)),
+                Eq(std::nullopt)),
           Field(&webrtc::VideoTrackSourceConstraints::max_fps, Optional(3)))));
   broadcaster.ProcessConstraints(
-      webrtc::VideoTrackSourceConstraints{absl::nullopt, 3});
+      webrtc::VideoTrackSourceConstraints{std::nullopt, 3});
   Mock::VerifyAndClearExpectations(&sink);
 
   EXPECT_CALL(
@@ -319,9 +319,9 @@
       OnConstraintsChanged(AllOf(
           Field(&webrtc::VideoTrackSourceConstraints::min_fps, Optional(2)),
           Field(&webrtc::VideoTrackSourceConstraints::max_fps,
-                Eq(absl::nullopt)))));
+                Eq(std::nullopt)))));
   broadcaster.ProcessConstraints(
-      webrtc::VideoTrackSourceConstraints{2, absl::nullopt});
+      webrtc::VideoTrackSourceConstraints{2, std::nullopt});
   Mock::VerifyAndClearExpectations(&sink);
 
   EXPECT_CALL(
diff --git a/media/engine/fake_webrtc_call.h b/media/engine/fake_webrtc_call.h
index 7b76e10..64baab7 100644
--- a/media/engine/fake_webrtc_call.h
+++ b/media/engine/fake_webrtc_call.h
@@ -234,7 +234,7 @@
   bool framerate_scaling_enabled_;
   rtc::VideoSourceInterface<webrtc::VideoFrame>* source_;
   int num_swapped_frames_;
-  absl::optional<webrtc::VideoFrame> last_frame_;
+  std::optional<webrtc::VideoFrame> last_frame_;
   webrtc::VideoSendStream::Stats stats_;
   int num_encoder_reconfigurations_ = 0;
   std::vector<std::string> keyframes_requested_by_rid_;
diff --git a/media/engine/fake_webrtc_video_engine.cc b/media/engine/fake_webrtc_video_engine.cc
index cb70268..a701a95 100644
--- a/media/engine/fake_webrtc_video_engine.cc
+++ b/media/engine/fake_webrtc_video_engine.cc
@@ -32,7 +32,7 @@
 
 bool IsScalabilityModeSupported(
     const std::vector<webrtc::SdpVideoFormat>& formats,
-    absl::optional<std::string> scalability_mode) {
+    std::optional<std::string> scalability_mode) {
   if (!scalability_mode.has_value()) {
     return true;
   }
@@ -222,7 +222,7 @@
 webrtc::VideoEncoderFactory::CodecSupport
 FakeWebRtcVideoEncoderFactory::QueryCodecSupport(
     const webrtc::SdpVideoFormat& format,
-    absl::optional<std::string> scalability_mode) const {
+    std::optional<std::string> scalability_mode) const {
   std::vector<webrtc::SdpVideoFormat> supported_formats;
   for (const auto& f : formats_) {
     if (format.IsSameCodec(f))
diff --git a/media/engine/fake_webrtc_video_engine.h b/media/engine/fake_webrtc_video_engine.h
index bf3eed1..237085a 100644
--- a/media/engine/fake_webrtc_video_engine.h
+++ b/media/engine/fake_webrtc_video_engine.h
@@ -118,7 +118,7 @@
   std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override;
   webrtc::VideoEncoderFactory::CodecSupport QueryCodecSupport(
       const webrtc::SdpVideoFormat& format,
-      absl::optional<std::string> scalability_mode) const override;
+      std::optional<std::string> scalability_mode) const override;
   std::unique_ptr<webrtc::VideoEncoder> Create(
       const webrtc::Environment& env,
       const webrtc::SdpVideoFormat& format) override;
diff --git a/media/engine/internal_encoder_factory.cc b/media/engine/internal_encoder_factory.cc
index 398926a..95ac3d5 100644
--- a/media/engine/internal_encoder_factory.cc
+++ b/media/engine/internal_encoder_factory.cc
@@ -11,10 +11,10 @@
 #include "media/engine/internal_encoder_factory.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/video_codecs/sdp_video_format.h"
 #include "api/video_codecs/video_encoder_factory.h"
@@ -57,7 +57,7 @@
 
 VideoEncoderFactory::CodecSupport InternalEncoderFactory::QueryCodecSupport(
     const SdpVideoFormat& format,
-    absl::optional<std::string> scalability_mode) const {
+    std::optional<std::string> scalability_mode) const {
   auto original_format =
       FuzzyMatchSdpVideoFormat(Factory().GetSupportedFormats(), format);
   return original_format
diff --git a/media/engine/internal_encoder_factory.h b/media/engine/internal_encoder_factory.h
index 1d79d3c..ec04f9f 100644
--- a/media/engine/internal_encoder_factory.h
+++ b/media/engine/internal_encoder_factory.h
@@ -12,10 +12,10 @@
 #define MEDIA_ENGINE_INTERNAL_ENCODER_FACTORY_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/video_codecs/sdp_video_format.h"
 #include "api/video_codecs/video_encoder_factory.h"
@@ -27,7 +27,7 @@
   std::vector<SdpVideoFormat> GetSupportedFormats() const override;
   CodecSupport QueryCodecSupport(
       const SdpVideoFormat& format,
-      absl::optional<std::string> scalability_mode) const override;
+      std::optional<std::string> scalability_mode) const override;
   std::unique_ptr<VideoEncoder> Create(const Environment& env,
                                        const SdpVideoFormat& format) override;
 };
diff --git a/media/engine/internal_encoder_factory_unittest.cc b/media/engine/internal_encoder_factory_unittest.cc
index c13c528..fcd879e 100644
--- a/media/engine/internal_encoder_factory_unittest.cc
+++ b/media/engine/internal_encoder_factory_unittest.cc
@@ -121,17 +121,17 @@
 TEST(InternalEncoderFactoryTest, QueryCodecSupportNoScalabilityModeAv1) {
   InternalEncoderFactory factory;
   EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat::AV1Profile0(),
-                                        /*scalability_mode=*/absl::nullopt),
+                                        /*scalability_mode=*/std::nullopt),
               Support(kSupported));
 }
 
 TEST(InternalEncoderFactoryTest, QueryCodecSupportNoScalabilityMode) {
   InternalEncoderFactory factory;
   EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat::VP8(),
-                                        /*scalability_mode=*/absl::nullopt),
+                                        /*scalability_mode=*/std::nullopt),
               Support(kSupported));
   EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat::VP9Profile0(),
-                                        /*scalability_mode=*/absl::nullopt),
+                                        /*scalability_mode=*/std::nullopt),
               Support(kVp9Enabled ? kSupported : kUnsupported));
 }
 
diff --git a/media/engine/payload_type_mapper.cc b/media/engine/payload_type_mapper.cc
index 0f7c00e..9db2281 100644
--- a/media/engine/payload_type_mapper.cc
+++ b/media/engine/payload_type_mapper.cc
@@ -93,7 +93,7 @@
 
 PayloadTypeMapper::~PayloadTypeMapper() = default;
 
-absl::optional<int> PayloadTypeMapper::GetMappingFor(
+std::optional<int> PayloadTypeMapper::GetMappingFor(
     const webrtc::SdpAudioFormat& format) {
   auto iter = mappings_.find(format);
   if (iter != mappings_.end())
@@ -110,19 +110,19 @@
     }
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<int> PayloadTypeMapper::FindMappingFor(
+std::optional<int> PayloadTypeMapper::FindMappingFor(
     const webrtc::SdpAudioFormat& format) const {
   auto iter = mappings_.find(format);
   if (iter != mappings_.end())
     return iter->second;
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<Codec> PayloadTypeMapper::ToAudioCodec(
+std::optional<Codec> PayloadTypeMapper::ToAudioCodec(
     const webrtc::SdpAudioFormat& format) {
   // TODO(ossu): We can safely set bitrate to zero here, since that field is
   // not presented in the SDP. It is used to ferry around some target bitrate
@@ -138,7 +138,7 @@
     return std::move(codec);
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool PayloadTypeMapper::SdpAudioFormatOrdering::operator()(
diff --git a/media/engine/payload_type_mapper.h b/media/engine/payload_type_mapper.h
index 3a79a4d..246b04e 100644
--- a/media/engine/payload_type_mapper.h
+++ b/media/engine/payload_type_mapper.h
@@ -12,9 +12,9 @@
 #define MEDIA_ENGINE_PAYLOAD_TYPE_MAPPER_H_
 
 #include <map>
+#include <optional>
 #include <set>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_format.h"
 #include "media/base/codec.h"
 
@@ -30,16 +30,15 @@
   // Finds the current payload type for `format` or assigns a new one, if no
   // current mapping exists. Will return an empty value if it was unable to
   // create a mapping, i.e. if all dynamic payload type ids have been used up.
-  absl::optional<int> GetMappingFor(const webrtc::SdpAudioFormat& format);
+  std::optional<int> GetMappingFor(const webrtc::SdpAudioFormat& format);
 
   // Finds the current payload type for `format`, if any. Returns an empty value
   // if no payload type mapping exists for the format.
-  absl::optional<int> FindMappingFor(
-      const webrtc::SdpAudioFormat& format) const;
+  std::optional<int> FindMappingFor(const webrtc::SdpAudioFormat& format) const;
 
   // Like GetMappingFor, but fills in an AudioCodec structure with the necessary
   // information instead.
-  absl::optional<Codec> ToAudioCodec(const webrtc::SdpAudioFormat& format);
+  std::optional<Codec> ToAudioCodec(const webrtc::SdpAudioFormat& format);
 
  private:
   struct SdpAudioFormatOrdering {
diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc
index 9bdb4d5..db36b73 100644
--- a/media/engine/simulcast_encoder_adapter.cc
+++ b/media/engine/simulcast_encoder_adapter.cc
@@ -17,6 +17,7 @@
 #include <cstdint>
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <utility>
@@ -24,7 +25,6 @@
 
 #include "absl/algorithm/container.h"
 #include "absl/base/nullability.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/environment/environment.h"
 #include "api/fec_controller_override.h"
@@ -809,7 +809,7 @@
   // By default, `scalability_mode` comes from SimulcastStream when
   // SimulcastEncoderAdapter is used. This allows multiple encodings of L1Tx,
   // but SimulcastStream currently does not support multiple spatial layers.
-  absl::optional<ScalabilityMode> scalability_mode =
+  std::optional<ScalabilityMode> scalability_mode =
       stream_params.GetScalabilityMode();
   // To support the full set of scalability modes in the event that this is the
   // only active encoding, prefer VideoCodec::GetScalabilityMode() if all other
@@ -907,7 +907,7 @@
   encoder_info.requested_resolution_alignment = 1;
   encoder_info.apply_alignment_to_all_simulcast_layers = false;
   encoder_info.supports_native_handle = true;
-  encoder_info.scaling_settings.thresholds = absl::nullopt;
+  encoder_info.scaling_settings.thresholds = std::nullopt;
 
   if (stream_contexts_.empty()) {
     // GetEncoderInfo queried before InitEncode. Only alignment info is needed
diff --git a/media/engine/simulcast_encoder_adapter.h b/media/engine/simulcast_encoder_adapter.h
index d713043..92d10a4 100644
--- a/media/engine/simulcast_encoder_adapter.h
+++ b/media/engine/simulcast_encoder_adapter.h
@@ -15,13 +15,13 @@
 #include <atomic>
 #include <list>
 #include <memory>
+#include <optional>
 #include <stack>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/base/nullability.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/fec_controller_override.h"
 #include "api/field_trials_view.h"
@@ -125,10 +125,10 @@
     void set_is_keyframe_needed() { is_keyframe_needed_ = true; }
     bool is_paused() const { return is_paused_; }
     void set_is_paused(bool is_paused) { is_paused_ = is_paused; }
-    absl::optional<double> target_fps() const {
+    std::optional<double> target_fps() const {
       return framerate_controller_ == nullptr
-                 ? absl::nullopt
-                 : absl::optional<double>(
+                 ? std::nullopt
+                 : std::optional<double>(
                        framerate_controller_->GetMaxFramerate());
     }
 
diff --git a/media/engine/simulcast_encoder_adapter_unittest.cc b/media/engine/simulcast_encoder_adapter_unittest.cc
index 5d38633..a52ac96 100644
--- a/media/engine/simulcast_encoder_adapter_unittest.cc
+++ b/media/engine/simulcast_encoder_adapter_unittest.cc
@@ -333,7 +333,7 @@
     video_format_ = video_format;
   }
 
-  void set_is_qp_trusted(absl::optional<bool> is_qp_trusted) {
+  void set_is_qp_trusted(std::optional<bool> is_qp_trusted) {
     is_qp_trusted_ = is_qp_trusted;
   }
 
@@ -360,7 +360,7 @@
   VideoEncoder::RateControlParameters last_set_rates_;
   FramerateFractions fps_allocation_;
   bool supports_simulcast_ = false;
-  absl::optional<bool> is_qp_trusted_;
+  std::optional<bool> is_qp_trusted_;
   SdpVideoFormat video_format_;
   std::vector<VideoEncoder::ResolutionBitrateLimits> resolution_bitrate_limits;
 
@@ -465,9 +465,9 @@
         env_, use_fallback_factory_,
         SdpVideoFormat("VP8", sdp_video_parameters_));
     adapter_ = helper_->CreateMockEncoderAdapter();
-    last_encoded_image_width_ = absl::nullopt;
-    last_encoded_image_height_ = absl::nullopt;
-    last_encoded_image_simulcast_index_ = absl::nullopt;
+    last_encoded_image_width_ = std::nullopt;
+    last_encoded_image_height_ = std::nullopt;
+    last_encoded_image_simulcast_index_ = std::nullopt;
   }
 
   void ReSetUp() {
@@ -489,9 +489,9 @@
     return Result(Result::OK, encoded_image.RtpTimestamp());
   }
 
-  bool GetLastEncodedImageInfo(absl::optional<int>* out_width,
-                               absl::optional<int>* out_height,
-                               absl::optional<int>* out_simulcast_index) {
+  bool GetLastEncodedImageInfo(std::optional<int>* out_width,
+                               std::optional<int>* out_height,
+                               std::optional<int>* out_simulcast_index) {
     if (!last_encoded_image_width_.has_value()) {
       return false;
     }
@@ -621,9 +621,9 @@
   std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
   std::unique_ptr<VideoEncoder> adapter_;
   VideoCodec codec_;
-  absl::optional<int> last_encoded_image_width_;
-  absl::optional<int> last_encoded_image_height_;
-  absl::optional<int> last_encoded_image_simulcast_index_;
+  std::optional<int> last_encoded_image_width_;
+  std::optional<int> last_encoded_image_height_;
+  std::optional<int> last_encoded_image_simulcast_index_;
   std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
   bool use_fallback_factory_;
   CodecParameterMap sdp_video_parameters_;
@@ -672,9 +672,9 @@
   std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
   ASSERT_EQ(3u, encoders.size());
   encoders[0]->SendEncodedImage(1152, 704);
-  absl::optional<int> width;
-  absl::optional<int> height;
-  absl::optional<int> simulcast_index;
+  std::optional<int> width;
+  std::optional<int> height;
+  std::optional<int> simulcast_index;
   EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
   ASSERT_TRUE(width.has_value());
   EXPECT_EQ(1152, width.value());
@@ -899,9 +899,9 @@
   std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
   ASSERT_EQ(3u, encoders.size());
   encoders[0]->SendEncodedImage(1152, 704);
-  absl::optional<int> width;
-  absl::optional<int> height;
-  absl::optional<int> simulcast_index;
+  std::optional<int> width;
+  std::optional<int> height;
+  std::optional<int> simulcast_index;
   EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
   // SEA doesn't intercept frame encode complete callback for the lowest stream.
   EXPECT_FALSE(simulcast_index.has_value());
diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc
index fcd7b23..ec51433 100644
--- a/media/engine/webrtc_video_engine.cc
+++ b/media/engine/webrtc_video_engine.cc
@@ -15,6 +15,7 @@
 #include <algorithm>
 #include <cstdint>
 #include <initializer_list>
+#include <optional>
 #include <set>
 #include <string>
 #include <type_traits>
@@ -24,7 +25,6 @@
 #include "absl/container/inlined_vector.h"
 #include "absl/functional/bind_front.h"
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/make_ref_counted.h"
 #include "api/media_stream_interface.h"
 #include "api/media_types.h"
@@ -422,19 +422,19 @@
   return res;
 }
 
-absl::optional<int> NumSpatialLayersFromEncoding(
+std::optional<int> NumSpatialLayersFromEncoding(
     const webrtc::RtpParameters& rtp_parameters,
     size_t idx) {
   if (idx >= rtp_parameters.encodings.size())
-    return absl::nullopt;
+    return std::nullopt;
 
-  absl::optional<webrtc::ScalabilityMode> scalability_mode =
+  std::optional<webrtc::ScalabilityMode> scalability_mode =
       webrtc::ScalabilityModeFromString(
           rtp_parameters.encodings[idx].scalability_mode.value_or(""));
   return scalability_mode
-             ? absl::optional<int>(
+             ? std::optional<int>(
                    ScalabilityModeToNumSpatialLayers(*scalability_mode))
-             : absl::nullopt;
+             : std::nullopt;
 }
 
 std::map<uint32_t, webrtc::VideoSendStream::StreamStats>
@@ -492,7 +492,7 @@
 }
 
 bool IsActiveFromEncodings(
-    absl::optional<uint32_t> ssrc,
+    std::optional<uint32_t> ssrc,
     const std::vector<webrtc::RtpEncodingParameters>& encodings) {
   if (ssrc.has_value()) {
     // Report the `active` value of a specific ssrc, or false if an encoding
@@ -574,7 +574,7 @@
   std::map<int, int> rtx_time_mapping;
 
   webrtc::UlpfecConfig ulpfec_config;
-  absl::optional<int> flexfec_payload_type;
+  std::optional<int> flexfec_payload_type;
 
   for (const Codec& in_codec : codecs) {
     const int payload_type = in_codec.id;
@@ -965,7 +965,7 @@
     vp9_settings.denoisingOn = codec_default_denoising ? true : denoising;
     // Disable automatic resize if more than one spatial layer is requested.
     bool vp9_automatic_resize = automatic_resize;
-    absl::optional<int> num_spatial_layers =
+    std::optional<int> num_spatial_layers =
         NumSpatialLayersFromEncoding(rtp_parameters_, /*idx=*/0);
     if (num_spatial_layers && *num_spatial_layers > 1) {
       vp9_automatic_resize = false;
@@ -1077,7 +1077,7 @@
       codec.flexfec_payload_type = -1;
   }
 
-  absl::optional<VideoCodecSettings> force_codec;
+  std::optional<VideoCodecSettings> force_codec;
   if (!send_streams_.empty()) {
     // Since we do not support mixed-codec simulcast yet,
     // all send streams must have the same codec value.
@@ -1104,7 +1104,7 @@
 
   if (negotiated_codecs_ != negotiated_codecs) {
     if (negotiated_codecs.empty()) {
-      changed_params->send_codec = absl::nullopt;
+      changed_params->send_codec = std::nullopt;
     } else if (force_codec) {
       changed_params->send_codec = force_codec;
     } else if (send_codec() != negotiated_codecs.front()) {
@@ -1122,7 +1122,7 @@
       call_->trials());
   if (send_rtp_extensions_ != filtered_extensions) {
     changed_params->rtp_header_extensions =
-        absl::optional<std::vector<webrtc::RtpExtension>>(filtered_extensions);
+        std::optional<std::vector<webrtc::RtpExtension>>(filtered_extensions);
   }
 
   if (params.mid != send_params_.mid) {
@@ -1404,11 +1404,11 @@
 
   return it->second->SetRtpParameters(parameters, std::move(callback));
 }
-absl::optional<Codec> WebRtcVideoSendChannel::GetSendCodec() const {
+std::optional<Codec> WebRtcVideoSendChannel::GetSendCodec() const {
   RTC_DCHECK_RUN_ON(&thread_checker_);
   if (!send_codec()) {
     RTC_LOG(LS_VERBOSE) << "GetSendCodec: No send codec set.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return send_codec()->codec;
 }
@@ -1703,7 +1703,7 @@
         webrtc::VideoSendStream::Config config,
         const VideoOptions& options,
         int max_bitrate_bps,
-        const absl::optional<VideoCodecSettings>& codec_settings)
+        const std::optional<VideoCodecSettings>& codec_settings)
     : config(std::move(config)),
       options(options),
       max_bitrate_bps(max_bitrate_bps),
@@ -1717,8 +1717,8 @@
     const VideoOptions& options,
     bool enable_cpu_overuse_detection,
     int max_bitrate_bps,
-    const absl::optional<VideoCodecSettings>& codec_settings,
-    const absl::optional<std::vector<webrtc::RtpExtension>>& rtp_extensions,
+    const std::optional<VideoCodecSettings>& codec_settings,
+    const std::optional<std::vector<webrtc::RtpExtension>>& rtp_extensions,
     // TODO(deadbeef): Don't duplicate information between send_params,
     // rtp_extensions, options, etc.
     const VideoSenderParameters& send_params)
@@ -2363,7 +2363,7 @@
         common_info.add_ssrc(ssrc);
       }
       common_info.active =
-          IsActiveFromEncodings(absl::nullopt, rtp_parameters_.encodings);
+          IsActiveFromEncodings(std::nullopt, rtp_parameters_.encodings);
       common_info.framerate_sent = stats.encode_frame_rate;
       common_info.frames_encoded = stats.frames_encoded;
       common_info.total_encode_time_ms = stats.total_encode_time_ms;
@@ -2390,7 +2390,7 @@
     info.add_ssrc(ssrc);
     info.rid = parameters_.config.rtp.GetRidForSsrc(ssrc);
     info.active = IsActiveFromEncodings(
-        !is_svc ? absl::optional<uint32_t>(ssrc) : absl::nullopt,
+        !is_svc ? std::optional<uint32_t>(ssrc) : std::nullopt,
         rtp_parameters_.encodings);
     auto stream_stats = pair.second;
     RTC_DCHECK_EQ(stream_stats.type,
@@ -2624,7 +2624,7 @@
     bool lntf_enabled,
     bool nack_enabled,
     webrtc::RtcpMode rtcp_mode,
-    absl::optional<int> rtx_time) {
+    std::optional<int> rtx_time) {
   RTC_DCHECK_RUN_ON(&thread_checker_);
 
   // Update receive feedback parameters from new codec or RTCP mode.
@@ -2722,7 +2722,7 @@
 
   if (NonFlexfecReceiveCodecsHaveChanged(recv_codecs_, mapped_codecs)) {
     changed_params->codec_settings =
-        absl::optional<std::vector<VideoCodecSettings>>(mapped_codecs);
+        std::optional<std::vector<VideoCodecSettings>>(mapped_codecs);
   }
 
   // Handle RTP header extensions.
@@ -2731,7 +2731,7 @@
       call_->trials());
   if (filtered_extensions != recv_rtp_extensions_) {
     changed_params->rtp_header_extensions =
-        absl::optional<std::vector<webrtc::RtpExtension>>(filtered_extensions);
+        std::optional<std::vector<webrtc::RtpExtension>>(filtered_extensions);
   }
 
   int flexfec_payload_type = mapped_codecs.front().flexfec_payload_type;
@@ -2958,7 +2958,7 @@
   RTC_DCHECK_RUN_ON(&thread_checker_);
   RTC_LOG(LS_INFO) << "ResetUnsignaledRecvStream.";
   unsignaled_stream_params_ = StreamParams();
-  last_unsignalled_ssrc_creation_time_ms_ = absl::nullopt;
+  last_unsignalled_ssrc_creation_time_ms_ = std::nullopt;
 
   // Delete any created default streams. This is needed to avoid SSRC collisions
   // in Call's RtpDemuxer, in the case that `this` has created a default video
@@ -2975,9 +2975,9 @@
   }
 }
 
-absl::optional<uint32_t> WebRtcVideoReceiveChannel::GetUnsignaledSsrc() const {
+std::optional<uint32_t> WebRtcVideoReceiveChannel::GetUnsignaledSsrc() const {
   RTC_DCHECK_RUN_ON(&thread_checker_);
-  absl::optional<uint32_t> ssrc;
+  std::optional<uint32_t> ssrc;
   for (auto it = receive_streams_.begin(); it != receive_streams_.end(); ++it) {
     if (it->second->IsDefaultStream()) {
       ssrc.emplace(it->first);
@@ -3128,7 +3128,7 @@
   if (is_rtx_payload) {
     // As we don't support receiving simulcast there can only be one RTX
     // stream, which will be associated with unsignaled media stream.
-    absl::optional<uint32_t> current_default_ssrc = GetUnsignaledSsrc();
+    std::optional<uint32_t> current_default_ssrc = GetUnsignaledSsrc();
     if (current_default_ssrc) {
       FindReceiveStream(*current_default_ssrc)->UpdateRtxSsrc(packet.Ssrc());
       return true;
@@ -3155,17 +3155,17 @@
   }
 
   // RTX SSRC not yet known.
-  ReCreateDefaultReceiveStream(packet.Ssrc(), absl::nullopt);
+  ReCreateDefaultReceiveStream(packet.Ssrc(), std::nullopt);
   last_unsignalled_ssrc_creation_time_ms_ = rtc::TimeMillis();
   return true;
 }
 
 void WebRtcVideoReceiveChannel::ReCreateDefaultReceiveStream(
     uint32_t ssrc,
-    absl::optional<uint32_t> rtx_ssrc) {
+    std::optional<uint32_t> rtx_ssrc) {
   RTC_DCHECK_RUN_ON(&thread_checker_);
 
-  absl::optional<uint32_t> default_recv_ssrc = GetUnsignaledSsrc();
+  std::optional<uint32_t> default_recv_ssrc = GetUnsignaledSsrc();
   if (default_recv_ssrc) {
     RTC_LOG(LS_INFO) << "Destroying old default receive stream for SSRC="
                      << ssrc << ".";
@@ -3215,7 +3215,7 @@
 bool WebRtcVideoReceiveChannel::SetBaseMinimumPlayoutDelayMs(uint32_t ssrc,
                                                              int delay_ms) {
   RTC_DCHECK_RUN_ON(&thread_checker_);
-  absl::optional<uint32_t> default_ssrc = GetUnsignaledSsrc();
+  std::optional<uint32_t> default_ssrc = GetUnsignaledSsrc();
 
   // SSRC of 0 represents the default receive stream.
   if (ssrc == 0) {
@@ -3240,7 +3240,7 @@
   }
 }
 
-absl::optional<int> WebRtcVideoReceiveChannel::GetBaseMinimumPlayoutDelayMs(
+std::optional<int> WebRtcVideoReceiveChannel::GetBaseMinimumPlayoutDelayMs(
     uint32_t ssrc) const {
   RTC_DCHECK_RUN_ON(&thread_checker_);
   // SSRC of 0 represents the default receive stream.
@@ -3253,7 +3253,7 @@
     return stream->second->GetBaseMinimumPlayoutDelayMs();
   } else {
     RTC_LOG(LS_ERROR) << "No stream found to get base minimum playout delay";
-    return absl::nullopt;
+    return std::nullopt;
   }
 }
 
@@ -3444,7 +3444,7 @@
     bool lntf_enabled,
     bool nack_enabled,
     webrtc::RtcpMode rtcp_mode,
-    absl::optional<int> rtx_time) {
+    std::optional<int> rtx_time) {
   RTC_DCHECK(stream_);
 
   if (config_.rtp.rtcp_mode != rtcp_mode) {
@@ -3520,8 +3520,8 @@
     RecreateReceiveStream() {
   RTC_DCHECK_RUN_ON(&thread_checker_);
   RTC_DCHECK(stream_);
-  absl::optional<int> base_minimum_playout_delay_ms;
-  absl::optional<webrtc::VideoReceiveStreamInterface::RecordingState>
+  std::optional<int> base_minimum_playout_delay_ms;
+  std::optional<webrtc::VideoReceiveStreamInterface::RecordingState>
       recording_state;
   if (stream_) {
     base_minimum_playout_delay_ms = stream_->GetBaseMinimumPlayoutDelayMs();
@@ -3828,7 +3828,7 @@
 WebRtcVideoReceiveChannel::WebRtcVideoReceiveStream*
 WebRtcVideoReceiveChannel::FindReceiveStream(uint32_t ssrc) {
   if (ssrc == 0) {
-    absl::optional<uint32_t> default_ssrc = GetUnsignaledSsrc();
+    std::optional<uint32_t> default_ssrc = GetUnsignaledSsrc();
     if (!default_ssrc) {
       return nullptr;
     }
diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h
index 14df03a..f5b5063 100644
--- a/media/engine/webrtc_video_engine.h
+++ b/media/engine/webrtc_video_engine.h
@@ -17,6 +17,7 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
@@ -24,7 +25,6 @@
 
 #include "absl/functional/any_invocable.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/call/transport.h"
 #include "api/crypto/crypto_options.h"
@@ -148,7 +148,7 @@
   webrtc::UlpfecConfig ulpfec;
   int flexfec_payload_type;  // -1 if absent.
   int rtx_payload_type;      // -1 if absent.
-  absl::optional<int> rtx_time;
+  std::optional<int> rtx_time;
 };
 
 class WebRtcVideoSendChannel : public MediaChannelUtil,
@@ -192,7 +192,7 @@
       const webrtc::RtpParameters& parameters,
       webrtc::SetParametersCallback callback) override;
   webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const override;
-  absl::optional<Codec> GetSendCodec() const override;
+  std::optional<Codec> GetSendCodec() const override;
   bool SetSend(bool send) override;
   bool SetVideoSend(
       uint32_t ssrc,
@@ -279,10 +279,10 @@
     }
     return HasNack(send_codec()->codec);
   }
-  absl::optional<int> SendCodecRtxTime() const override {
+  std::optional<int> SendCodecRtxTime() const override {
     RTC_DCHECK_RUN_ON(&thread_checker_);
     if (!send_codec()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return send_codec()->rtx_time;
   }
@@ -290,14 +290,14 @@
  private:
   struct ChangedSenderParameters {
     // These optionals are unset if not changed.
-    absl::optional<VideoCodecSettings> send_codec;
-    absl::optional<std::vector<VideoCodecSettings>> negotiated_codecs;
-    absl::optional<std::vector<webrtc::RtpExtension>> rtp_header_extensions;
-    absl::optional<std::string> mid;
-    absl::optional<bool> extmap_allow_mixed;
-    absl::optional<int> max_bandwidth_bps;
-    absl::optional<bool> conference_mode;
-    absl::optional<webrtc::RtcpMode> rtcp_mode;
+    std::optional<VideoCodecSettings> send_codec;
+    std::optional<std::vector<VideoCodecSettings>> negotiated_codecs;
+    std::optional<std::vector<webrtc::RtpExtension>> rtp_header_extensions;
+    std::optional<std::string> mid;
+    std::optional<bool> extmap_allow_mixed;
+    std::optional<int> max_bandwidth_bps;
+    std::optional<bool> conference_mode;
+    std::optional<webrtc::RtcpMode> rtcp_mode;
   };
 
   bool GetChangedSenderParameters(const VideoSenderParameters& params,
@@ -326,8 +326,8 @@
         const VideoOptions& options,
         bool enable_cpu_overuse_detection,
         int max_bitrate_bps,
-        const absl::optional<VideoCodecSettings>& codec_settings,
-        const absl::optional<std::vector<webrtc::RtpExtension>>& rtp_extensions,
+        const std::optional<VideoCodecSettings>& codec_settings,
+        const std::optional<std::vector<webrtc::RtpExtension>>& rtp_extensions,
         const VideoSenderParameters& send_params);
     ~WebRtcVideoSendStream();
 
@@ -374,12 +374,12 @@
           webrtc::VideoSendStream::Config config,
           const VideoOptions& options,
           int max_bitrate_bps,
-          const absl::optional<VideoCodecSettings>& codec_settings);
+          const std::optional<VideoCodecSettings>& codec_settings);
       webrtc::VideoSendStream::Config config;
       VideoOptions options;
       int max_bitrate_bps;
       bool conference_mode;
-      absl::optional<VideoCodecSettings> codec_settings;
+      std::optional<VideoCodecSettings> codec_settings;
       // Sent resolutions + bitrates etc. by the underlying VideoSendStream,
       // typically changes when setting a new resolution or reconfiguring
       // bitrates.
@@ -449,8 +449,8 @@
   // that a receive channel does not touch the send codec directly.
   // Can go away once these are different classes.
   // TODO(bugs.webrtc.org/13931): Remove this function
-  absl::optional<VideoCodecSettings>& send_codec() { return send_codec_; }
-  const absl::optional<VideoCodecSettings>& send_codec() const {
+  std::optional<VideoCodecSettings>& send_codec() { return send_codec_; }
+  const std::optional<VideoCodecSettings>& send_codec() const {
     return send_codec_;
   }
   webrtc::TaskQueueBase* const worker_thread_;
@@ -491,13 +491,12 @@
   //   is a risk of receiving ssrcs for other, recently added m= sections.
   uint32_t demuxer_criteria_id_ RTC_GUARDED_BY(thread_checker_) = 0;
   uint32_t demuxer_criteria_completed_id_ RTC_GUARDED_BY(thread_checker_) = 0;
-  absl::optional<int64_t> last_unsignalled_ssrc_creation_time_ms_
+  std::optional<int64_t> last_unsignalled_ssrc_creation_time_ms_
       RTC_GUARDED_BY(thread_checker_);
   std::set<uint32_t> send_ssrcs_ RTC_GUARDED_BY(thread_checker_);
   std::set<uint32_t> receive_ssrcs_ RTC_GUARDED_BY(thread_checker_);
 
-  absl::optional<VideoCodecSettings> send_codec_
-      RTC_GUARDED_BY(thread_checker_);
+  std::optional<VideoCodecSettings> send_codec_ RTC_GUARDED_BY(thread_checker_);
   std::vector<VideoCodecSettings> negotiated_codecs_
       RTC_GUARDED_BY(thread_checker_);
 
@@ -587,7 +586,7 @@
   }
   bool RemoveRecvStream(uint32_t ssrc) override;
   void ResetUnsignaledRecvStream() override;
-  absl::optional<uint32_t> GetUnsignaledSsrc() const override;
+  std::optional<uint32_t> GetUnsignaledSsrc() const override;
   void OnDemuxerCriteriaUpdatePending() override;
   void OnDemuxerCriteriaUpdateComplete() override;
   bool SetSink(uint32_t ssrc,
@@ -598,8 +597,7 @@
   void OnPacketReceived(const webrtc::RtpPacketReceived& packet) override;
   bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) override;
 
-  absl::optional<int> GetBaseMinimumPlayoutDelayMs(
-      uint32_t ssrc) const override;
+  std::optional<int> GetBaseMinimumPlayoutDelayMs(uint32_t ssrc) const override;
 
   // Choose one of the available SSRCs (or default if none) as the current
   // receiver report SSRC.
@@ -627,18 +625,18 @@
   void SetReceiverFeedbackParameters(bool lntf_enabled,
                                      bool nack_enabled,
                                      webrtc::RtcpMode rtcp_mode,
-                                     absl::optional<int> rtx_time) override;
+                                     std::optional<int> rtx_time) override;
 
  private:
   class WebRtcVideoReceiveStream;
   struct ChangedReceiverParameters {
     // These optionals are unset if not changed.
-    absl::optional<std::vector<VideoCodecSettings>> codec_settings;
-    absl::optional<std::vector<webrtc::RtpExtension>> rtp_header_extensions;
+    std::optional<std::vector<VideoCodecSettings>> codec_settings;
+    std::optional<std::vector<webrtc::RtpExtension>> rtp_header_extensions;
     // Keep track of the FlexFEC payload type separately from `codec_settings`.
     // This allows us to recreate the FlexfecReceiveStream separately from the
     // VideoReceiveStreamInterface when the FlexFEC payload type is changed.
-    absl::optional<int> flexfec_payload_type;
+    std::optional<int> flexfec_payload_type;
   };
 
   // Finds VideoReceiveStreamInterface corresponding to ssrc. Aware of
@@ -656,7 +654,7 @@
       const webrtc::RtpPacketReceived& parsed_packet)
       RTC_EXCLUSIVE_LOCKS_REQUIRED(thread_checker_);
   void ReCreateDefaultReceiveStream(uint32_t ssrc,
-                                    absl::optional<uint32_t> rtx_ssrc);
+                                    std::optional<uint32_t> rtx_ssrc);
   // Add a receive stream. Used for testing.
   bool AddRecvStream(const StreamParams& sp, bool default_stream);
 
@@ -704,7 +702,7 @@
     void SetFeedbackParameters(bool lntf_enabled,
                                bool nack_enabled,
                                webrtc::RtcpMode rtcp_mode,
-                               absl::optional<int> rtx_time);
+                               std::optional<int> rtx_time);
     void SetReceiverParameters(const ChangedReceiverParameters& recv_params);
 
     void OnFrame(const webrtc::VideoFrame& frame) override;
@@ -822,13 +820,12 @@
   //   is a risk of receiving ssrcs for other, recently added m= sections.
   uint32_t demuxer_criteria_id_ RTC_GUARDED_BY(thread_checker_) = 0;
   uint32_t demuxer_criteria_completed_id_ RTC_GUARDED_BY(thread_checker_) = 0;
-  absl::optional<int64_t> last_unsignalled_ssrc_creation_time_ms_
+  std::optional<int64_t> last_unsignalled_ssrc_creation_time_ms_
       RTC_GUARDED_BY(thread_checker_);
   std::set<uint32_t> send_ssrcs_ RTC_GUARDED_BY(thread_checker_);
   std::set<uint32_t> receive_ssrcs_ RTC_GUARDED_BY(thread_checker_);
 
-  absl::optional<VideoCodecSettings> send_codec_
-      RTC_GUARDED_BY(thread_checker_);
+  std::optional<VideoCodecSettings> send_codec_ RTC_GUARDED_BY(thread_checker_);
   std::vector<VideoCodecSettings> negotiated_codecs_
       RTC_GUARDED_BY(thread_checker_);
 
diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc
index 2046f8c..13ffe6f 100644
--- a/media/engine/webrtc_video_engine_unittest.cc
+++ b/media/engine/webrtc_video_engine_unittest.cc
@@ -408,7 +408,7 @@
   std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
       video_bitrate_allocator_factory_;
   WebRtcVideoEngine engine_;
-  absl::optional<Codec> default_codec_;
+  std::optional<Codec> default_codec_;
   std::map<int, int> default_apt_rtx_types_;
 };
 
@@ -839,7 +839,7 @@
     // The tests only use H264 Constrained Baseline. Make sure we don't return
     // an internal H264 codec from the engine with a different H264 profile.
     if (absl::EqualsIgnoreCase(name.c_str(), kH264CodecName)) {
-      const absl::optional<webrtc::H264ProfileLevelId> profile_level_id =
+      const std::optional<webrtc::H264ProfileLevelId> profile_level_id =
           webrtc::ParseSdpForH264ProfileLevelId(engine_codec.params);
       if (profile_level_id->profile !=
           webrtc::H264Profile::kProfileConstrainedBaseline) {
@@ -2509,7 +2509,7 @@
   parameters.codecs.push_back(GetEngineCodec("VP8"));
   EXPECT_TRUE(send_channel_->SetSenderParameters(parameters));
 
-  absl::optional<Codec> codec = send_channel_->GetSendCodec();
+  std::optional<Codec> codec = send_channel_->GetSendCodec();
   ASSERT_TRUE(codec);
   EXPECT_EQ("VP9", codec->name);
 
@@ -2535,7 +2535,7 @@
   parameters.codecs.push_back(GetEngineCodec("VP8"));
   EXPECT_TRUE(send_channel_->SetSenderParameters(parameters));
 
-  absl::optional<Codec> codec = send_channel_->GetSendCodec();
+  std::optional<Codec> codec = send_channel_->GetSendCodec();
   ASSERT_TRUE(codec);
   EXPECT_EQ("VP9", codec->name);
 
@@ -2561,7 +2561,7 @@
   parameters.codecs.push_back(vp9);
   EXPECT_TRUE(send_channel_->SetSenderParameters(parameters));
 
-  absl::optional<Codec> codec = send_channel_->GetSendCodec();
+  std::optional<Codec> codec = send_channel_->GetSendCodec();
   ASSERT_TRUE(codec);
   EXPECT_EQ("VP8", codec->name);
 
@@ -3662,7 +3662,7 @@
   EXPECT_THAT(
       rtp_parameters.encodings,
       ElementsAre(Field(&webrtc::RtpEncodingParameters::scalability_mode,
-                        absl::nullopt)));
+                        std::nullopt)));
   rtp_parameters.encodings[0].scalability_mode = "L2T3";
   EXPECT_TRUE(
       send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
@@ -3803,7 +3803,7 @@
   EXPECT_THAT(
       rtp_parameters.encodings,
       ElementsAre(Field(&webrtc::RtpEncodingParameters::scalability_mode,
-                        absl::nullopt)));
+                        std::nullopt)));
   rtp_parameters.encodings[0].scalability_mode = "L2T1";
   EXPECT_TRUE(
       send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
@@ -4339,7 +4339,7 @@
   AssignDefaultAptRtxTypes();
   ASSERT_TRUE(send_channel_->SetSenderParameters(send_parameters_));
 
-  absl::optional<Codec> codec = send_channel_->GetSendCodec();
+  std::optional<Codec> codec = send_channel_->GetSendCodec();
   ASSERT_TRUE(codec);
   EXPECT_TRUE(codec->Matches(engine_.send_codecs()[0]));
 
@@ -4909,7 +4909,7 @@
   // forced codec anymore.
   webrtc::RtpParameters new_params =
       send_channel_->GetRtpSendParameters(last_ssrc_);
-  EXPECT_EQ(new_params.encodings[0].codec, absl::nullopt);
+  EXPECT_EQ(new_params.encodings[0].codec, std::nullopt);
 }
 
 // Test that when both the codec-specific bitrate params and max_bandwidth_bps
@@ -5130,7 +5130,7 @@
   EXPECT_EQ(atoi(kMaxQuantization),
             AddSendStream()->GetVideoStreams().back().max_qp);
 
-  absl::optional<Codec> codec = send_channel_->GetSendCodec();
+  std::optional<Codec> codec = send_channel_->GetSendCodec();
   ASSERT_TRUE(codec);
   EXPECT_EQ(kMaxQuantization, codec->params[kCodecParamMaxQuantization]);
 }
@@ -5954,14 +5954,14 @@
             stats.total_encoded_bytes_target);
   // Comes from substream only.
   EXPECT_EQ(sender.total_packet_send_delay, webrtc::TimeDelta::Zero());
-  EXPECT_EQ(sender.qp_sum, absl::nullopt);
+  EXPECT_EQ(sender.qp_sum, std::nullopt);
 
   EXPECT_EQ(sender.has_entered_low_resolution,
             stats.has_entered_low_resolution);
   EXPECT_EQ(sender.content_type, webrtc::VideoContentType::SCREENSHARE);
   EXPECT_EQ(sender.frames_sent, stats.frames_encoded);
   EXPECT_EQ(sender.huge_frames_sent, stats.huge_frames_sent);
-  EXPECT_EQ(sender.rid, absl::nullopt);
+  EXPECT_EQ(sender.rid, std::nullopt);
 }
 
 TEST_F(WebRtcVideoChannelTest, GetAggregatedStatsReportForSubStreams) {
@@ -6085,7 +6085,7 @@
   EXPECT_EQ(sender.content_type, webrtc::VideoContentType::SCREENSHARE);
   EXPECT_EQ(sender.frames_sent, 2u * substream.frames_encoded);
   EXPECT_EQ(sender.huge_frames_sent, stats.huge_frames_sent);
-  EXPECT_EQ(sender.rid, absl::nullopt);
+  EXPECT_EQ(sender.rid, std::nullopt);
 }
 
 TEST_F(WebRtcVideoChannelTest, GetPerLayerStatsReportForSubStreams) {
@@ -6210,7 +6210,7 @@
   EXPECT_EQ(sender.frames_sent,
             static_cast<uint32_t>(substream.frames_encoded));
   EXPECT_EQ(sender.huge_frames_sent, substream.huge_frames_sent);
-  EXPECT_EQ(sender.rid, absl::nullopt);
+  EXPECT_EQ(sender.rid, std::nullopt);
 }
 
 TEST_F(WebRtcVideoChannelTest,
@@ -6417,7 +6417,7 @@
   substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.padding_bytes = 6;
   substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.payload_bytes = 7;
   substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.packets = 8;
-  substreams[kFirstMediaStreamSsrc].referenced_media_ssrc = absl::nullopt;
+  substreams[kFirstMediaStreamSsrc].referenced_media_ssrc = std::nullopt;
   substreams[kFirstMediaStreamSsrc].width = 1280;
   substreams[kFirstMediaStreamSsrc].height = 720;
   // Second kMedia stream.
@@ -6431,7 +6431,7 @@
   substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.padding_bytes = 15;
   substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.payload_bytes = 16;
   substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.packets = 17;
-  substreams[kSecondMediaStreamSsrc].referenced_media_ssrc = absl::nullopt;
+  substreams[kSecondMediaStreamSsrc].referenced_media_ssrc = std::nullopt;
   substreams[kSecondMediaStreamSsrc].width = 640;
   substreams[kSecondMediaStreamSsrc].height = 480;
   // kRtx stream referencing the first kMedia stream.
@@ -6514,7 +6514,7 @@
   stats.substreams[101].rtp_stats.retransmitted.padding_bytes = 0;
   stats.substreams[101].rtp_stats.retransmitted.payload_bytes = 0;
   stats.substreams[101].rtp_stats.retransmitted.packets = 0;
-  stats.substreams[101].referenced_media_ssrc = absl::nullopt;
+  stats.substreams[101].referenced_media_ssrc = std::nullopt;
   // Simulcast layer 1, RTX stream. header+padding=5, payload=10, packets=1.
   stats.substreams[102].type =
       webrtc::VideoSendStream::StreamStats::StreamType::kRtx;
@@ -6536,7 +6536,7 @@
   stats.substreams[201].rtp_stats.retransmitted.padding_bytes = 0;
   stats.substreams[201].rtp_stats.retransmitted.payload_bytes = 0;
   stats.substreams[201].rtp_stats.retransmitted.packets = 0;
-  stats.substreams[201].referenced_media_ssrc = absl::nullopt;
+  stats.substreams[201].referenced_media_ssrc = std::nullopt;
   // Simulcast layer 2, RTX stream. header+padding=10, payload=20, packets=4.
   stats.substreams[202].type =
       webrtc::VideoSendStream::StreamStats::StreamType::kRtx;
@@ -7373,7 +7373,7 @@
 
 // Test BaseMinimumPlayoutDelayMs on unsignaled receive streams.
 TEST_F(WebRtcVideoChannelTest, BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
-  absl::optional<int> delay_ms;
+  std::optional<int> delay_ms;
   const FakeVideoReceiveStream* recv_stream;
 
   // Set default stream with SSRC 0
@@ -7931,7 +7931,7 @@
   // Check that the vector of VideoStreams also was propagated correctly. Note
   // that this is testing the behavior of the FakeVideoSendStream, which mimics
   // the calls to CreateEncoderStreams to get the VideoStreams.
-  EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
+  EXPECT_EQ(std::optional<double>(new_bitrate_priority),
             video_send_stream->GetVideoStreams()[0].bitrate_priority);
 }
 
@@ -7990,13 +7990,13 @@
   // FakeVideoSendStream calls CreateEncoderStreams, and we are testing that
   // these are created appropriately for the simulcast case.
   EXPECT_EQ(kNumSimulcastStreams, video_send_stream->GetVideoStreams().size());
-  EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
+  EXPECT_EQ(std::optional<double>(new_bitrate_priority),
             video_send_stream->GetVideoStreams()[0].bitrate_priority);
   // Since we are only setting bitrate priority per-sender, the other
   // VideoStreams should have a bitrate priority of 0.
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             video_send_stream->GetVideoStreams()[1].bitrate_priority);
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             video_send_stream->GetVideoStreams()[2].bitrate_priority);
   EXPECT_TRUE(send_channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
 }
@@ -8332,14 +8332,14 @@
   webrtc::RtpParameters parameters =
       send_channel_->GetRtpSendParameters(last_ssrc_);
   EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
-  parameters.encodings[0].scalability_mode = absl::nullopt;
+  parameters.encodings[0].scalability_mode = std::nullopt;
   parameters.encodings[1].scalability_mode = "L1T3";  // Supported.
   parameters.encodings[2].scalability_mode = "L3T3";  // Unsupported.
   EXPECT_TRUE(send_channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
 
   // Verify that the new value is propagated down to the encoder.
   // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
-  const absl::optional<ScalabilityMode> kDefaultScalabilityMode =
+  const std::optional<ScalabilityMode> kDefaultScalabilityMode =
       webrtc::ScalabilityModeFromString(kDefaultScalabilityModeStr);
   EXPECT_EQ(2, stream->num_encoder_reconfigurations());
   webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
@@ -8413,7 +8413,7 @@
 
   // Verify that the new value is propagated down to the encoder.
   // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
-  const absl::optional<ScalabilityMode> kDefaultScalabilityMode =
+  const std::optional<ScalabilityMode> kDefaultScalabilityMode =
       webrtc::ScalabilityModeFromString(kDefaultScalabilityModeStr);
   EXPECT_EQ(2, stream->num_encoder_reconfigurations());
   webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
@@ -9589,7 +9589,7 @@
   EXPECT_TRUE(send_channel_->SetSenderParameters(parameters));
   send_channel_->SetSend(true);
 
-  absl::optional<Codec> codec = send_channel_->GetSendCodec();
+  std::optional<Codec> codec = send_channel_->GetSendCodec();
   ASSERT_TRUE(codec);
   EXPECT_EQ("VP8", codec->name);
 
diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc
index 95a8f36..542ba57 100644
--- a/media/engine/webrtc_voice_engine.cc
+++ b/media/engine/webrtc_voice_engine.cc
@@ -17,6 +17,7 @@
 #include <initializer_list>
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <utility>
@@ -26,7 +27,6 @@
 #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/audio_processing.h"
@@ -145,14 +145,14 @@
   return absl::EqualsIgnoreCase(codec.name, ref_name);
 }
 
-absl::optional<Codec> FindCodec(const std::vector<Codec>& codecs,
-                                const Codec& codec) {
+std::optional<Codec> FindCodec(const std::vector<Codec>& codecs,
+                               const Codec& codec) {
   for (const Codec& c : codecs) {
     if (c.Matches(codec)) {
       return c;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool VerifyUniquePayloadTypes(const std::vector<Codec>& codecs) {
@@ -166,7 +166,7 @@
   return absl::c_adjacent_find(payload_types) == payload_types.end();
 }
 
-absl::optional<std::string> GetAudioNetworkAdaptorConfig(
+std::optional<std::string> GetAudioNetworkAdaptorConfig(
     const AudioOptions& options) {
   if (options.audio_network_adaptor && *options.audio_network_adaptor &&
       options.audio_network_adaptor_config) {
@@ -174,7 +174,7 @@
     // equals true and `options_.audio_network_adaptor_config` has a value.
     return options.audio_network_adaptor_config;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // Returns its smallest positive argument. If neither argument is positive,
@@ -191,9 +191,9 @@
 
 // `max_send_bitrate_bps` is the bitrate from "b=" in SDP.
 // `rtp_max_bitrate_bps` is the bitrate from RtpSender::SetParameters.
-absl::optional<int> ComputeSendBitrate(int max_send_bitrate_bps,
-                                       absl::optional<int> rtp_max_bitrate_bps,
-                                       const webrtc::AudioCodecSpec& spec) {
+std::optional<int> ComputeSendBitrate(int max_send_bitrate_bps,
+                                      std::optional<int> rtp_max_bitrate_bps,
+                                      const webrtc::AudioCodecSpec& spec) {
   // If application-configured bitrate is set, take minimum of that and SDP
   // bitrate.
   const int bps = rtp_max_bitrate_bps
@@ -212,7 +212,7 @@
                       << " bps"
                          ", requires at least "
                       << spec.info.min_bitrate_bps << " bps.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (spec.info.HasFixedBitrate()) {
@@ -235,7 +235,7 @@
   webrtc::DataRate min_encoder_bitrate = webrtc::DataRate::KilobitsPerSec(16);
   bool use_slow_adaptation = true;
 
-  absl::optional<std::string> audio_network_adaptor_config;
+  std::optional<std::string> audio_network_adaptor_config;
 
   std::unique_ptr<webrtc::StructParametersParser> Parser() {
     return webrtc::StructParametersParser::Create(    //
@@ -272,7 +272,7 @@
     webrtc::Transport* rtcp_send_transport,
     const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory,
     const std::map<int, webrtc::SdpAudioFormat>& decoder_map,
-    absl::optional<webrtc::AudioCodecPairId> codec_pair_id,
+    std::optional<webrtc::AudioCodecPairId> codec_pair_id,
     size_t jitter_buffer_max_packets,
     bool jitter_buffer_fast_accelerate,
     int jitter_buffer_min_delay_ms,
@@ -686,7 +686,7 @@
   }
 }
 
-absl::optional<webrtc::AudioDeviceModule::Stats>
+std::optional<webrtc::AudioDeviceModule::Stats>
 WebRtcVoiceEngine::GetAudioDeviceStats() {
   return adm()->GetStats();
 }
@@ -722,7 +722,7 @@
 
   auto map_format = [&mapper](const webrtc::SdpAudioFormat& format,
                               std::vector<Codec>* out) {
-    absl::optional<Codec> opt_codec = mapper.ToAudioCodec(format);
+    std::optional<Codec> opt_codec = mapper.ToAudioCodec(format);
     if (opt_codec) {
       if (out) {
         out->push_back(*opt_codec);
@@ -737,7 +737,7 @@
 
   for (const auto& spec : specs) {
     // We need to do some extra stuff before adding the main codecs to out.
-    absl::optional<Codec> opt_codec = map_format(spec.format, nullptr);
+    std::optional<Codec> opt_codec = map_format(spec.format, nullptr);
     if (opt_codec) {
       Codec& codec = *opt_codec;
       if (spec.info.supports_network_adaption) {
@@ -796,17 +796,17 @@
       const std::string& mid,
       const std::string& c_name,
       const std::string track_id,
-      const absl::optional<webrtc::AudioSendStream::Config::SendCodecSpec>&
+      const std::optional<webrtc::AudioSendStream::Config::SendCodecSpec>&
           send_codec_spec,
       bool extmap_allow_mixed,
       const std::vector<webrtc::RtpExtension>& extensions,
       int max_send_bitrate_bps,
       int rtcp_report_interval_ms,
-      const absl::optional<std::string>& audio_network_adaptor_config,
+      const std::optional<std::string>& audio_network_adaptor_config,
       webrtc::Call* call,
       webrtc::Transport* send_transport,
       const rtc::scoped_refptr<webrtc::AudioEncoderFactory>& encoder_factory,
-      const absl::optional<webrtc::AudioCodecPairId> codec_pair_id,
+      const std::optional<webrtc::AudioCodecPairId> codec_pair_id,
       rtc::scoped_refptr<webrtc::FrameEncryptorInterface> frame_encryptor,
       const webrtc::CryptoOptions& crypto_options)
       : adaptive_ptime_config_(call->trials()),
@@ -899,7 +899,7 @@
   }
 
   void SetAudioNetworkAdaptorConfig(
-      const absl::optional<std::string>& audio_network_adaptor_config) {
+      const std::optional<std::string>& audio_network_adaptor_config) {
     RTC_DCHECK_RUN_ON(&worker_thread_checker_);
     if (audio_network_adaptor_config_from_options_ ==
         audio_network_adaptor_config) {
@@ -1000,7 +1000,7 @@
               int sample_rate,
               size_t number_of_channels,
               size_t number_of_frames,
-              absl::optional<int64_t> absolute_capture_timestamp_ms) override {
+              std::optional<int64_t> absolute_capture_timestamp_ms) override {
     TRACE_EVENT_BEGIN2("webrtc", "WebRtcAudioSendStream::OnData", "sample_rate",
                        sample_rate, "number_of_frames", number_of_frames);
     RTC_DCHECK_EQ(16, bits_per_sample);
@@ -1044,7 +1044,7 @@
       return webrtc::InvokeSetParametersCallback(callback, error);
     }
 
-    absl::optional<int> send_rate;
+    std::optional<int> send_rate;
     if (audio_codec_spec_) {
       send_rate = ComputeSendBitrate(max_send_bitrate_bps_,
                                      parameters.encodings[0].max_bitrate_bps,
@@ -1055,7 +1055,7 @@
       }
     }
 
-    const absl::optional<int> old_rtp_max_bitrate =
+    const std::optional<int> old_rtp_max_bitrate =
         rtp_parameters_.encodings[0].max_bitrate_bps;
     double old_priority = rtp_parameters_.encodings[0].bitrate_priority;
     webrtc::Priority old_dscp = rtp_parameters_.encodings[0].network_priority;
@@ -1207,10 +1207,10 @@
   bool muted_ = false;
   int max_send_bitrate_bps_;
   webrtc::RtpParameters rtp_parameters_;
-  absl::optional<webrtc::AudioCodecSpec> audio_codec_spec_;
+  std::optional<webrtc::AudioCodecSpec> audio_codec_spec_;
   // TODO(webrtc:11717): Remove this once audio_network_adaptor in AudioOptions
   // has been removed.
-  absl::optional<std::string> audio_network_adaptor_config_from_options_;
+  std::optional<std::string> audio_network_adaptor_config_from_options_;
   std::atomic<int> num_encoded_channels_{-1};
 };
 
@@ -1254,7 +1254,7 @@
   options_.SetAll(options);
   engine()->ApplyOptions(options_);
 
-  absl::optional<std::string> audio_network_adaptor_config =
+  std::optional<std::string> audio_network_adaptor_config =
       GetAudioNetworkAdaptorConfig(options_);
   for (auto& it : send_streams_) {
     it.second->SetAudioNetworkAdaptorConfig(audio_network_adaptor_config);
@@ -1275,7 +1275,7 @@
   // all the information at once.
 
   // Finding if the RtpParameters force a specific codec
-  absl::optional<Codec> force_codec;
+  std::optional<Codec> force_codec;
   if (send_streams_.size() == 1) {
     // Since audio simulcast is not supported, currently, only PlanB
     // has multiple tracks and we don't care about getting the
@@ -1343,11 +1343,11 @@
   return SetOptions(params.options);
 }
 
-absl::optional<Codec> WebRtcVoiceSendChannel::GetSendCodec() const {
+std::optional<Codec> WebRtcVoiceSendChannel::GetSendCodec() const {
   if (send_codec_spec_) {
     return CreateAudioCodec(send_codec_spec_->format);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // Utility function called from SetSenderParameters() to extract current send
@@ -1355,9 +1355,9 @@
 // and receive streams may be reconfigured based on the new settings.
 bool WebRtcVoiceSendChannel::SetSendCodecs(
     const std::vector<Codec>& codecs,
-    absl::optional<Codec> preferred_codec) {
+    std::optional<Codec> preferred_codec) {
   RTC_DCHECK_RUN_ON(worker_thread_);
-  dtmf_payload_type_ = absl::nullopt;
+  dtmf_payload_type_ = std::nullopt;
   dtmf_payload_freq_ = -1;
 
   // Validate supplied codecs list.
@@ -1387,10 +1387,9 @@
   }
 
   // Scan through the list to figure out the codec to use for sending.
-  absl::optional<webrtc::AudioSendStream::Config::SendCodecSpec>
-      send_codec_spec;
+  std::optional<webrtc::AudioSendStream::Config::SendCodecSpec> send_codec_spec;
   webrtc::BitrateConstraints bitrate_config;
-  absl::optional<webrtc::AudioCodecInfo> voice_codec_info;
+  std::optional<webrtc::AudioCodecInfo> voice_codec_info;
   size_t send_codec_position = 0;
   for (const Codec& voice_codec : codecs) {
     if (!(IsCodec(voice_codec, kCnCodecName) ||
@@ -1554,7 +1553,7 @@
     return false;
   }
 
-  absl::optional<std::string> audio_network_adaptor_config =
+  std::optional<std::string> audio_network_adaptor_config =
       GetAudioNetworkAdaptorConfig(options_);
   WebRtcAudioSendStream* stream = new WebRtcAudioSendStream(
       ssrc, mid_, sp.cname, sp.id, send_codec_spec_, ExtmapAllowMixed(),
@@ -1878,7 +1877,7 @@
     }
     SetPreferredDscp(new_dscp);
 
-    absl::optional<cricket::Codec> send_codec = GetSendCodec();
+    std::optional<cricket::Codec> send_codec = GetSendCodec();
     // Since we validate that all layers have the same value, we can just check
     // the first layer.
     // TODO(orphis): Support mixed-codec simulcast
@@ -2168,7 +2167,7 @@
   for (const Codec& 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.
-    absl::optional<Codec> old_codec = FindCodec(recv_codecs_, codec);
+    std::optional<Codec> old_codec = FindCodec(recv_codecs_, codec);
     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 "
@@ -2357,9 +2356,9 @@
   }
 }
 
-absl::optional<uint32_t> WebRtcVoiceReceiveChannel::GetUnsignaledSsrc() const {
+std::optional<uint32_t> WebRtcVoiceReceiveChannel::GetUnsignaledSsrc() const {
   if (unsignaled_recv_ssrcs_.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   // In the event of multiple unsignaled ssrcs, the last in the vector will be
   // the most recent one (the one forwarded to the MediaStreamTrack).
@@ -2447,7 +2446,7 @@
   return true;
 }
 
-absl::optional<int> WebRtcVoiceReceiveChannel::GetBaseMinimumPlayoutDelayMs(
+std::optional<int> WebRtcVoiceReceiveChannel::GetBaseMinimumPlayoutDelayMs(
     uint32_t ssrc) const {
   // SSRC of 0 represents the default receive stream.
   if (ssrc == 0) {
@@ -2459,7 +2458,7 @@
   if (it != recv_streams_.end()) {
     return it->second->GetBaseMinimumPlayoutDelayMs();
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void WebRtcVoiceReceiveChannel::SetFrameDecryptor(
diff --git a/media/engine/webrtc_voice_engine.h b/media/engine/webrtc_voice_engine.h
index 13ec681..942c569 100644
--- a/media/engine/webrtc_voice_engine.h
+++ b/media/engine/webrtc_voice_engine.h
@@ -16,6 +16,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
@@ -23,7 +24,6 @@
 
 #include "absl/functional/any_invocable.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/audio/audio_frame_processor.h"
 #include "api/audio/audio_mixer.h"
@@ -130,7 +130,7 @@
   // Stops AEC dump.
   void StopAecDump() override;
 
-  absl::optional<webrtc::AudioDeviceModule::Stats> GetAudioDeviceStats()
+  std::optional<webrtc::AudioDeviceModule::Stats> GetAudioDeviceStats()
       override;
 
  private:
@@ -202,7 +202,7 @@
   }
   VoiceMediaSendChannelInterface* AsVoiceSendChannel() override { return this; }
 
-  absl::optional<Codec> GetSendCodec() const override;
+  std::optional<Codec> GetSendCodec() const override;
 
   // Functions imported from MediaChannelUtil
   void SetInterface(MediaChannelNetworkInterface* iface) override {
@@ -285,7 +285,7 @@
  private:
   bool SetOptions(const AudioOptions& options);
   bool SetSendCodecs(const std::vector<Codec>& codecs,
-                     absl::optional<Codec> preferred_codec);
+                     std::optional<Codec> preferred_codec);
   bool SetLocalSource(uint32_t ssrc, AudioSource* source);
   bool MuteStream(uint32_t ssrc, bool mute);
 
@@ -303,7 +303,7 @@
 
   int max_send_bitrate_bps_ = 0;
   AudioOptions options_;
-  absl::optional<int> dtmf_payload_type_;
+  std::optional<int> dtmf_payload_type_;
   int dtmf_payload_freq_ = -1;
   bool enable_non_sender_rtt_ = false;
   bool send_ = false;
@@ -318,7 +318,7 @@
   std::string mid_;
   webrtc::RtcpMode rtcp_mode_;
 
-  absl::optional<webrtc::AudioSendStream::Config::SendCodecSpec>
+  std::optional<webrtc::AudioSendStream::Config::SendCodecSpec>
       send_codec_spec_;
 
   // TODO(kwiberg): Per-SSRC codec pair IDs?
@@ -381,7 +381,7 @@
   bool AddRecvStream(const StreamParams& sp) override;
   bool RemoveRecvStream(uint32_t ssrc) override;
   void ResetUnsignaledRecvStream() override;
-  absl::optional<uint32_t> GetUnsignaledSsrc() const override;
+  std::optional<uint32_t> GetUnsignaledSsrc() const override;
 
   void ChooseReceiverReportSsrc(const std::set<uint32_t>& choices) override;
 
@@ -401,8 +401,7 @@
   bool SetDefaultOutputVolume(double volume) override;
 
   bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) override;
-  absl::optional<int> GetBaseMinimumPlayoutDelayMs(
-      uint32_t ssrc) const override;
+  std::optional<int> GetBaseMinimumPlayoutDelayMs(uint32_t ssrc) const override;
 
   void OnPacketReceived(const webrtc::RtpPacketReceived& packet) override;
   bool GetStats(VoiceMediaReceiveInfo* info,
@@ -496,7 +495,7 @@
   std::vector<webrtc::RtpExtension> recv_rtp_extensions_;
   webrtc::RtpHeaderExtensionMap recv_rtp_extension_map_;
 
-  absl::optional<webrtc::AudioSendStream::Config::SendCodecSpec>
+  std::optional<webrtc::AudioSendStream::Config::SendCodecSpec>
       send_codec_spec_;
 
   // TODO(kwiberg): Per-SSRC codec pair IDs?
diff --git a/media/engine/webrtc_voice_engine_unittest.cc b/media/engine/webrtc_voice_engine_unittest.cc
index 2189a67..e15690d 100644
--- a/media/engine/webrtc_voice_engine_unittest.cc
+++ b/media/engine/webrtc_voice_engine_unittest.cc
@@ -11,11 +11,11 @@
 #include "media/engine/webrtc_voice_engine.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "absl/memory/memory.h"
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
 #include "api/environment/environment.h"
@@ -468,7 +468,7 @@
     EXPECT_EQ(expected_bitrate, spec->target_bitrate_bps);
   }
 
-  absl::optional<int> GetCodecBitrate(int32_t ssrc) {
+  std::optional<int> GetCodecBitrate(int32_t ssrc) {
     return GetSendStreamConfig(ssrc).send_codec_spec->target_bitrate_bps;
   }
 
@@ -476,8 +476,7 @@
     return GetSendStreamConfig(ssrc).max_bitrate_bps;
   }
 
-  const absl::optional<std::string>& GetAudioNetworkAdaptorConfig(
-      int32_t ssrc) {
+  const std::optional<std::string>& GetAudioNetworkAdaptorConfig(int32_t ssrc) {
     return GetSendStreamConfig(ssrc).audio_network_adaptor_config;
   }
 
@@ -1230,7 +1229,7 @@
   // Now change it back to active and verify we resume sending.
   // This should occur even when other parameters are updated.
   parameters.encodings[0].active = true;
-  parameters.encodings[0].max_bitrate_bps = absl::optional<int>(6000);
+  parameters.encodings[0].max_bitrate_bps = std::optional<int>(6000);
   EXPECT_TRUE(send_channel_->SetRtpSendParameters(kSsrcX, parameters).ok());
   EXPECT_TRUE(GetSendStream(kSsrcX).IsSending());
 }
@@ -1408,7 +1407,7 @@
   // forced codec anymore.
   webrtc::RtpParameters new_params =
       send_channel_->GetRtpSendParameters(kSsrcX);
-  EXPECT_EQ(new_params.encodings[0].codec, absl::nullopt);
+  EXPECT_EQ(new_params.encodings[0].codec, std::nullopt);
 }
 
 // Test that max_bitrate_bps in send stream config gets updated correctly when
@@ -1590,7 +1589,7 @@
   EXPECT_EQ(22000, send_codec_spec.target_bitrate_bps);
   EXPECT_STRCASEEQ("OPUS", send_codec_spec.format.name.c_str());
   EXPECT_NE(send_codec_spec.format.clockrate_hz, 8000);
-  EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
+  EXPECT_EQ(std::nullopt, send_codec_spec.cng_payload_type);
   EXPECT_FALSE(send_channel_->CanInsertDtmf());
 }
 
@@ -1620,7 +1619,7 @@
   const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
   EXPECT_EQ(111, send_codec_spec.payload_type);
   EXPECT_STRCASEEQ("opus", send_codec_spec.format.name.c_str());
-  EXPECT_EQ(absl::nullopt, send_codec_spec.red_payload_type);
+  EXPECT_EQ(std::nullopt, send_codec_spec.red_payload_type);
 }
 
 // Test that we do not use Opus/Red by default.
@@ -1634,7 +1633,7 @@
   const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
   EXPECT_EQ(111, send_codec_spec.payload_type);
   EXPECT_STRCASEEQ("opus", send_codec_spec.format.name.c_str());
-  EXPECT_EQ(absl::nullopt, send_codec_spec.red_payload_type);
+  EXPECT_EQ(std::nullopt, send_codec_spec.red_payload_type);
 }
 
 // Test that the RED fmtp line must match the payload type.
@@ -1648,7 +1647,7 @@
   const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
   EXPECT_EQ(111, send_codec_spec.payload_type);
   EXPECT_STRCASEEQ("opus", send_codec_spec.format.name.c_str());
-  EXPECT_EQ(absl::nullopt, send_codec_spec.red_payload_type);
+  EXPECT_EQ(std::nullopt, send_codec_spec.red_payload_type);
 }
 
 // Test that the RED fmtp line must show 2..32 payloads.
@@ -1662,7 +1661,7 @@
   const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
   EXPECT_EQ(111, send_codec_spec.payload_type);
   EXPECT_STRCASEEQ("opus", send_codec_spec.format.name.c_str());
-  EXPECT_EQ(absl::nullopt, send_codec_spec.red_payload_type);
+  EXPECT_EQ(std::nullopt, send_codec_spec.red_payload_type);
   for (int i = 1; i < 32; i++) {
     parameters.codecs[0].params[""] += "/111";
     SetSenderParameters(parameters);
@@ -1676,7 +1675,7 @@
   const auto& send_codec_spec3 = *GetSendStreamConfig(kSsrcX).send_codec_spec;
   EXPECT_EQ(111, send_codec_spec3.payload_type);
   EXPECT_STRCASEEQ("opus", send_codec_spec3.format.name.c_str());
-  EXPECT_EQ(absl::nullopt, send_codec_spec3.red_payload_type);
+  EXPECT_EQ(std::nullopt, send_codec_spec3.red_payload_type);
 }
 
 // Test that WebRtcVoiceEngine reconfigures, rather than recreates its
@@ -1709,7 +1708,7 @@
   parameters.codecs[0].bitrate = 0;
   parameters.codecs[0].clockrate = 50000;
   EXPECT_TRUE(send_channel_->SetSenderParameters(parameters));
-  EXPECT_EQ(send_channel_->GetSendCodec(), absl::nullopt);
+  EXPECT_EQ(send_channel_->GetSendCodec(), std::nullopt);
 }
 
 // Test that if channels=0 for opus, we do not have a send codec.
@@ -1720,7 +1719,7 @@
   parameters.codecs[0].bitrate = 0;
   parameters.codecs[0].channels = 0;
   EXPECT_TRUE(send_channel_->SetSenderParameters(parameters));
-  EXPECT_EQ(send_channel_->GetSendCodec(), absl::nullopt);
+  EXPECT_EQ(send_channel_->GetSendCodec(), std::nullopt);
 }
 
 // Test that if channels=0 for opus, we do not have a send codec.
@@ -1732,7 +1731,7 @@
   parameters.codecs[0].channels = 0;
   parameters.codecs[0].params["stereo"] = "1";
   EXPECT_TRUE(send_channel_->SetSenderParameters(parameters));
-  EXPECT_EQ(send_channel_->GetSendCodec(), absl::nullopt);
+  EXPECT_EQ(send_channel_->GetSendCodec(), std::nullopt);
 }
 
 // Test that if channel is 1 for opus and there's no stereo, we do not have a
@@ -1744,7 +1743,7 @@
   parameters.codecs[0].bitrate = 0;
   parameters.codecs[0].channels = 1;
   EXPECT_TRUE(send_channel_->SetSenderParameters(parameters));
-  EXPECT_EQ(send_channel_->GetSendCodec(), absl::nullopt);
+  EXPECT_EQ(send_channel_->GetSendCodec(), std::nullopt);
 }
 
 // Test that if channel is 1 for opus and stereo=0, we do not have a send codec.
@@ -1756,7 +1755,7 @@
   parameters.codecs[0].channels = 1;
   parameters.codecs[0].params["stereo"] = "0";
   EXPECT_TRUE(send_channel_->SetSenderParameters(parameters));
-  EXPECT_EQ(send_channel_->GetSendCodec(), absl::nullopt);
+  EXPECT_EQ(send_channel_->GetSendCodec(), std::nullopt);
 }
 
 // Test that if channel is 1 for opus and stereo=1, we do not have a send codec.
@@ -1768,7 +1767,7 @@
   parameters.codecs[0].channels = 1;
   parameters.codecs[0].params["stereo"] = "1";
   EXPECT_TRUE(send_channel_->SetSenderParameters(parameters));
-  EXPECT_EQ(send_channel_->GetSendCodec(), absl::nullopt);
+  EXPECT_EQ(send_channel_->GetSendCodec(), std::nullopt);
 }
 
 // Test that with bitrate=0 and no stereo, bitrate is 32000.
@@ -2046,7 +2045,7 @@
   EXPECT_TRUE(SetupSendStream());
   cricket::AudioSenderParameter parameters;
   EXPECT_TRUE(send_channel_->SetSenderParameters(parameters));
-  EXPECT_EQ(send_channel_->GetSendCodec(), absl::nullopt);
+  EXPECT_EQ(send_channel_->GetSendCodec(), std::nullopt);
 }
 
 // Test that we can set send codecs even with telephone-event codec as the first
@@ -2178,7 +2177,7 @@
   {
     const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
     EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
-    EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
+    EXPECT_EQ(std::nullopt, send_codec_spec.cng_payload_type);
   }
   // Set PCMU(8K) and CN(8K). VAD should be activated.
   parameters.codecs[1] = kCn8000Codec;
@@ -2195,7 +2194,7 @@
   {
     const auto& send_codec_spec = *GetSendStreamConfig(kSsrcX).send_codec_spec;
     EXPECT_STRCASEEQ("OPUS", send_codec_spec.format.name.c_str());
-    EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
+    EXPECT_EQ(std::nullopt, send_codec_spec.cng_payload_type);
   }
 }
 
@@ -2366,7 +2365,7 @@
     const auto& send_codec_spec =
         *call_.GetAudioSendStream(ssrc)->GetConfig().send_codec_spec;
     EXPECT_STRCASEEQ("PCMU", send_codec_spec.format.name.c_str());
-    EXPECT_EQ(absl::nullopt, send_codec_spec.cng_payload_type);
+    EXPECT_EQ(std::nullopt, send_codec_spec.cng_payload_type);
   }
 }
 
@@ -2532,7 +2531,7 @@
   cricket::AudioOptions options;
   options.audio_network_adaptor = false;
   SetAudioSend(kSsrcX, true, nullptr, &options);
-  EXPECT_EQ(absl::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
+  EXPECT_EQ(std::nullopt, GetAudioNetworkAdaptorConfig(kSsrcX));
 }
 
 TEST_P(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) {
@@ -2544,7 +2543,7 @@
             GetAudioNetworkAdaptorConfig(kSsrcX));
   const int initial_num = call_.GetNumCreatedSendStreams();
   cricket::AudioOptions options;
-  options.audio_network_adaptor = absl::nullopt;
+  options.audio_network_adaptor = std::nullopt;
   // Unvalued `options.audio_network_adaptor` should not reset audio network
   // adaptor.
   SetAudioSend(kSsrcX, true, nullptr, &options);
diff --git a/media/sctp/dcsctp_transport.cc b/media/sctp/dcsctp_transport.cc
index 4623435..ae8d778 100644
--- a/media/sctp/dcsctp_transport.cc
+++ b/media/sctp/dcsctp_transport.cc
@@ -13,11 +13,11 @@
 #include <atomic>
 #include <cstdint>
 #include <limits>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/data_channel_interface.h"
 #include "api/environment/environment.h"
@@ -72,7 +72,7 @@
   }
 }
 
-absl::optional<DataMessageType> ToDataMessageType(dcsctp::PPID ppid) {
+std::optional<DataMessageType> ToDataMessageType(dcsctp::PPID ppid) {
   switch (static_cast<WebrtcPPID>(ppid.value())) {
     case WebrtcPPID::kDCEP:
       return DataMessageType::kControl;
@@ -85,10 +85,10 @@
     case WebrtcPPID::kBinaryEmpty:
       return DataMessageType::kBinary;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<cricket::SctpErrorCauseCode> ToErrorCauseCode(
+std::optional<cricket::SctpErrorCauseCode> ToErrorCauseCode(
     dcsctp::ErrorKind error) {
   switch (error) {
     case dcsctp::ErrorKind::kParseFailed:
@@ -107,7 +107,7 @@
       // No SCTP error cause code matches those
       break;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool IsEmptyPPID(dcsctp::PPID ppid) {
@@ -192,8 +192,8 @@
     options.max_message_size = max_message_size;
     options.max_timer_backoff_duration = kMaxTimerBackoffDuration;
     // Don't close the connection automatically on too many retransmissions.
-    options.max_retransmissions = absl::nullopt;
-    options.max_init_retransmits = absl::nullopt;
+    options.max_retransmissions = std::nullopt;
+    options.max_init_retransmits = std::nullopt;
     options.per_stream_send_queue_limit =
         DataChannelInterface::MaxSendQueueSize();
     // This is just set to avoid denial-of-service. Practically unlimited.
@@ -382,15 +382,15 @@
   return socket_->options().max_message_size;
 }
 
-absl::optional<int> DcSctpTransport::max_outbound_streams() const {
+std::optional<int> DcSctpTransport::max_outbound_streams() const {
   if (!socket_)
-    return absl::nullopt;
+    return std::nullopt;
   return socket_->options().announced_maximum_outgoing_streams;
 }
 
-absl::optional<int> DcSctpTransport::max_inbound_streams() const {
+std::optional<int> DcSctpTransport::max_inbound_streams() const {
   if (!socket_)
-    return absl::nullopt;
+    return std::nullopt;
   return socket_->options().announced_maximum_incoming_streams;
 }
 
diff --git a/media/sctp/dcsctp_transport.h b/media/sctp/dcsctp_transport.h
index 7f3e7df..030babe 100644
--- a/media/sctp/dcsctp_transport.h
+++ b/media/sctp/dcsctp_transport.h
@@ -12,10 +12,10 @@
 #define MEDIA_SCTP_DCSCTP_TRANSPORT_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/environment/environment.h"
 #include "api/priority.h"
@@ -65,8 +65,8 @@
                     const rtc::CopyOnWriteBuffer& payload) override;
   bool ReadyToSendData() override;
   int max_message_size() const override;
-  absl::optional<int> max_outbound_streams() const override;
-  absl::optional<int> max_inbound_streams() const override;
+  std::optional<int> max_outbound_streams() const override;
+  std::optional<int> max_inbound_streams() const override;
   size_t buffered_amount(int sid) const override;
   size_t buffered_amount_low_threshold(int sid) const override;
   void SetBufferedAmountLowThreshold(int sid, size_t bytes) override;
diff --git a/media/sctp/sctp_transport_internal.h b/media/sctp/sctp_transport_internal.h
index 7596d67..2dad0cd 100644
--- a/media/sctp/sctp_transport_internal.h
+++ b/media/sctp/sctp_transport_internal.h
@@ -137,10 +137,10 @@
   // Returns the current max message size, set with Start().
   virtual int max_message_size() const = 0;
   // Returns the current negotiated max # of outbound streams.
-  // Will return absl::nullopt if negotiation is incomplete.
-  virtual absl::optional<int> max_outbound_streams() const = 0;
+  // Will return std::nullopt if negotiation is incomplete.
+  virtual std::optional<int> max_outbound_streams() const = 0;
   // Returns the current negotiated max # of inbound streams.
-  virtual absl::optional<int> max_inbound_streams() const = 0;
+  virtual std::optional<int> max_inbound_streams() const = 0;
   // Returns the amount of buffered data in the send queue for a stream.
   virtual size_t buffered_amount(int sid) const = 0;
   virtual size_t buffered_amount_low_threshold(int sid) const = 0;
diff --git a/modules/BUILD.gn b/modules/BUILD.gn
index 540e856..21f866d 100644
--- a/modules/BUILD.gn
+++ b/modules/BUILD.gn
@@ -30,7 +30,6 @@
 
 rtc_source_set("module_api_public") {
   sources = [ "include/module_common_types_public.h" ]
-  deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
 }
 
 rtc_source_set("module_api") {
diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn
index a28152b..087043b 100644
--- a/modules/audio_coding/BUILD.gn
+++ b/modules/audio_coding/BUILD.gn
@@ -62,7 +62,6 @@
     "../../system_wrappers:metrics",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -76,7 +75,6 @@
     "../../api/audio_codecs:audio_codecs_api",
     "../../rtc_base:buffer",
     "../../rtc_base:checks",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -109,7 +107,6 @@
     "../../api/units:time_delta",
     "../../common_audio",
     "../../rtc_base:checks",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -131,7 +128,6 @@
     "../../rtc_base:checks",
     "../../rtc_base:logging",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -152,7 +148,6 @@
     "../../api/units:time_delta",
     "../../rtc_base:buffer",
     "../../rtc_base:checks",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   public_deps += [ ":g711_c" ]  # no-presubmit-check TODO(webrtc:8603)
 }
@@ -185,7 +180,6 @@
     "../../rtc_base:buffer",
     "../../rtc_base:checks",
     "../../rtc_base:safe_conversions",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   public_deps += [ ":g722_c" ]  # no-presubmit-check TODO(webrtc:8603)
 }
@@ -220,7 +214,6 @@
     "../../rtc_base:checks",
     "../../rtc_base:logging",
     "../../rtc_base:safe_conversions",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   public_deps += [ ":ilbc_c" ]  # no-presubmit-check TODO(webrtc:8603)
 }
@@ -452,7 +445,6 @@
     "../../rtc_base:checks",
     "../../rtc_base:stringutils",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -488,7 +480,6 @@
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   public_deps +=  # no-presubmit-check TODO(webrtc:8603)
       [ ":webrtc_opus_wrapper" ]
@@ -522,7 +513,6 @@
     "../../rtc_base:stringutils",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   public_deps +=  # no-presubmit-check TODO(webrtc:8603)
       [ ":webrtc_opus_wrapper" ]
@@ -574,7 +564,6 @@
     "audio_network_adaptor/audio_network_adaptor_config.cc",
     "audio_network_adaptor/include/audio_network_adaptor_config.h",
   ]
-  deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
 }
 
 rtc_library("audio_network_adaptor") {
@@ -624,7 +613,6 @@
     "../../system_wrappers:field_trial",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 
   if (rtc_enable_protobuf) {
@@ -739,7 +727,6 @@
     "../../system_wrappers:metrics",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -802,7 +789,6 @@
     "../../rtc_base:stringutils",
     "../../system_wrappers",
     "../rtp_rtcp:rtp_rtcp_format",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   defines = audio_codec_defines
 }
@@ -843,7 +829,6 @@
     "../../test:rtp_test_utils",
     "../rtp_rtcp:rtp_rtcp_format",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -876,7 +861,6 @@
     "../rtp_rtcp",
     "../rtp_rtcp:rtp_rtcp_format",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 
   if (rtc_enable_protobuf) {
@@ -961,7 +945,6 @@
     "//testing/gtest",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   defines = audio_coding_defines
 
@@ -1244,7 +1227,6 @@
         "../../rtc_base:refcount",
         "../../test:fileutils",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
       sources = [
         "neteq/tools/neteq_test_factory.cc",
@@ -1278,7 +1260,6 @@
         "//third_party/abseil-cpp/absl/flags:flag",
         "//third_party/abseil-cpp/absl/flags:parse",
         "//third_party/abseil-cpp/absl/strings",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
       sources = [ "neteq/tools/neteq_rtpplay.cc" ]
     }
@@ -1751,7 +1732,6 @@
         "//third_party/abseil-cpp/absl/flags:flag",
         "//third_party/abseil-cpp/absl/memory",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
 
       defines = audio_coding_defines
diff --git a/modules/audio_coding/acm2/acm_receiver.cc b/modules/audio_coding/acm2/acm_receiver.cc
index e203a32..0946d79 100644
--- a/modules/audio_coding/acm2/acm_receiver.cc
+++ b/modules/audio_coding/acm2/acm_receiver.cc
@@ -90,11 +90,11 @@
   return neteq_->GetBaseMinimumDelayMs();
 }
 
-absl::optional<int> AcmReceiver::last_packet_sample_rate_hz() const {
-  absl::optional<NetEq::DecoderFormat> decoder =
+std::optional<int> AcmReceiver::last_packet_sample_rate_hz() const {
+  std::optional<NetEq::DecoderFormat> decoder =
       neteq_->GetCurrentDecoderFormat();
   if (!decoder) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return decoder->sample_rate_hz;
 }
@@ -194,7 +194,7 @@
   neteq_->FlushBuffers();
 }
 
-absl::optional<uint32_t> AcmReceiver::GetPlayoutTimestamp() {
+std::optional<uint32_t> AcmReceiver::GetPlayoutTimestamp() {
   return neteq_->GetPlayoutTimestamp();
 }
 
@@ -206,12 +206,11 @@
   return neteq_->TargetDelayMs();
 }
 
-absl::optional<std::pair<int, SdpAudioFormat>> AcmReceiver::LastDecoder()
-    const {
-  absl::optional<NetEq::DecoderFormat> decoder =
+std::optional<std::pair<int, SdpAudioFormat>> AcmReceiver::LastDecoder() const {
+  std::optional<NetEq::DecoderFormat> decoder =
       neteq_->GetCurrentDecoderFormat();
   if (!decoder) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return std::make_pair(decoder->payload_type, decoder->sdp_format);
 }
diff --git a/modules/audio_coding/acm2/acm_receiver.h b/modules/audio_coding/acm2/acm_receiver.h
index 1e14248..2d0dffb 100644
--- a/modules/audio_coding/acm2/acm_receiver.h
+++ b/modules/audio_coding/acm2/acm_receiver.h
@@ -16,11 +16,11 @@
 #include <array>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/audio_frame.h"
 #include "api/audio_codecs/audio_decoder.h"
@@ -147,7 +147,7 @@
   // packet. If no packet of a registered non-CNG codec has been received, the
   // return value is empty. Also, if the decoder was unregistered since the last
   // packet was inserted, the return value is empty.
-  absl::optional<int> last_packet_sample_rate_hz() const;
+  std::optional<int> last_packet_sample_rate_hz() const;
 
   // Returns last_output_sample_rate_hz from the NetEq instance.
   int last_output_sample_rate_hz() const;
@@ -168,7 +168,7 @@
 
   // Returns the RTP timestamp for the last sample delivered by GetAudio().
   // The return value will be empty if no valid timestamp is available.
-  absl::optional<uint32_t> GetPlayoutTimestamp();
+  std::optional<uint32_t> GetPlayoutTimestamp();
 
   // Returns the current total delay from NetEq (packet buffer and sync buffer)
   // in ms, with smoothing applied to even out short-time fluctuations due to
@@ -183,9 +183,9 @@
 
   //
   // Get payload type and format of the last non-CNG/non-DTMF received payload.
-  // If no non-CNG/non-DTMF packet is received absl::nullopt is returned.
+  // If no non-CNG/non-DTMF packet is received std::nullopt is returned.
   //
-  absl::optional<std::pair<int, SdpAudioFormat>> LastDecoder() const;
+  std::optional<std::pair<int, SdpAudioFormat>> LastDecoder() const;
 
   //
   // Enable NACK and set the maximum size of the NACK list. If NACK is already
diff --git a/modules/audio_coding/acm2/acm_receiver_unittest.cc b/modules/audio_coding/acm2/acm_receiver_unittest.cc
index 07fcb05..55b5c49 100644
--- a/modules/audio_coding/acm2/acm_receiver_unittest.cc
+++ b/modules/audio_coding/acm2/acm_receiver_unittest.cc
@@ -12,8 +12,8 @@
 
 #include <algorithm>  // std::min
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
 #include "api/environment/environment.h"
@@ -67,7 +67,7 @@
                             const SdpAudioFormat& format,
                             const std::map<int, int> cng_payload_types = {}) {
     // Create the speech encoder.
-    absl::optional<AudioCodecInfo> info =
+    std::optional<AudioCodecInfo> info =
         encoder_factory_->QueryAudioEncoder(format);
     RTC_CHECK(info.has_value());
     std::unique_ptr<AudioEncoder> enc =
@@ -264,7 +264,7 @@
   }
 
   // No audio payload is received.
-  EXPECT_EQ(absl::nullopt, receiver_->LastDecoder());
+  EXPECT_EQ(std::nullopt, receiver_->LastDecoder());
 
   // Start with sending DTX.
   packet_sent_ = false;
@@ -275,8 +275,8 @@
   EXPECT_EQ(AudioFrameType::kAudioFrameCN, last_frame_type_);
 
   // Has received, only, DTX. Last Audio codec is undefined.
-  EXPECT_EQ(absl::nullopt, receiver_->LastDecoder());
-  EXPECT_EQ(absl::nullopt, receiver_->last_packet_sample_rate_hz());
+  EXPECT_EQ(std::nullopt, receiver_->LastDecoder());
+  EXPECT_EQ(std::nullopt, receiver_->last_packet_sample_rate_hz());
 
   for (size_t i = 0; i < codecs.size(); ++i) {
     // Set DTX off to send audio payload.
diff --git a/modules/audio_coding/acm2/audio_coding_module.cc b/modules/audio_coding/acm2/audio_coding_module.cc
index 3635701..e1a775d 100644
--- a/modules/audio_coding/acm2/audio_coding_module.cc
+++ b/modules/audio_coding/acm2/audio_coding_module.cc
@@ -108,7 +108,7 @@
   // TODO(bugs.webrtc.org/10739): change `absolute_capture_timestamp_ms` to
   // int64_t when it always receives a valid value.
   int Encode(const InputData& input_data,
-             absl::optional<int64_t> absolute_capture_timestamp_ms)
+             std::optional<int64_t> absolute_capture_timestamp_ms)
       RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_mutex_);
 
   bool HaveValidEncoder(absl::string_view caller_name) const
@@ -152,7 +152,7 @@
   bool first_frame_ RTC_GUARDED_BY(acm_mutex_);
   uint32_t last_timestamp_ RTC_GUARDED_BY(acm_mutex_);
   uint32_t last_rtp_timestamp_ RTC_GUARDED_BY(acm_mutex_);
-  absl::optional<int64_t> absolute_capture_timestamp_ms_
+  std::optional<int64_t> absolute_capture_timestamp_ms_
       RTC_GUARDED_BY(acm_mutex_);
 
   Mutex callback_mutex_;
@@ -198,7 +198,7 @@
 
 int32_t AudioCodingModuleImpl::Encode(
     const InputData& input_data,
-    absl::optional<int64_t> absolute_capture_timestamp_ms) {
+    std::optional<int64_t> absolute_capture_timestamp_ms) {
   // TODO(bugs.webrtc.org/10739): add dcheck that
   // `audio_frame.absolute_capture_timestamp_ms()` always has a value.
   AudioEncoder::EncodedInfo encoded_info;
@@ -280,7 +280,7 @@
           absolute_capture_timestamp_ms_.value_or(-1));
     }
   }
-  absolute_capture_timestamp_ms_ = absl::nullopt;
+  absolute_capture_timestamp_ms_ = std::nullopt;
   previous_pltype_ = encoded_info.payload_type;
   return static_cast<int32_t>(encode_buffer_.size());
 }
diff --git a/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
index b30788c..c8ef9df 100644
--- a/modules/audio_coding/acm2/audio_coding_module_unittest.cc
+++ b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
@@ -249,7 +249,7 @@
   RTPHeader rtp_header_;
   AudioFrame input_frame_;
 
-  absl::optional<SdpAudioFormat> audio_format_;
+  std::optional<SdpAudioFormat> audio_format_;
   int pac_size_ = -1;
 };
 
diff --git a/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc b/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc
index 64163f9..3cc80da 100644
--- a/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc
+++ b/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc
@@ -107,7 +107,7 @@
     controller->MakeDecision(&config);
 
   // Update ANA stats.
-  auto increment_opt = [](absl::optional<uint32_t>& a) {
+  auto increment_opt = [](std::optional<uint32_t>& a) {
     a = a.value_or(0) + 1;
   };
   if (prev_config_) {
diff --git a/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h b/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h
index 664e76b..b4ec355 100644
--- a/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h
+++ b/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h
@@ -14,8 +14,8 @@
 #include <stdio.h>
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "modules/audio_coding/audio_network_adaptor/controller.h"
 #include "modules/audio_coding/audio_network_adaptor/debug_dump_writer.h"
@@ -79,7 +79,7 @@
 
   Controller::NetworkMetrics last_metrics_;
 
-  absl::optional<AudioEncoderRuntimeConfig> prev_config_;
+  std::optional<AudioEncoderRuntimeConfig> prev_config_;
 
   ANAStats stats_;
 };
diff --git a/modules/audio_coding/audio_network_adaptor/bitrate_controller.h b/modules/audio_coding/audio_network_adaptor/bitrate_controller.h
index c103214..6e91ec2 100644
--- a/modules/audio_coding/audio_network_adaptor/bitrate_controller.h
+++ b/modules/audio_coding/audio_network_adaptor/bitrate_controller.h
@@ -13,7 +13,8 @@
 
 #include <stddef.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/audio_coding/audio_network_adaptor/controller.h"
 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
 
@@ -49,8 +50,8 @@
   const Config config_;
   int bitrate_bps_;
   int frame_length_ms_;
-  absl::optional<int> target_audio_bitrate_bps_;
-  absl::optional<size_t> overhead_bytes_per_packet_;
+  std::optional<int> target_audio_bitrate_bps_;
+  std::optional<size_t> overhead_bytes_per_packet_;
 };
 
 }  // namespace audio_network_adaptor
diff --git a/modules/audio_coding/audio_network_adaptor/bitrate_controller_unittest.cc b/modules/audio_coding/audio_network_adaptor/bitrate_controller_unittest.cc
index 9c593b8..e847f87 100644
--- a/modules/audio_coding/audio_network_adaptor/bitrate_controller_unittest.cc
+++ b/modules/audio_coding/audio_network_adaptor/bitrate_controller_unittest.cc
@@ -21,8 +21,8 @@
 
 void UpdateNetworkMetrics(
     BitrateController* controller,
-    const absl::optional<int>& target_audio_bitrate_bps,
-    const absl::optional<size_t>& overhead_bytes_per_packet) {
+    const std::optional<int>& target_audio_bitrate_bps,
+    const std::optional<size_t>& overhead_bytes_per_packet) {
   // UpdateNetworkMetrics can accept multiple network metric updates at once.
   // However, currently, the most used case is to update one metric at a time.
   // To reflect this fact, we separate the calls.
@@ -39,7 +39,7 @@
 }
 
 void CheckDecision(BitrateController* controller,
-                   const absl::optional<int>& frame_length_ms,
+                   const std::optional<int>& frame_length_ms,
                    int expected_bitrate_bps) {
   AudioEncoderRuntimeConfig config;
   config.frame_length_ms = frame_length_ms;
@@ -59,7 +59,7 @@
   constexpr size_t kOverheadBytesPerPacket = 64;
   BitrateController controller(BitrateController::Config(
       kInitialBitrateBps, kInitialFrameLengthMs, 0, 0));
-  UpdateNetworkMetrics(&controller, absl::nullopt, kOverheadBytesPerPacket);
+  UpdateNetworkMetrics(&controller, std::nullopt, kOverheadBytesPerPacket);
   CheckDecision(&controller, kInitialFrameLengthMs * 2, kInitialBitrateBps);
 }
 
@@ -69,7 +69,7 @@
   constexpr int kTargetBitrateBps = 48000;
   BitrateController controller(BitrateController::Config(
       kInitialBitrateBps, kInitialFrameLengthMs, 0, 0));
-  UpdateNetworkMetrics(&controller, kTargetBitrateBps, absl::nullopt);
+  UpdateNetworkMetrics(&controller, kTargetBitrateBps, std::nullopt);
   CheckDecision(&controller, kInitialFrameLengthMs * 2, kInitialBitrateBps);
 }
 
@@ -121,7 +121,7 @@
                                                       1000 /
                                                       kInitialFrameLengthMs;
   UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
-  CheckDecision(&controller, absl::nullopt, kBitrateBps);
+  CheckDecision(&controller, std::nullopt, kBitrateBps);
 }
 
 TEST(AnaBitrateControllerTest, IncreaseBitrateOnFrameLengthIncreased) {
@@ -135,7 +135,7 @@
                                                       1000 /
                                                       kInitialFrameLengthMs;
   UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
-  CheckDecision(&controller, absl::nullopt, kBitrateBps);
+  CheckDecision(&controller, std::nullopt, kBitrateBps);
 
   constexpr int kFrameLengthMs = 60;
   constexpr size_t kPacketOverheadRateDiff =
@@ -157,7 +157,7 @@
                                                       1000 /
                                                       kInitialFrameLengthMs;
   UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
-  CheckDecision(&controller, absl::nullopt, kBitrateBps);
+  CheckDecision(&controller, std::nullopt, kBitrateBps);
 
   constexpr int kFrameLengthMs = 20;
   constexpr size_t kPacketOverheadRateDiff =
diff --git a/modules/audio_coding/audio_network_adaptor/channel_controller.h b/modules/audio_coding/audio_network_adaptor/channel_controller.h
index 3cd4bb7..a877d77 100644
--- a/modules/audio_coding/audio_network_adaptor/channel_controller.h
+++ b/modules/audio_coding/audio_network_adaptor/channel_controller.h
@@ -13,7 +13,8 @@
 
 #include <stddef.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/audio_coding/audio_network_adaptor/controller.h"
 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
 
@@ -50,7 +51,7 @@
  private:
   const Config config_;
   size_t channels_to_encode_;
-  absl::optional<int> uplink_bandwidth_bps_;
+  std::optional<int> uplink_bandwidth_bps_;
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_coding/audio_network_adaptor/channel_controller_unittest.cc b/modules/audio_coding/audio_network_adaptor/channel_controller_unittest.cc
index 21504bc..1803d44 100644
--- a/modules/audio_coding/audio_network_adaptor/channel_controller_unittest.cc
+++ b/modules/audio_coding/audio_network_adaptor/channel_controller_unittest.cc
@@ -33,7 +33,7 @@
 }
 
 void CheckDecision(ChannelController* controller,
-                   const absl::optional<int>& uplink_bandwidth_bps,
+                   const std::optional<int>& uplink_bandwidth_bps,
                    size_t expected_num_channels) {
   if (uplink_bandwidth_bps) {
     Controller::NetworkMetrics network_metrics;
@@ -50,7 +50,7 @@
 TEST(ChannelControllerTest, OutputInitValueWhenUplinkBandwidthUnknown) {
   constexpr int kInitChannels = 2;
   auto controller = CreateChannelController(kInitChannels);
-  CheckDecision(controller.get(), absl::nullopt, kInitChannels);
+  CheckDecision(controller.get(), std::nullopt, kInitChannels);
 }
 
 TEST(ChannelControllerTest, SwitchTo2ChannelsOnHighUplinkBandwidth) {
diff --git a/modules/audio_coding/audio_network_adaptor/controller.h b/modules/audio_coding/audio_network_adaptor/controller.h
index b70ada0..fc2cba7 100644
--- a/modules/audio_coding/audio_network_adaptor/controller.h
+++ b/modules/audio_coding/audio_network_adaptor/controller.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_CONTROLLER_H_
 #define MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_CONTROLLER_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
 
 namespace webrtc {
@@ -21,11 +22,11 @@
   struct NetworkMetrics {
     NetworkMetrics();
     ~NetworkMetrics();
-    absl::optional<int> uplink_bandwidth_bps;
-    absl::optional<float> uplink_packet_loss_fraction;
-    absl::optional<int> target_audio_bitrate_bps;
-    absl::optional<int> rtt_ms;
-    absl::optional<size_t> overhead_bytes_per_packet;
+    std::optional<int> uplink_bandwidth_bps;
+    std::optional<float> uplink_packet_loss_fraction;
+    std::optional<int> target_audio_bitrate_bps;
+    std::optional<int> rtt_ms;
+    std::optional<size_t> overhead_bytes_per_packet;
   };
 
   virtual ~Controller() = default;
diff --git a/modules/audio_coding/audio_network_adaptor/controller_manager.cc b/modules/audio_coding/audio_network_adaptor/controller_manager.cc
index 793c73a..40a48a0 100644
--- a/modules/audio_coding/audio_network_adaptor/controller_manager.cc
+++ b/modules/audio_coding/audio_network_adaptor/controller_manager.cc
@@ -338,7 +338,7 @@
     const std::map<const Controller*, std::pair<int, float>>& scoring_points)
     : config_(config),
       controllers_(std::move(controllers)),
-      last_reordering_time_ms_(absl::nullopt),
+      last_reordering_time_ms_(std::nullopt),
       last_scoring_point_(0, 0.0) {
   for (auto& controller : controllers_)
     default_sorted_controllers_.push_back(controller.get());
diff --git a/modules/audio_coding/audio_network_adaptor/controller_manager.h b/modules/audio_coding/audio_network_adaptor/controller_manager.h
index 47e8e0f..e03bd05 100644
--- a/modules/audio_coding/audio_network_adaptor/controller_manager.h
+++ b/modules/audio_coding/audio_network_adaptor/controller_manager.h
@@ -107,7 +107,7 @@
 
   std::vector<std::unique_ptr<Controller>> controllers_;
 
-  absl::optional<int64_t> last_reordering_time_ms_;
+  std::optional<int64_t> last_reordering_time_ms_;
   ScoringPoint last_scoring_point_;
 
   std::vector<Controller*> default_sorted_controllers_;
diff --git a/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc b/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc
index f399511..dfc3d6f 100644
--- a/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc
+++ b/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc
@@ -86,8 +86,8 @@
 // exists in the vector.
 void CheckControllersOrder(
     ControllerManagerStates* states,
-    const absl::optional<int>& uplink_bandwidth_bps,
-    const absl::optional<float>& uplink_packet_loss_fraction,
+    const std::optional<int>& uplink_bandwidth_bps,
+    const std::optional<float>& uplink_packet_loss_fraction,
     const std::vector<int>& expected_order) {
   RTC_DCHECK_EQ(kNumControllers, expected_order.size());
   Controller::NetworkMetrics metrics;
@@ -123,7 +123,7 @@
   auto states = CreateControllerManager();
   // `network_metrics` are empty, and the controllers are supposed to follow the
   // default order.
-  CheckControllersOrder(&states, absl::nullopt, absl::nullopt, {0, 1, 2, 3});
+  CheckControllersOrder(&states, std::nullopt, std::nullopt, {0, 1, 2, 3});
 }
 
 TEST(ControllerManagerTest, ControllersWithoutCharPointAtEndAndInDefaultOrder) {
diff --git a/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc b/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc
index 5ffbee2..f5fdca7 100644
--- a/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc
+++ b/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc
@@ -10,9 +10,9 @@
 
 #include "modules/audio_coding/audio_network_adaptor/debug_dump_writer.h"
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_conversions.h"
 #include "rtc_base/system/file_wrapper.h"
diff --git a/modules/audio_coding/audio_network_adaptor/dtx_controller.h b/modules/audio_coding/audio_network_adaptor/dtx_controller.h
index b8a8e47..f43fd02 100644
--- a/modules/audio_coding/audio_network_adaptor/dtx_controller.h
+++ b/modules/audio_coding/audio_network_adaptor/dtx_controller.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_DTX_CONTROLLER_H_
 #define MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_DTX_CONTROLLER_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/audio_coding/audio_network_adaptor/controller.h"
 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
 
@@ -44,7 +45,7 @@
  private:
   const Config config_;
   bool dtx_enabled_;
-  absl::optional<int> uplink_bandwidth_bps_;
+  std::optional<int> uplink_bandwidth_bps_;
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_coding/audio_network_adaptor/dtx_controller_unittest.cc b/modules/audio_coding/audio_network_adaptor/dtx_controller_unittest.cc
index 567df6f..46c8f8b 100644
--- a/modules/audio_coding/audio_network_adaptor/dtx_controller_unittest.cc
+++ b/modules/audio_coding/audio_network_adaptor/dtx_controller_unittest.cc
@@ -31,7 +31,7 @@
 }
 
 void CheckDecision(DtxController* controller,
-                   const absl::optional<int>& uplink_bandwidth_bps,
+                   const std::optional<int>& uplink_bandwidth_bps,
                    bool expected_dtx_enabled) {
   if (uplink_bandwidth_bps) {
     Controller::NetworkMetrics network_metrics;
@@ -48,7 +48,7 @@
 TEST(DtxControllerTest, OutputInitValueWhenUplinkBandwidthUnknown) {
   constexpr bool kInitialDtxEnabled = true;
   auto controller = CreateController(kInitialDtxEnabled);
-  CheckDecision(controller.get(), absl::nullopt, kInitialDtxEnabled);
+  CheckDecision(controller.get(), std::nullopt, kInitialDtxEnabled);
 }
 
 TEST(DtxControllerTest, TurnOnDtxForLowUplinkBandwidth) {
diff --git a/modules/audio_coding/audio_network_adaptor/event_log_writer.cc b/modules/audio_coding/audio_network_adaptor/event_log_writer.cc
index 0a79484..1bef64e 100644
--- a/modules/audio_coding/audio_network_adaptor/event_log_writer.cc
+++ b/modules/audio_coding/audio_network_adaptor/event_log_writer.cc
@@ -15,9 +15,9 @@
 #include <algorithm>
 #include <cstdlib>
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/rtc_event_log/rtc_event.h"
 #include "api/rtc_event_log/rtc_event_log.h"
 #include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
diff --git a/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.cc b/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.cc
index 2134dad..bcfbd75 100644
--- a/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.cc
+++ b/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.cc
@@ -68,7 +68,7 @@
 }
 
 bool FecControllerPlrBased::FecEnablingDecision(
-    const absl::optional<float>& packet_loss) const {
+    const std::optional<float>& packet_loss) const {
   if (!uplink_bandwidth_bps_ || !packet_loss) {
     return false;
   } else {
@@ -79,7 +79,7 @@
 }
 
 bool FecControllerPlrBased::FecDisablingDecision(
-    const absl::optional<float>& packet_loss) const {
+    const std::optional<float>& packet_loss) const {
   if (!uplink_bandwidth_bps_ || !packet_loss) {
     return false;
   } else {
diff --git a/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.h b/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.h
index 0c57ad1..71b2d69 100644
--- a/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.h
+++ b/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.h
@@ -12,8 +12,8 @@
 #define MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_FEC_CONTROLLER_PLR_BASED_H_
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "common_audio/smoothing_filter.h"
 #include "modules/audio_coding/audio_network_adaptor/controller.h"
 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
@@ -60,12 +60,12 @@
   void MakeDecision(AudioEncoderRuntimeConfig* config) override;
 
  private:
-  bool FecEnablingDecision(const absl::optional<float>& packet_loss) const;
-  bool FecDisablingDecision(const absl::optional<float>& packet_loss) const;
+  bool FecEnablingDecision(const std::optional<float>& packet_loss) const;
+  bool FecDisablingDecision(const std::optional<float>& packet_loss) const;
 
   const Config config_;
   bool fec_enabled_;
-  absl::optional<int> uplink_bandwidth_bps_;
+  std::optional<int> uplink_bandwidth_bps_;
   const std::unique_ptr<SmoothingFilter> packet_loss_smoother_;
 };
 
diff --git a/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based_unittest.cc b/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based_unittest.cc
index 743b087..f110477 100644
--- a/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based_unittest.cc
+++ b/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based_unittest.cc
@@ -79,8 +79,8 @@
 }
 
 void UpdateNetworkMetrics(FecControllerPlrBasedTestStates* states,
-                          const absl::optional<int>& uplink_bandwidth_bps,
-                          const absl::optional<float>& uplink_packet_loss) {
+                          const std::optional<int>& uplink_bandwidth_bps,
+                          const std::optional<float>& uplink_packet_loss) {
   // UpdateNetworkMetrics can accept multiple network metric updates at once.
   // However, currently, the most used case is to update one metric at a time.
   // To reflect this fact, we separate the calls.
@@ -132,7 +132,7 @@
           kEnablingPacketLossAtLowBw - kEpsilon, kEnablingPacketLossAtLowBw,
           kEnablingPacketLossAtLowBw + kEpsilon}) {
       auto states = CreateFecControllerPlrBased(initial_fec_enabled);
-      UpdateNetworkMetrics(&states, absl::nullopt, packet_loss);
+      UpdateNetworkMetrics(&states, std::nullopt, packet_loss);
       CheckDecision(&states, initial_fec_enabled, packet_loss);
     }
   }
@@ -147,7 +147,7 @@
                           kDisablingBandwidthLow + 1, kEnablingBandwidthLow - 1,
                           kEnablingBandwidthLow, kEnablingBandwidthLow + 1}) {
       auto states = CreateFecControllerPlrBased(initial_fec_enabled);
-      UpdateNetworkMetrics(&states, bandwidth, absl::nullopt);
+      UpdateNetworkMetrics(&states, bandwidth, std::nullopt);
       CheckDecision(&states, initial_fec_enabled, 0.0);
     }
   }
diff --git a/modules/audio_coding/audio_network_adaptor/frame_length_controller.h b/modules/audio_coding/audio_network_adaptor/frame_length_controller.h
index 04693f8..5abfb83 100644
--- a/modules/audio_coding/audio_network_adaptor/frame_length_controller.h
+++ b/modules/audio_coding/audio_network_adaptor/frame_length_controller.h
@@ -14,9 +14,9 @@
 #include <stddef.h>
 
 #include <map>
+#include <optional>
 #include <set>
 
-#include "absl/types/optional.h"
 #include "modules/audio_coding/audio_network_adaptor/controller.h"
 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
 
@@ -77,11 +77,11 @@
 
   std::set<int>::const_iterator frame_length_ms_;
 
-  absl::optional<int> uplink_bandwidth_bps_;
+  std::optional<int> uplink_bandwidth_bps_;
 
-  absl::optional<float> uplink_packet_loss_fraction_;
+  std::optional<float> uplink_packet_loss_fraction_;
 
-  absl::optional<size_t> overhead_bytes_per_packet_;
+  std::optional<size_t> overhead_bytes_per_packet_;
 
   // True if the previous frame length decision was an increase, otherwise
   // false.
diff --git a/modules/audio_coding/audio_network_adaptor/frame_length_controller_unittest.cc b/modules/audio_coding/audio_network_adaptor/frame_length_controller_unittest.cc
index 2312393..2bf52b2 100644
--- a/modules/audio_coding/audio_network_adaptor/frame_length_controller_unittest.cc
+++ b/modules/audio_coding/audio_network_adaptor/frame_length_controller_unittest.cc
@@ -124,9 +124,9 @@
 
 void UpdateNetworkMetrics(
     FrameLengthController* controller,
-    const absl::optional<int>& uplink_bandwidth_bps,
-    const absl::optional<float>& uplink_packet_loss_fraction,
-    const absl::optional<size_t>& overhead_bytes_per_packet) {
+    const std::optional<int>& uplink_bandwidth_bps,
+    const std::optional<float>& uplink_packet_loss_fraction,
+    const std::optional<size_t>& overhead_bytes_per_packet) {
   // UpdateNetworkMetrics can accept multiple network metric updates at once.
   // However, currently, the most used case is to update one metric at a time.
   // To reflect this fact, we separate the calls.
@@ -160,14 +160,14 @@
   auto controller = CreateController(CreateChangeCriteriaFor20msAnd60ms(),
                                      kDefaultEncoderFrameLengthsMs, 60);
   UpdateNetworkMetrics(controller.get(), kFl60msTo20msBandwidthBps,
-                       absl::nullopt, kOverheadBytesPerPacket);
+                       std::nullopt, kOverheadBytesPerPacket);
   CheckDecision(controller.get(), 20);
 }
 
 TEST(FrameLengthControllerTest, DecreaseTo20MsOnHighUplinkPacketLossFraction) {
   auto controller = CreateController(CreateChangeCriteriaFor20msAnd60ms(),
                                      kDefaultEncoderFrameLengthsMs, 60);
-  UpdateNetworkMetrics(controller.get(), absl::nullopt,
+  UpdateNetworkMetrics(controller.get(), std::nullopt,
                        kFlDecreasingPacketLossFraction,
                        kOverheadBytesPerPacket);
   CheckDecision(controller.get(), 20);
@@ -200,7 +200,7 @@
   auto controller = CreateController(CreateChangeCriteriaFor40msAnd60ms(),
                                      kDefaultEncoderFrameLengthsMs, 40);
   UpdateNetworkMetrics(controller.get(), kFl60msTo40msBandwidthBps,
-                       absl::nullopt, kOverheadBytesPerPacket);
+                       std::nullopt, kOverheadBytesPerPacket);
   CheckDecision(controller.get(), 40);
 }
 
@@ -316,11 +316,11 @@
                                      kDefaultEncoderFrameLengthsMs, 120);
   // It takes two steps for frame length to go from 120ms to 20ms.
   UpdateNetworkMetrics(controller.get(), kFl60msTo20msBandwidthBps,
-                       absl::nullopt, kOverheadBytesPerPacket);
+                       std::nullopt, kOverheadBytesPerPacket);
   CheckDecision(controller.get(), 60);
 
   UpdateNetworkMetrics(controller.get(), kFl60msTo20msBandwidthBps,
-                       absl::nullopt, kOverheadBytesPerPacket);
+                       std::nullopt, kOverheadBytesPerPacket);
   CheckDecision(controller.get(), 20);
 }
 
@@ -328,12 +328,12 @@
   auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(),
                                      kDefaultEncoderFrameLengthsMs, 120);
   // It takes two steps for frame length to go from 120ms to 20ms.
-  UpdateNetworkMetrics(controller.get(), absl::nullopt,
+  UpdateNetworkMetrics(controller.get(), std::nullopt,
                        kFlDecreasingPacketLossFraction,
                        kOverheadBytesPerPacket);
   CheckDecision(controller.get(), 60);
 
-  UpdateNetworkMetrics(controller.get(), absl::nullopt,
+  UpdateNetworkMetrics(controller.get(), std::nullopt,
                        kFlDecreasingPacketLossFraction,
                        kOverheadBytesPerPacket);
   CheckDecision(controller.get(), 20);
diff --git a/modules/audio_coding/audio_network_adaptor/frame_length_controller_v2.h b/modules/audio_coding/audio_network_adaptor/frame_length_controller_v2.h
index d7102b0..dc936c9 100644
--- a/modules/audio_coding/audio_network_adaptor/frame_length_controller_v2.h
+++ b/modules/audio_coding/audio_network_adaptor/frame_length_controller_v2.h
@@ -11,9 +11,9 @@
 #ifndef MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_FRAME_LENGTH_CONTROLLER_V2_H_
 #define MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_FRAME_LENGTH_CONTROLLER_V2_H_
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "modules/audio_coding/audio_network_adaptor/controller.h"
 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
 
@@ -34,9 +34,9 @@
   const int min_payload_bitrate_bps_;
   const bool use_slow_adaptation_;
 
-  absl::optional<int> uplink_bandwidth_bps_;
-  absl::optional<int> target_bitrate_bps_;
-  absl::optional<int> overhead_bytes_per_packet_;
+  std::optional<int> uplink_bandwidth_bps_;
+  std::optional<int> target_bitrate_bps_;
+  std::optional<int> overhead_bytes_per_packet_;
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_coding/audio_network_adaptor/frame_length_controller_v2_unittest.cc b/modules/audio_coding/audio_network_adaptor/frame_length_controller_v2_unittest.cc
index 1c88f47..1bec1ac 100644
--- a/modules/audio_coding/audio_network_adaptor/frame_length_controller_v2_unittest.cc
+++ b/modules/audio_coding/audio_network_adaptor/frame_length_controller_v2_unittest.cc
@@ -62,8 +62,8 @@
       std::make_unique<FrameLengthControllerV2>(kANASupportedFrameLengths,
                                                 kMinPayloadBitrateBps,
                                                 /*use_slow_adaptation=*/false);
-  absl::optional<int> target_audio_bitrate_bps_;
-  absl::optional<int> overhead_bytes_per_packet_;
+  std::optional<int> target_audio_bitrate_bps_;
+  std::optional<int> overhead_bytes_per_packet_;
 };
 
 // Don't return any decision if we haven't received all required network
diff --git a/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h b/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h
index 346ed5d..ed07298 100644
--- a/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h
+++ b/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_INCLUDE_AUDIO_NETWORK_ADAPTOR_H_
 #define MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_INCLUDE_AUDIO_NETWORK_ADAPTOR_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/audio_codecs/audio_encoder.h"
 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
 
diff --git a/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h b/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h
index bd16292..5934f6e 100644
--- a/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h
+++ b/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h
@@ -13,7 +13,7 @@
 
 #include <stddef.h>
 
-#include "absl/types/optional.h"
+#include <optional>
 
 namespace webrtc {
 
@@ -23,18 +23,18 @@
   ~AudioEncoderRuntimeConfig();
   AudioEncoderRuntimeConfig& operator=(const AudioEncoderRuntimeConfig& other);
   bool operator==(const AudioEncoderRuntimeConfig& other) const;
-  absl::optional<int> bitrate_bps;
-  absl::optional<int> frame_length_ms;
+  std::optional<int> bitrate_bps;
+  std::optional<int> frame_length_ms;
   // Note: This is what we tell the encoder. It doesn't have to reflect
   // the actual NetworkMetrics; it's subject to our decision.
-  absl::optional<float> uplink_packet_loss_fraction;
-  absl::optional<bool> enable_fec;
-  absl::optional<bool> enable_dtx;
+  std::optional<float> uplink_packet_loss_fraction;
+  std::optional<bool> enable_fec;
+  std::optional<bool> enable_dtx;
 
   // Some encoders can encode fewer channels than the actual input to make
   // better use of the bandwidth. `num_channels` sets the number of channels
   // to encode.
-  absl::optional<size_t> num_channels;
+  std::optional<size_t> num_channels;
 
   // This is true if the last frame length change was an increase, and otherwise
   // false.
diff --git a/modules/audio_coding/codecs/builtin_audio_decoder_factory_unittest.cc b/modules/audio_coding/codecs/builtin_audio_decoder_factory_unittest.cc
index d61c471..3383ffb 100644
--- a/modules/audio_coding/codecs/builtin_audio_decoder_factory_unittest.cc
+++ b/modules/audio_coding/codecs/builtin_audio_decoder_factory_unittest.cc
@@ -23,7 +23,7 @@
   rtc::scoped_refptr<AudioDecoderFactory> adf =
       CreateBuiltinAudioDecoderFactory();
   ASSERT_TRUE(adf);
-  EXPECT_FALSE(adf->Create(env, SdpAudioFormat("rey", 8000, 1), absl::nullopt));
+  EXPECT_FALSE(adf->Create(env, SdpAudioFormat("rey", 8000, 1), std::nullopt));
 }
 
 TEST(AudioDecoderFactoryTest, CreatePcmu) {
@@ -32,13 +32,12 @@
       CreateBuiltinAudioDecoderFactory();
   ASSERT_TRUE(adf);
   // PCMu supports 8 kHz, and any number of channels.
+  EXPECT_FALSE(adf->Create(env, SdpAudioFormat("pcmu", 8000, 0), std::nullopt));
+  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("pcmu", 8000, 1), std::nullopt));
+  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("pcmu", 8000, 2), std::nullopt));
+  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("pcmu", 8000, 3), std::nullopt));
   EXPECT_FALSE(
-      adf->Create(env, SdpAudioFormat("pcmu", 8000, 0), absl::nullopt));
-  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("pcmu", 8000, 1), absl::nullopt));
-  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("pcmu", 8000, 2), absl::nullopt));
-  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("pcmu", 8000, 3), absl::nullopt));
-  EXPECT_FALSE(
-      adf->Create(env, SdpAudioFormat("pcmu", 16000, 1), absl::nullopt));
+      adf->Create(env, SdpAudioFormat("pcmu", 16000, 1), std::nullopt));
 }
 
 TEST(AudioDecoderFactoryTest, CreatePcma) {
@@ -47,13 +46,12 @@
       CreateBuiltinAudioDecoderFactory();
   ASSERT_TRUE(adf);
   // PCMa supports 8 kHz, and any number of channels.
+  EXPECT_FALSE(adf->Create(env, SdpAudioFormat("pcma", 8000, 0), std::nullopt));
+  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("pcma", 8000, 1), std::nullopt));
+  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("pcma", 8000, 2), std::nullopt));
+  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("pcma", 8000, 3), std::nullopt));
   EXPECT_FALSE(
-      adf->Create(env, SdpAudioFormat("pcma", 8000, 0), absl::nullopt));
-  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("pcma", 8000, 1), absl::nullopt));
-  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("pcma", 8000, 2), absl::nullopt));
-  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("pcma", 8000, 3), absl::nullopt));
-  EXPECT_FALSE(
-      adf->Create(env, SdpAudioFormat("pcma", 16000, 1), absl::nullopt));
+      adf->Create(env, SdpAudioFormat("pcma", 16000, 1), std::nullopt));
 }
 
 TEST(AudioDecoderFactoryTest, CreateIlbc) {
@@ -62,15 +60,13 @@
       CreateBuiltinAudioDecoderFactory();
   ASSERT_TRUE(adf);
   // iLBC supports 8 kHz, 1 channel.
-  EXPECT_FALSE(
-      adf->Create(env, SdpAudioFormat("ilbc", 8000, 0), absl::nullopt));
+  EXPECT_FALSE(adf->Create(env, SdpAudioFormat("ilbc", 8000, 0), std::nullopt));
 #ifdef WEBRTC_CODEC_ILBC
-  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("ilbc", 8000, 1), absl::nullopt));
+  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("ilbc", 8000, 1), std::nullopt));
 #endif
+  EXPECT_FALSE(adf->Create(env, SdpAudioFormat("ilbc", 8000, 2), std::nullopt));
   EXPECT_FALSE(
-      adf->Create(env, SdpAudioFormat("ilbc", 8000, 2), absl::nullopt));
-  EXPECT_FALSE(
-      adf->Create(env, SdpAudioFormat("ilbc", 16000, 1), absl::nullopt));
+      adf->Create(env, SdpAudioFormat("ilbc", 16000, 1), std::nullopt));
 }
 
 TEST(AudioDecoderFactoryTest, CreateL16) {
@@ -83,10 +79,10 @@
   const int num_channels[] = {1, 2, 3, 24};
   for (int clockrate : clockrates) {
     EXPECT_FALSE(
-        adf->Create(env, SdpAudioFormat("l16", clockrate, 0), absl::nullopt));
+        adf->Create(env, SdpAudioFormat("l16", clockrate, 0), std::nullopt));
     for (int channels : num_channels) {
       EXPECT_TRUE(adf->Create(env, SdpAudioFormat("l16", clockrate, channels),
-                              absl::nullopt));
+                              std::nullopt));
     }
   }
 }
@@ -110,7 +106,7 @@
     EXPECT_FALSE(adf->Create(
         env,
         SdpAudioFormat(codec, 32000, AudioDecoder::kMaxNumberOfChannels + 1),
-        absl::nullopt));
+        std::nullopt));
   }
 }
 
@@ -120,20 +116,18 @@
       CreateBuiltinAudioDecoderFactory();
   ASSERT_TRUE(adf);
   // g722 supports 8 kHz, 1-2 channels.
+  EXPECT_FALSE(adf->Create(env, SdpAudioFormat("g722", 8000, 0), std::nullopt));
+  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("g722", 8000, 1), std::nullopt));
+  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("g722", 8000, 2), std::nullopt));
+  EXPECT_FALSE(adf->Create(env, SdpAudioFormat("g722", 8000, 3), std::nullopt));
   EXPECT_FALSE(
-      adf->Create(env, SdpAudioFormat("g722", 8000, 0), absl::nullopt));
-  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("g722", 8000, 1), absl::nullopt));
-  EXPECT_TRUE(adf->Create(env, SdpAudioFormat("g722", 8000, 2), absl::nullopt));
+      adf->Create(env, SdpAudioFormat("g722", 16000, 1), std::nullopt));
   EXPECT_FALSE(
-      adf->Create(env, SdpAudioFormat("g722", 8000, 3), absl::nullopt));
-  EXPECT_FALSE(
-      adf->Create(env, SdpAudioFormat("g722", 16000, 1), absl::nullopt));
-  EXPECT_FALSE(
-      adf->Create(env, SdpAudioFormat("g722", 32000, 1), absl::nullopt));
+      adf->Create(env, SdpAudioFormat("g722", 32000, 1), std::nullopt));
 
   // g722 actually uses a 16 kHz sample rate instead of the nominal 8 kHz.
   std::unique_ptr<AudioDecoder> dec =
-      adf->Create(env, SdpAudioFormat("g722", 8000, 1), absl::nullopt);
+      adf->Create(env, SdpAudioFormat("g722", 8000, 1), std::nullopt);
   EXPECT_EQ(16000, dec->SampleRateHz());
 }
 
@@ -157,7 +151,7 @@
             good,
             static_cast<bool>(adf->Create(
                 env, SdpAudioFormat("opus", hz, channels, std::move(params)),
-                absl::nullopt)));
+                std::nullopt)));
       }
     }
   }
diff --git a/modules/audio_coding/codecs/cng/audio_encoder_cng.cc b/modules/audio_coding/codecs/cng/audio_encoder_cng.cc
index de82cd9..cbb0ba9 100644
--- a/modules/audio_coding/codecs/cng/audio_encoder_cng.cc
+++ b/modules/audio_coding/codecs/cng/audio_encoder_cng.cc
@@ -12,9 +12,9 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/units/time_delta.h"
 #include "modules/audio_coding/codecs/cng/webrtc_cng.h"
 #include "rtc_base/checks.h"
@@ -54,10 +54,9 @@
       override;
   void OnReceivedUplinkPacketLossFraction(
       float uplink_packet_loss_fraction) override;
-  void OnReceivedUplinkBandwidth(
-      int target_audio_bitrate_bps,
-      absl::optional<int64_t> bwe_period_ms) override;
-  absl::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
+  void OnReceivedUplinkBandwidth(int target_audio_bitrate_bps,
+                                 std::optional<int64_t> bwe_period_ms) override;
+  std::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
       const override;
 
  private:
@@ -225,12 +224,12 @@
 
 void AudioEncoderCng::OnReceivedUplinkBandwidth(
     int target_audio_bitrate_bps,
-    absl::optional<int64_t> bwe_period_ms) {
+    std::optional<int64_t> bwe_period_ms) {
   speech_encoder_->OnReceivedUplinkBandwidth(target_audio_bitrate_bps,
                                              bwe_period_ms);
 }
 
-absl::optional<std::pair<TimeDelta, TimeDelta>>
+std::optional<std::pair<TimeDelta, TimeDelta>>
 AudioEncoderCng::GetFrameLengthRange() const {
   return speech_encoder_->GetFrameLengthRange();
 }
diff --git a/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc b/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
index c688004..4895c24 100644
--- a/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
+++ b/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
@@ -226,8 +226,8 @@
 TEST_F(AudioEncoderCngTest, CheckTargetAudioBitratePropagation) {
   CreateCng(MakeCngConfig());
   EXPECT_CALL(*mock_encoder_,
-              OnReceivedUplinkBandwidth(4711, absl::optional<int64_t>()));
-  cng_->OnReceivedUplinkBandwidth(4711, absl::nullopt);
+              OnReceivedUplinkBandwidth(4711, std::optional<int64_t>()));
+  cng_->OnReceivedUplinkBandwidth(4711, std::nullopt);
 }
 
 TEST_F(AudioEncoderCngTest, CheckPacketLossFractionPropagation) {
@@ -241,7 +241,7 @@
   auto expected_range =
       std::make_pair(TimeDelta::Millis(20), TimeDelta::Millis(20));
   EXPECT_CALL(*mock_encoder_, GetFrameLengthRange())
-      .WillRepeatedly(Return(absl::make_optional(expected_range)));
+      .WillRepeatedly(Return(std::make_optional(expected_range)));
   EXPECT_THAT(cng_->GetFrameLengthRange(), Optional(Eq(expected_range)));
 }
 
diff --git a/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc b/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
index 65e2da4..42aa25c 100644
--- a/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
+++ b/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
@@ -89,7 +89,7 @@
   speech_buffer_.clear();
 }
 
-absl::optional<std::pair<TimeDelta, TimeDelta>>
+std::optional<std::pair<TimeDelta, TimeDelta>>
 AudioEncoderPcm::GetFrameLengthRange() const {
   return {{TimeDelta::Millis(num_10ms_frames_per_packet_ * 10),
            TimeDelta::Millis(num_10ms_frames_per_packet_ * 10)}};
diff --git a/modules/audio_coding/codecs/g711/audio_encoder_pcm.h b/modules/audio_coding/codecs/g711/audio_encoder_pcm.h
index d50be4b..ad9a2ae 100644
--- a/modules/audio_coding/codecs/g711/audio_encoder_pcm.h
+++ b/modules/audio_coding/codecs/g711/audio_encoder_pcm.h
@@ -11,10 +11,10 @@
 #ifndef MODULES_AUDIO_CODING_CODECS_G711_AUDIO_ENCODER_PCM_H_
 #define MODULES_AUDIO_CODING_CODECS_G711_AUDIO_ENCODER_PCM_H_
 
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/units/time_delta.h"
 
@@ -43,7 +43,7 @@
   size_t Max10MsFramesInAPacket() const override;
   int GetTargetBitrate() const override;
   void Reset() override;
-  absl::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
+  std::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
       const override;
 
  protected:
diff --git a/modules/audio_coding/codecs/g722/audio_encoder_g722.cc b/modules/audio_coding/codecs/g722/audio_encoder_g722.cc
index b7d34ba..61d275e 100644
--- a/modules/audio_coding/codecs/g722/audio_encoder_g722.cc
+++ b/modules/audio_coding/codecs/g722/audio_encoder_g722.cc
@@ -79,7 +79,7 @@
     RTC_CHECK_EQ(0, WebRtcG722_EncoderInit(encoders_[i].encoder));
 }
 
-absl::optional<std::pair<TimeDelta, TimeDelta>>
+std::optional<std::pair<TimeDelta, TimeDelta>>
 AudioEncoderG722Impl::GetFrameLengthRange() const {
   return {{TimeDelta::Millis(num_10ms_frames_per_packet_ * 10),
            TimeDelta::Millis(num_10ms_frames_per_packet_ * 10)}};
diff --git a/modules/audio_coding/codecs/g722/audio_encoder_g722.h b/modules/audio_coding/codecs/g722/audio_encoder_g722.h
index a932aa8..4db7a7d 100644
--- a/modules/audio_coding/codecs/g722/audio_encoder_g722.h
+++ b/modules/audio_coding/codecs/g722/audio_encoder_g722.h
@@ -12,9 +12,9 @@
 #define MODULES_AUDIO_CODING_CODECS_G722_AUDIO_ENCODER_G722_H_
 
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/g722/audio_encoder_g722_config.h"
 #include "api/units/time_delta.h"
@@ -38,7 +38,7 @@
   size_t Max10MsFramesInAPacket() const override;
   int GetTargetBitrate() const override;
   void Reset() override;
-  absl::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
+  std::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
       const override;
 
  protected:
diff --git a/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc b/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc
index 9fbf42c..afe3aff 100644
--- a/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc
+++ b/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc
@@ -127,7 +127,7 @@
   num_10ms_frames_buffered_ = 0;
 }
 
-absl::optional<std::pair<TimeDelta, TimeDelta>>
+std::optional<std::pair<TimeDelta, TimeDelta>>
 AudioEncoderIlbcImpl::GetFrameLengthRange() const {
   return {{TimeDelta::Millis(num_10ms_frames_per_packet_ * 10),
            TimeDelta::Millis(num_10ms_frames_per_packet_ * 10)}};
diff --git a/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h b/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h
index c8dfa2c..31c2047 100644
--- a/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h
+++ b/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h
@@ -14,9 +14,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/ilbc/audio_encoder_ilbc_config.h"
 #include "api/units/time_delta.h"
@@ -41,7 +41,7 @@
                          rtc::ArrayView<const int16_t> audio,
                          rtc::Buffer* encoded) override;
   void Reset() override;
-  absl::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
+  std::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
       const override;
 
  private:
diff --git a/modules/audio_coding/codecs/legacy_encoded_audio_frame.cc b/modules/audio_coding/codecs/legacy_encoded_audio_frame.cc
index dacf325..82417f8 100644
--- a/modules/audio_coding/codecs/legacy_encoded_audio_frame.cc
+++ b/modules/audio_coding/codecs/legacy_encoded_audio_frame.cc
@@ -29,7 +29,7 @@
   return (ret < 0) ? 0 : static_cast<size_t>(ret);
 }
 
-absl::optional<AudioDecoder::EncodedAudioFrame::DecodeResult>
+std::optional<AudioDecoder::EncodedAudioFrame::DecodeResult>
 LegacyEncodedAudioFrame::Decode(rtc::ArrayView<int16_t> decoded) const {
   AudioDecoder::SpeechType speech_type = AudioDecoder::kSpeech;
   const int ret = decoder_->Decode(
@@ -37,7 +37,7 @@
       decoded.size() * sizeof(int16_t), decoded.data(), &speech_type);
 
   if (ret < 0)
-    return absl::nullopt;
+    return std::nullopt;
 
   return DecodeResult{static_cast<size_t>(ret), speech_type};
 }
diff --git a/modules/audio_coding/codecs/legacy_encoded_audio_frame.h b/modules/audio_coding/codecs/legacy_encoded_audio_frame.h
index 21da136..1063637 100644
--- a/modules/audio_coding/codecs/legacy_encoded_audio_frame.h
+++ b/modules/audio_coding/codecs/legacy_encoded_audio_frame.h
@@ -14,9 +14,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "rtc_base/buffer.h"
@@ -37,7 +37,7 @@
 
   size_t Duration() const override;
 
-  absl::optional<DecodeResult> Decode(
+  std::optional<DecodeResult> Decode(
       rtc::ArrayView<int16_t> decoded) const override;
 
   // For testing:
diff --git a/modules/audio_coding/codecs/opus/audio_coder_opus_common.cc b/modules/audio_coding/codecs/opus/audio_coder_opus_common.cc
index 03c0218..7e127cc 100644
--- a/modules/audio_coding/codecs/opus/audio_coder_opus_common.cc
+++ b/modules/audio_coding/codecs/opus/audio_coder_opus_common.cc
@@ -14,18 +14,18 @@
 
 namespace webrtc {
 
-absl::optional<std::string> GetFormatParameter(const SdpAudioFormat& format,
-                                               absl::string_view param) {
+std::optional<std::string> GetFormatParameter(const SdpAudioFormat& format,
+                                              absl::string_view param) {
   auto it = format.parameters.find(std::string(param));
   if (it == format.parameters.end())
-    return absl::nullopt;
+    return std::nullopt;
 
   return it->second;
 }
 
 // Parses a comma-separated string "1,2,0,6" into a std::vector<unsigned char>.
 template <>
-absl::optional<std::vector<unsigned char>> GetFormatParameter(
+std::optional<std::vector<unsigned char>> GetFormatParameter(
     const SdpAudioFormat& format,
     absl::string_view param) {
   std::vector<unsigned char> result;
@@ -41,7 +41,7 @@
         comma_separated_list.substr(pos, distance_to_next_comma);
     auto conv = rtc::StringToNumber<int>(substring_with_number);
     if (!conv.has_value()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     result.push_back(*conv);
     pos += substring_with_number.size() + 1;
diff --git a/modules/audio_coding/codecs/opus/audio_coder_opus_common.h b/modules/audio_coding/codecs/opus/audio_coder_opus_common.h
index 5ebb51b..708ae4a 100644
--- a/modules/audio_coding/codecs/opus/audio_coder_opus_common.h
+++ b/modules/audio_coding/codecs/opus/audio_coder_opus_common.h
@@ -11,29 +11,29 @@
 #ifndef MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_CODER_OPUS_COMMON_H_
 #define MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_CODER_OPUS_COMMON_H_
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_format.h"
 #include "rtc_base/string_to_number.h"
 
 namespace webrtc {
 
-absl::optional<std::string> GetFormatParameter(const SdpAudioFormat& format,
-                                               absl::string_view param);
+std::optional<std::string> GetFormatParameter(const SdpAudioFormat& format,
+                                              absl::string_view param);
 
 template <typename T>
-absl::optional<T> GetFormatParameter(const SdpAudioFormat& format,
-                                     absl::string_view param) {
+std::optional<T> GetFormatParameter(const SdpAudioFormat& format,
+                                    absl::string_view param) {
   return rtc::StringToNumber<T>(GetFormatParameter(format, param).value_or(""));
 }
 
 template <>
-absl::optional<std::vector<unsigned char>> GetFormatParameter(
+std::optional<std::vector<unsigned char>> GetFormatParameter(
     const SdpAudioFormat& format,
     absl::string_view param);
 
@@ -58,7 +58,7 @@
 
   bool IsDtxPacket() const override { return payload_.size() <= 2; }
 
-  absl::optional<DecodeResult> Decode(
+  std::optional<DecodeResult> Decode(
       rtc::ArrayView<int16_t> decoded) const override {
     AudioDecoder::SpeechType speech_type = AudioDecoder::kSpeech;
     int ret;
@@ -73,7 +73,7 @@
     }
 
     if (ret < 0)
-      return absl::nullopt;
+      return std::nullopt;
 
     return DecodeResult{static_cast<size_t>(ret), speech_type};
   }
diff --git a/modules/audio_coding/codecs/opus/audio_decoder_multi_channel_opus_impl.cc b/modules/audio_coding/codecs/opus/audio_decoder_multi_channel_opus_impl.cc
index 285ea89..7123b92 100644
--- a/modules/audio_coding/codecs/opus/audio_decoder_multi_channel_opus_impl.cc
+++ b/modules/audio_coding/codecs/opus/audio_decoder_multi_channel_opus_impl.cc
@@ -57,30 +57,30 @@
   WebRtcOpus_DecoderFree(dec_state_);
 }
 
-absl::optional<AudioDecoderMultiChannelOpusConfig>
+std::optional<AudioDecoderMultiChannelOpusConfig>
 AudioDecoderMultiChannelOpusImpl::SdpToConfig(const SdpAudioFormat& format) {
   AudioDecoderMultiChannelOpusConfig config;
   config.num_channels = format.num_channels;
   auto num_streams = GetFormatParameter<int>(format, "num_streams");
   if (!num_streams.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   config.num_streams = *num_streams;
 
   auto coupled_streams = GetFormatParameter<int>(format, "coupled_streams");
   if (!coupled_streams.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   config.coupled_streams = *coupled_streams;
 
   auto channel_mapping =
       GetFormatParameter<std::vector<unsigned char>>(format, "channel_mapping");
   if (!channel_mapping.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   config.channel_mapping = *channel_mapping;
   if (!config.IsOk()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return config;
 }
diff --git a/modules/audio_coding/codecs/opus/audio_decoder_multi_channel_opus_impl.h b/modules/audio_coding/codecs/opus/audio_decoder_multi_channel_opus_impl.h
index 2ff47a8..85dc5e1 100644
--- a/modules/audio_coding/codecs/opus/audio_decoder_multi_channel_opus_impl.h
+++ b/modules/audio_coding/codecs/opus/audio_decoder_multi_channel_opus_impl.h
@@ -46,7 +46,7 @@
   int SampleRateHz() const override;
   size_t Channels() const override;
 
-  static absl::optional<AudioDecoderMultiChannelOpusConfig> SdpToConfig(
+  static std::optional<AudioDecoderMultiChannelOpusConfig> SdpToConfig(
       const SdpAudioFormat& format);
 
  protected:
diff --git a/modules/audio_coding/codecs/opus/audio_decoder_multi_channel_opus_unittest.cc b/modules/audio_coding/codecs/opus/audio_decoder_multi_channel_opus_unittest.cc
index 57e2107..7b30a39 100644
--- a/modules/audio_coding/codecs/opus/audio_decoder_multi_channel_opus_unittest.cc
+++ b/modules/audio_coding/codecs/opus/audio_decoder_multi_channel_opus_unittest.cc
@@ -25,15 +25,15 @@
                                    {"num_streams", "2"}});
 
   EXPECT_EQ(GetFormatParameter(sdp_format, "channel_mapping"),
-            absl::optional<std::string>("0,1,2,3"));
+            std::optional<std::string>("0,1,2,3"));
 
   EXPECT_EQ(GetFormatParameter<int>(sdp_format, "coupled_streams"),
-            absl::optional<int>(2));
+            std::optional<int>(2));
 
-  EXPECT_EQ(GetFormatParameter(sdp_format, "missing"), absl::nullopt);
+  EXPECT_EQ(GetFormatParameter(sdp_format, "missing"), std::nullopt);
 
   EXPECT_EQ(GetFormatParameter<int>(sdp_format, "channel_mapping"),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(AudioDecoderMultiOpusTest, InvalidChannelMappings) {
@@ -43,7 +43,7 @@
                                     {{"channel_mapping", "3,0"},
                                      {"coupled_streams", "1"},
                                      {"num_streams", "2"}});
-    const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
+    const std::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
         AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
     EXPECT_FALSE(decoder_config.has_value());
   }
@@ -54,7 +54,7 @@
                                     {{"channel_mapping", "0,1,2,3,4,5"},
                                      {"coupled_streams", "0"},
                                      {"num_streams", "2"}});
-    const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
+    const std::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
         AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
     EXPECT_FALSE(decoder_config.has_value());
   }
@@ -63,7 +63,7 @@
     const SdpAudioFormat sdp_format(
         "multiopus", 48000, 5,
         {{"channel_mapping", "0,1,two,3,4"}, {"coupled_streams", "0"}});
-    const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
+    const std::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
         AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
     EXPECT_FALSE(decoder_config.has_value());
   }
@@ -75,7 +75,7 @@
                                    {"coupled_streams", "2"},
                                    {"num_streams", "2"}});
 
-  const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
+  const std::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
       AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
 
   ASSERT_TRUE(decoder_config.has_value());
@@ -92,7 +92,7 @@
                                      {"coupled_stream", "2"},
                                      {"num_streams", "2"}});
 
-    const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
+    const std::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
         AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
 
     EXPECT_FALSE(decoder_config.has_value());
@@ -104,7 +104,7 @@
                                      {"coupled_streams", "2"},
                                      {"num_streams", "2"}});
 
-    const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
+    const std::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
         AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
 
     EXPECT_FALSE(decoder_config.has_value());
@@ -117,7 +117,7 @@
                                    {"coupled_streams", "2"},
                                    {"num_streams", "2"}});
 
-  const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
+  const std::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
       AudioDecoderMultiChannelOpus::SdpToConfig(sdp_format);
 
   ASSERT_TRUE(decoder_config.has_value());
@@ -135,7 +135,7 @@
   EXPECT_FALSE(specs.empty());
 
   for (const AudioCodecSpec& spec : specs) {
-    const absl::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
+    const std::optional<AudioDecoderMultiChannelOpus::Config> decoder_config =
         AudioDecoderMultiChannelOpus::SdpToConfig(spec.format);
     ASSERT_TRUE(decoder_config.has_value());
 
diff --git a/modules/audio_coding/codecs/opus/audio_decoder_opus.cc b/modules/audio_coding/codecs/opus/audio_decoder_opus.cc
index 7d5e3cf..9eed1c6 100644
--- a/modules/audio_coding/codecs/opus/audio_decoder_opus.cc
+++ b/modules/audio_coding/codecs/opus/audio_decoder_opus.cc
@@ -11,9 +11,9 @@
 #include "modules/audio_coding/codecs/opus/audio_decoder_opus.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/field_trials_view.h"
 #include "modules/audio_coding/codecs/opus/audio_coder_opus_common.h"
diff --git a/modules/audio_coding/codecs/opus/audio_encoder_multi_channel_opus_impl.cc b/modules/audio_coding/codecs/opus/audio_encoder_multi_channel_opus_impl.cc
index 9d140f7..45f3be1 100644
--- a/modules/audio_coding/codecs/opus/audio_encoder_multi_channel_opus_impl.cc
+++ b/modules/audio_coding/codecs/opus/audio_encoder_multi_channel_opus_impl.cc
@@ -103,7 +103,7 @@
 // out how invalid it is and accurately log invalid values.
 int CalculateBitrate(int max_playback_rate_hz,
                      size_t num_channels,
-                     absl::optional<std::string> bitrate_param) {
+                     std::optional<std::string> bitrate_param) {
   const int default_bitrate =
       CalculateDefaultBitrate(max_playback_rate_hz, num_channels);
 
@@ -167,7 +167,7 @@
   RTC_CHECK(RecreateEncoderInstance(config_));
 }
 
-absl::optional<std::pair<TimeDelta, TimeDelta>>
+std::optional<std::pair<TimeDelta, TimeDelta>>
 AudioEncoderMultiChannelOpusImpl::GetFrameLengthRange() const {
   return {{TimeDelta::Millis(config_.frame_size_ms),
            TimeDelta::Millis(config_.frame_size_ms)}};
@@ -237,11 +237,11 @@
   return true;
 }
 
-absl::optional<AudioEncoderMultiChannelOpusConfig>
+std::optional<AudioEncoderMultiChannelOpusConfig>
 AudioEncoderMultiChannelOpusImpl::SdpToConfig(const SdpAudioFormat& format) {
   if (!absl::EqualsIgnoreCase(format.name, "multiopus") ||
       format.clockrate_hz != 48000) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   AudioEncoderMultiChannelOpusConfig config;
@@ -266,25 +266,25 @@
 
   auto num_streams = GetFormatParameter<int>(format, "num_streams");
   if (!num_streams.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   config.num_streams = *num_streams;
 
   auto coupled_streams = GetFormatParameter<int>(format, "coupled_streams");
   if (!coupled_streams.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   config.coupled_streams = *coupled_streams;
 
   auto channel_mapping =
       GetFormatParameter<std::vector<unsigned char>>(format, "channel_mapping");
   if (!channel_mapping.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   config.channel_mapping = *channel_mapping;
 
   if (!config.IsOk()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return config;
 }
diff --git a/modules/audio_coding/codecs/opus/audio_encoder_multi_channel_opus_impl.h b/modules/audio_coding/codecs/opus/audio_encoder_multi_channel_opus_impl.h
index 6d6e63b..9def211 100644
--- a/modules/audio_coding/codecs/opus/audio_encoder_multi_channel_opus_impl.h
+++ b/modules/audio_coding/codecs/opus/audio_encoder_multi_channel_opus_impl.h
@@ -15,10 +15,10 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_format.h"
@@ -45,7 +45,7 @@
 
   // Static interface for use by BuiltinAudioEncoderFactory.
   static constexpr const char* GetPayloadName() { return "multiopus"; }
-  static absl::optional<AudioCodecInfo> QueryAudioEncoder(
+  static std::optional<AudioCodecInfo> QueryAudioEncoder(
       const SdpAudioFormat& format);
 
   int SampleRateHz() const override;
@@ -55,7 +55,7 @@
   int GetTargetBitrate() const override;
 
   void Reset() override;
-  absl::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
+  std::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
       const override;
 
  protected:
@@ -64,7 +64,7 @@
                          rtc::Buffer* encoded) override;
 
  private:
-  static absl::optional<AudioEncoderMultiChannelOpusConfig> SdpToConfig(
+  static std::optional<AudioEncoderMultiChannelOpusConfig> SdpToConfig(
       const SdpAudioFormat& format);
   static AudioCodecInfo QueryAudioEncoder(
       const AudioEncoderMultiChannelOpusConfig& config);
diff --git a/modules/audio_coding/codecs/opus/audio_encoder_multi_channel_opus_unittest.cc b/modules/audio_coding/codecs/opus/audio_encoder_multi_channel_opus_unittest.cc
index 92f6f2c..7601589 100644
--- a/modules/audio_coding/codecs/opus/audio_encoder_multi_channel_opus_unittest.cc
+++ b/modules/audio_coding/codecs/opus/audio_encoder_multi_channel_opus_unittest.cc
@@ -26,7 +26,7 @@
                                     {{"channel_mapping", "3,0"},
                                      {"coupled_streams", "1"},
                                      {"num_streams", "2"}});
-    const absl::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
+    const std::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
         AudioEncoderMultiChannelOpus::SdpToConfig(sdp_format);
 
     // Maps input channel 0 to coded channel 3, which doesn't exist.
@@ -38,7 +38,7 @@
                                     {{"channel_mapping", "0"},
                                      {"coupled_streams", "1"},
                                      {"num_streams", "2"}});
-    const absl::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
+    const std::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
         AudioEncoderMultiChannelOpus::SdpToConfig(sdp_format);
 
     // The mapping is too short.
@@ -49,7 +49,7 @@
                                     {{"channel_mapping", "0,0,0"},
                                      {"coupled_streams", "0"},
                                      {"num_streams", "1"}});
-    const absl::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
+    const std::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
         AudioEncoderMultiChannelOpus::SdpToConfig(sdp_format);
 
     // Coded channel 0 comes from both input channels 0, 1 and 2.
@@ -60,7 +60,7 @@
                                     {{"channel_mapping", "0,255,255"},
                                      {"coupled_streams", "0"},
                                      {"num_streams", "1"}});
-    const absl::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
+    const std::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
         AudioEncoderMultiChannelOpus::SdpToConfig(sdp_format);
     ASSERT_TRUE(encoder_config.has_value());
 
@@ -72,7 +72,7 @@
                                     {{"channel_mapping", "0,255,255"},
                                      {"coupled_streams", "0"},
                                      {"num_streams", "2"}});
-    const absl::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
+    const std::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
         AudioEncoderMultiChannelOpus::SdpToConfig(sdp_format);
 
     // This is NOT fine, because channels nothing says how coded channel 1
@@ -90,7 +90,7 @@
                               {"channel_mapping", "0,4,1,2,3,5"},
                               {"num_streams", "4"},
                               {"coupled_streams", "2"}}});
-  const absl::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
+  const std::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
       AudioEncoderMultiChannelOpus::SdpToConfig(sdp_format);
   ASSERT_TRUE(encoder_config.has_value());
 
@@ -107,7 +107,7 @@
                                     {{"channel_mapping", "0,255,255"},
                                      {"coupled_streams", "0"},
                                      {"num_streams", "2"}});
-    const absl::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
+    const std::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
         AudioEncoderMultiChannelOpus::SdpToConfig(sdp_format);
     ASSERT_FALSE(encoder_config.has_value());
   }
@@ -116,7 +116,7 @@
                                     {{"channel_mapping", "1,255,0"},
                                      {"coupled_streams", "1"},
                                      {"num_streams", "1"}});
-    const absl::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
+    const std::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
         AudioEncoderMultiChannelOpus::SdpToConfig(sdp_format);
     ASSERT_TRUE(encoder_config.has_value());
 
@@ -141,7 +141,7 @@
   EXPECT_FALSE(specs.empty());
 
   for (const AudioCodecSpec& spec : specs) {
-    const absl::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
+    const std::optional<AudioEncoderMultiChannelOpus::Config> encoder_config =
         AudioEncoderMultiChannelOpus::SdpToConfig(spec.format);
     ASSERT_TRUE(encoder_config.has_value());
 
diff --git a/modules/audio_coding/codecs/opus/audio_encoder_opus.cc b/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
index 7eb8bbd..b2e44c7 100644
--- a/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
+++ b/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
@@ -89,7 +89,7 @@
 // out how invalid it is and accurately log invalid values.
 int CalculateBitrate(int max_playback_rate_hz,
                      size_t num_channels,
-                     absl::optional<std::string> bitrate_param) {
+                     std::optional<std::string> bitrate_param) {
   const int default_bitrate =
       CalculateDefaultBitrate(max_playback_rate_hz, num_channels);
 
@@ -228,11 +228,11 @@
   return info;
 }
 
-absl::optional<AudioEncoderOpusConfig> AudioEncoderOpusImpl::SdpToConfig(
+std::optional<AudioEncoderOpusConfig> AudioEncoderOpusImpl::SdpToConfig(
     const SdpAudioFormat& format) {
   if (!absl::EqualsIgnoreCase(format.name, "opus") ||
       format.clockrate_hz != kRtpTimestampRateHz || format.num_channels != 2) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   AudioEncoderOpusConfig config;
@@ -265,12 +265,12 @@
                             &config.supported_frame_lengths_ms);
   if (!config.IsOk()) {
     RTC_DCHECK_NOTREACHED();
-    return absl::nullopt;
+    return std::nullopt;
   }
   return config;
 }
 
-absl::optional<int> AudioEncoderOpusImpl::GetNewComplexity(
+std::optional<int> AudioEncoderOpusImpl::GetNewComplexity(
     const AudioEncoderOpusConfig& config) {
   RTC_DCHECK(config.IsOk());
   const int bitrate_bps = GetBitrateBps(config);
@@ -279,7 +279,7 @@
       bitrate_bps <= config.complexity_threshold_bps +
                          config.complexity_threshold_window_bps) {
     // Within the hysteresis window; make no change.
-    return absl::nullopt;
+    return std::nullopt;
   } else {
     return bitrate_bps <= config.complexity_threshold_bps
                ? config.low_rate_complexity
@@ -287,7 +287,7 @@
   }
 }
 
-absl::optional<int> AudioEncoderOpusImpl::GetNewBandwidth(
+std::optional<int> AudioEncoderOpusImpl::GetNewBandwidth(
     const AudioEncoderOpusConfig& config,
     OpusEncInst* inst) {
   constexpr int kMinWidebandBitrate = 8000;
@@ -296,17 +296,17 @@
   RTC_DCHECK(config.IsOk());
   const int bitrate = GetBitrateBps(config);
   if (bitrate > kAutomaticThreshold) {
-    return absl::optional<int>(OPUS_AUTO);
+    return std::optional<int>(OPUS_AUTO);
   }
   const int bandwidth = WebRtcOpus_GetBandwidth(inst);
   RTC_DCHECK_GE(bandwidth, 0);
   if (bitrate > kMaxNarrowbandBitrate && bandwidth < OPUS_BANDWIDTH_WIDEBAND) {
-    return absl::optional<int>(OPUS_BANDWIDTH_WIDEBAND);
+    return std::optional<int>(OPUS_BANDWIDTH_WIDEBAND);
   } else if (bitrate < kMinWidebandBitrate &&
              bandwidth > OPUS_BANDWIDTH_NARROWBAND) {
-    return absl::optional<int>(OPUS_BANDWIDTH_NARROWBAND);
+    return std::optional<int>(OPUS_BANDWIDTH_NARROWBAND);
   }
-  return absl::optional<int>();
+  return std::optional<int>();
 }
 
 class AudioEncoderOpusImpl::PacketLossFractionSmoother {
@@ -496,8 +496,8 @@
 
 void AudioEncoderOpusImpl::OnReceivedUplinkBandwidth(
     int target_audio_bitrate_bps,
-    absl::optional<int64_t> bwe_period_ms,
-    absl::optional<int64_t> stable_target_bitrate_bps) {
+    std::optional<int64_t> bwe_period_ms,
+    std::optional<int64_t> stable_target_bitrate_bps) {
   if (audio_network_adaptor_) {
     audio_network_adaptor_->SetTargetAudioBitrate(target_audio_bitrate_bps);
     if (use_stable_target_for_adaptation_) {
@@ -538,9 +538,9 @@
 }
 void AudioEncoderOpusImpl::OnReceivedUplinkBandwidth(
     int target_audio_bitrate_bps,
-    absl::optional<int64_t> bwe_period_ms) {
+    std::optional<int64_t> bwe_period_ms) {
   OnReceivedUplinkBandwidth(target_audio_bitrate_bps, bwe_period_ms,
-                            absl::nullopt);
+                            std::nullopt);
 }
 
 void AudioEncoderOpusImpl::OnReceivedUplinkAllocation(
@@ -794,7 +794,7 @@
     if (!bitrate_smoother_last_update_time_ ||
         now_ms - *bitrate_smoother_last_update_time_ >=
             config_.uplink_bandwidth_update_interval_ms) {
-      absl::optional<float> smoothed_bitrate = bitrate_smoother_->GetAverage();
+      std::optional<float> smoothed_bitrate = bitrate_smoother_->GetAverage();
       if (smoothed_bitrate)
         audio_network_adaptor_->SetUplinkBandwidth(*smoothed_bitrate);
       bitrate_smoother_last_update_time_ = now_ms;
@@ -809,11 +809,11 @@
   return ANAStats();
 }
 
-absl::optional<std::pair<TimeDelta, TimeDelta> >
+std::optional<std::pair<TimeDelta, TimeDelta> >
 AudioEncoderOpusImpl::GetFrameLengthRange() const {
   if (audio_network_adaptor_) {
     if (config_.supported_frame_lengths_ms.empty()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return {{TimeDelta::Millis(config_.supported_frame_lengths_ms.front()),
              TimeDelta::Millis(config_.supported_frame_lengths_ms.back())}};
diff --git a/modules/audio_coding/codecs/opus/audio_encoder_opus.h b/modules/audio_coding/codecs/opus/audio_encoder_opus.h
index b09fbf1..f1c9c65 100644
--- a/modules/audio_coding/codecs/opus/audio_encoder_opus.h
+++ b/modules/audio_coding/codecs/opus/audio_encoder_opus.h
@@ -13,11 +13,11 @@
 
 #include <functional>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/audio_codecs/audio_format.h"
 #include "api/audio_codecs/opus/audio_encoder_opus_config.h"
@@ -36,13 +36,13 @@
   // defined by complexity_threshold_bps +/- complexity_threshold_window_bps.
   // Otherwise, returns the current complexity depending on whether the
   // current bitrate is above or below complexity_threshold_bps.
-  static absl::optional<int> GetNewComplexity(
+  static std::optional<int> GetNewComplexity(
       const AudioEncoderOpusConfig& config);
 
   // Returns OPUS_AUTO if the the current bitrate is above wideband threshold.
   // Returns empty if it is below, but bandwidth coincides with the desired one.
   // Otherwise returns the desired bandwidth.
-  static absl::optional<int> GetNewBandwidth(
+  static std::optional<int> GetNewBandwidth(
       const AudioEncoderOpusConfig& config,
       OpusEncInst* inst);
 
@@ -90,16 +90,15 @@
   void OnReceivedUplinkPacketLossFraction(
       float uplink_packet_loss_fraction) override;
   void OnReceivedTargetAudioBitrate(int target_audio_bitrate_bps) override;
-  void OnReceivedUplinkBandwidth(
-      int target_audio_bitrate_bps,
-      absl::optional<int64_t> bwe_period_ms) override;
+  void OnReceivedUplinkBandwidth(int target_audio_bitrate_bps,
+                                 std::optional<int64_t> bwe_period_ms) override;
   void OnReceivedUplinkAllocation(BitrateAllocationUpdate update) override;
   void OnReceivedRtt(int rtt_ms) override;
   void OnReceivedOverhead(size_t overhead_bytes_per_packet) override;
   void SetReceiverFrameLengthRange(int min_frame_length_ms,
                                    int max_frame_length_ms) override;
   ANAStats GetANAStats() const override;
-  absl::optional<std::pair<TimeDelta, TimeDelta> > GetFrameLengthRange()
+  std::optional<std::pair<TimeDelta, TimeDelta> > GetFrameLengthRange()
       const override;
   rtc::ArrayView<const int> supported_frame_lengths_ms() const {
     return config_.supported_frame_lengths_ms;
@@ -129,7 +128,7 @@
       const AudioNetworkAdaptorCreator& audio_network_adaptor_creator,
       std::unique_ptr<SmoothingFilter> bitrate_smoother);
 
-  static absl::optional<AudioEncoderOpusConfig> SdpToConfig(
+  static std::optional<AudioEncoderOpusConfig> SdpToConfig(
       const SdpAudioFormat& format);
   static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
   static AudioCodecInfo QueryAudioEncoder(const AudioEncoderOpusConfig& config);
@@ -144,8 +143,8 @@
 
   void OnReceivedUplinkBandwidth(
       int target_audio_bitrate_bps,
-      absl::optional<int64_t> bwe_period_ms,
-      absl::optional<int64_t> link_capacity_allocation);
+      std::optional<int64_t> bwe_period_ms,
+      std::optional<int64_t> link_capacity_allocation);
 
   // TODO(minyue): remove "override" when we can deprecate
   // `AudioEncoder::SetTargetBitrate`.
@@ -177,9 +176,9 @@
   std::unique_ptr<PacketLossFractionSmoother> packet_loss_fraction_smoother_;
   const AudioNetworkAdaptorCreator audio_network_adaptor_creator_;
   std::unique_ptr<AudioNetworkAdaptor> audio_network_adaptor_;
-  absl::optional<size_t> overhead_bytes_per_packet_;
+  std::optional<size_t> overhead_bytes_per_packet_;
   const std::unique_ptr<SmoothingFilter> bitrate_smoother_;
-  absl::optional<int64_t> bitrate_smoother_last_update_time_;
+  std::optional<int64_t> bitrate_smoother_last_update_time_;
   int consecutive_dtx_frames_;
 
   friend struct AudioEncoderOpus;
diff --git a/modules/audio_coding/codecs/opus/audio_encoder_opus_unittest.cc b/modules/audio_coding/codecs/opus/audio_encoder_opus_unittest.cc
index c12f70f..fc37a21 100644
--- a/modules/audio_coding/codecs/opus/audio_encoder_opus_unittest.cc
+++ b/modules/audio_coding/codecs/opus/audio_encoder_opus_unittest.cc
@@ -208,24 +208,24 @@
                            rtc::CheckedDivExact(48000, kDefaultOpusPacSize);
   // Set a too low bitrate.
   states->encoder->OnReceivedUplinkBandwidth(kMinBitrateBps + kOverheadBps - 1,
-                                             absl::nullopt);
+                                             std::nullopt);
   EXPECT_EQ(kMinBitrateBps, states->encoder->GetTargetBitrate());
   // Set a too high bitrate.
   states->encoder->OnReceivedUplinkBandwidth(kMaxBitrateBps + kOverheadBps + 1,
-                                             absl::nullopt);
+                                             std::nullopt);
   EXPECT_EQ(kMaxBitrateBps, states->encoder->GetTargetBitrate());
   // Set the minimum rate.
   states->encoder->OnReceivedUplinkBandwidth(kMinBitrateBps + kOverheadBps,
-                                             absl::nullopt);
+                                             std::nullopt);
   EXPECT_EQ(kMinBitrateBps, states->encoder->GetTargetBitrate());
   // Set the maximum rate.
   states->encoder->OnReceivedUplinkBandwidth(kMaxBitrateBps + kOverheadBps,
-                                             absl::nullopt);
+                                             std::nullopt);
   EXPECT_EQ(kMaxBitrateBps, states->encoder->GetTargetBitrate());
   // Set rates from kMaxBitrateBps up to 32000 bps.
   for (int rate = kMinBitrateBps + kOverheadBps; rate <= 32000 + kOverheadBps;
        rate += 1000) {
-    states->encoder->OnReceivedUplinkBandwidth(rate, absl::nullopt);
+    states->encoder->OnReceivedUplinkBandwidth(rate, std::nullopt);
     EXPECT_EQ(rate - kOverheadBps, states->encoder->GetTargetBitrate());
   }
 }
@@ -379,7 +379,7 @@
   auto states = CreateCodec(sample_rate_hz_, 2);
 
   states->encoder->OnReceivedUplinkBandwidth(kDefaultOpusRate * 2,
-                                             absl::nullopt);
+                                             std::nullopt);
 
   // Since `OnReceivedOverhead` has not been called, the codec bitrate should
   // not change.
@@ -394,7 +394,7 @@
 
   // Bitrate within hysteresis window. Expect empty output.
   config.bitrate_bps = 12500;
-  EXPECT_EQ(absl::nullopt, AudioEncoderOpusImpl::GetNewComplexity(config));
+  EXPECT_EQ(std::nullopt, AudioEncoderOpusImpl::GetNewComplexity(config));
 
   // Bitrate below hysteresis window. Expect higher complexity.
   config.bitrate_bps = 10999;
@@ -402,7 +402,7 @@
 
   // Bitrate within hysteresis window. Expect empty output.
   config.bitrate_bps = 12500;
-  EXPECT_EQ(absl::nullopt, AudioEncoderOpusImpl::GetNewComplexity(config));
+  EXPECT_EQ(std::nullopt, AudioEncoderOpusImpl::GetNewComplexity(config));
 
   // Bitrate above hysteresis window. Expect lower complexity.
   config.bitrate_bps = 14001;
@@ -428,9 +428,9 @@
                    sample_rate_hz_));
 
   // Bitrate below minmum wideband. Expect narrowband.
-  config.bitrate_bps = absl::optional<int>(7999);
+  config.bitrate_bps = std::optional<int>(7999);
   auto bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
-  EXPECT_EQ(absl::optional<int>(OPUS_BANDWIDTH_NARROWBAND), bandwidth);
+  EXPECT_EQ(std::optional<int>(OPUS_BANDWIDTH_NARROWBAND), bandwidth);
   WebRtcOpus_SetBandwidth(inst, *bandwidth);
   // It is necessary to encode here because Opus has some logic in the encoder
   // that goes from the user-set bandwidth to the used and returned one.
@@ -439,14 +439,14 @@
                     kMaxBytes, bitstream);
 
   // Bitrate not yet above maximum narrowband. Expect empty.
-  config.bitrate_bps = absl::optional<int>(9000);
+  config.bitrate_bps = std::optional<int>(9000);
   bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
-  EXPECT_EQ(absl::optional<int>(), bandwidth);
+  EXPECT_EQ(std::optional<int>(), bandwidth);
 
   // Bitrate above maximum narrowband. Expect wideband.
-  config.bitrate_bps = absl::optional<int>(9001);
+  config.bitrate_bps = std::optional<int>(9001);
   bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
-  EXPECT_EQ(absl::optional<int>(OPUS_BANDWIDTH_WIDEBAND), bandwidth);
+  EXPECT_EQ(std::optional<int>(OPUS_BANDWIDTH_WIDEBAND), bandwidth);
   WebRtcOpus_SetBandwidth(inst, *bandwidth);
   // It is necessary to encode here because Opus has some logic in the encoder
   // that goes from the user-set bandwidth to the used and returned one.
@@ -455,14 +455,14 @@
                     kMaxBytes, bitstream);
 
   // Bitrate not yet below minimum wideband. Expect empty.
-  config.bitrate_bps = absl::optional<int>(8000);
+  config.bitrate_bps = std::optional<int>(8000);
   bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
-  EXPECT_EQ(absl::optional<int>(), bandwidth);
+  EXPECT_EQ(std::optional<int>(), bandwidth);
 
   // Bitrate above automatic threshold. Expect automatic.
-  config.bitrate_bps = absl::optional<int>(12001);
+  config.bitrate_bps = std::optional<int>(12001);
   bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
-  EXPECT_EQ(absl::optional<int>(OPUS_AUTO), bandwidth);
+  EXPECT_EQ(std::optional<int>(OPUS_AUTO), bandwidth);
 
   EXPECT_EQ(0, WebRtcOpus_EncoderFree(inst));
 }
@@ -528,7 +528,7 @@
   rtc::Buffer encoded;
   uint32_t rtp_timestamp = 12345;  // Just a number not important to this test.
 
-  states->encoder->OnReceivedUplinkBandwidth(0, absl::nullopt);
+  states->encoder->OnReceivedUplinkBandwidth(0, std::nullopt);
   for (int packet_index = 0; packet_index < kNumPacketsToEncode;
        packet_index++) {
     // Make sure we are not encoding before we have enough data for
@@ -676,7 +676,7 @@
   std::unique_ptr<AudioEncoder> encoder = AudioEncoderOpus::MakeAudioEncoder(
       CreateEnvironment(), config, {.payload_type = kDefaultOpusPayloadType});
   auto ptime = webrtc::TimeDelta::Millis(10);
-  absl::optional<std::pair<webrtc::TimeDelta, webrtc::TimeDelta>> range = {
+  std::optional<std::pair<webrtc::TimeDelta, webrtc::TimeDelta>> range = {
       {ptime, ptime}};
   EXPECT_EQ(encoder->GetFrameLengthRange(), range);
 }
diff --git a/modules/audio_coding/codecs/opus/opus_bandwidth_unittest.cc b/modules/audio_coding/codecs/opus/opus_bandwidth_unittest.cc
index 85b9293..2e05447 100644
--- a/modules/audio_coding/codecs/opus/opus_bandwidth_unittest.cc
+++ b/modules/audio_coding/codecs/opus/opus_bandwidth_unittest.cc
@@ -114,7 +114,7 @@
 
   // Create encoder.
   AudioEncoderOpusConfig enc_config;
-  enc_config.bitrate_bps = absl::optional<int>(7999);
+  enc_config.bitrate_bps = std::optional<int>(7999);
   enc_config.num_channels = kNumChannels;
   auto encoder =
       AudioEncoderOpus::MakeAudioEncoder(env, enc_config, {.payload_type = 17});
diff --git a/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc b/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
index 634f14d..a622de7 100644
--- a/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
+++ b/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
@@ -237,7 +237,7 @@
 
 void AudioEncoderCopyRed::OnReceivedUplinkBandwidth(
     int target_audio_bitrate_bps,
-    absl::optional<int64_t> bwe_period_ms) {
+    std::optional<int64_t> bwe_period_ms) {
   speech_encoder_->OnReceivedUplinkBandwidth(target_audio_bitrate_bps,
                                              bwe_period_ms);
 }
@@ -247,7 +247,7 @@
   speech_encoder_->OnReceivedUplinkAllocation(update);
 }
 
-absl::optional<std::pair<TimeDelta, TimeDelta>>
+std::optional<std::pair<TimeDelta, TimeDelta>>
 AudioEncoderCopyRed::GetFrameLengthRange() const {
   return speech_encoder_->GetFrameLengthRange();
 }
diff --git a/modules/audio_coding/codecs/red/audio_encoder_copy_red.h b/modules/audio_coding/codecs/red/audio_encoder_copy_red.h
index 359b5ea..dee6a42 100644
--- a/modules/audio_coding/codecs/red/audio_encoder_copy_red.h
+++ b/modules/audio_coding/codecs/red/audio_encoder_copy_red.h
@@ -16,9 +16,9 @@
 
 #include <list>
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/field_trials_view.h"
@@ -70,16 +70,15 @@
   void DisableAudioNetworkAdaptor() override;
   void OnReceivedUplinkPacketLossFraction(
       float uplink_packet_loss_fraction) override;
-  void OnReceivedUplinkBandwidth(
-      int target_audio_bitrate_bps,
-      absl::optional<int64_t> bwe_period_ms) override;
+  void OnReceivedUplinkBandwidth(int target_audio_bitrate_bps,
+                                 std::optional<int64_t> bwe_period_ms) override;
   void OnReceivedUplinkAllocation(BitrateAllocationUpdate update) override;
   void OnReceivedRtt(int rtt_ms) override;
   void OnReceivedOverhead(size_t overhead_bytes_per_packet) override;
   void SetReceiverFrameLengthRange(int min_frame_length_ms,
                                    int max_frame_length_ms) override;
   ANAStats GetANAStats() const override;
-  absl::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
+  std::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
       const override;
   rtc::ArrayView<std::unique_ptr<AudioEncoder>> ReclaimContainedEncoders()
       override;
diff --git a/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc b/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
index e9b1b07..8f2703e 100644
--- a/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
+++ b/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
@@ -106,8 +106,8 @@
 
 TEST_F(AudioEncoderCopyRedTest, CheckTargetAudioBitratePropagation) {
   EXPECT_CALL(*mock_encoder_,
-              OnReceivedUplinkBandwidth(4711, absl::optional<int64_t>()));
-  red_->OnReceivedUplinkBandwidth(4711, absl::nullopt);
+              OnReceivedUplinkBandwidth(4711, std::optional<int64_t>()));
+  red_->OnReceivedUplinkBandwidth(4711, std::nullopt);
 }
 
 TEST_F(AudioEncoderCopyRedTest, CheckPacketLossFractionPropagation) {
@@ -119,7 +119,7 @@
   auto expected_range =
       std::make_pair(TimeDelta::Millis(20), TimeDelta::Millis(20));
   EXPECT_CALL(*mock_encoder_, GetFrameLengthRange())
-      .WillRepeatedly(Return(absl::make_optional(expected_range)));
+      .WillRepeatedly(Return(std::make_optional(expected_range)));
   EXPECT_THAT(red_->GetFrameLengthRange(), Optional(Eq(expected_range)));
 }
 
diff --git a/modules/audio_coding/include/audio_coding_module.h b/modules/audio_coding/include/audio_coding_module.h
index 5c5bd16..ec8255e 100644
--- a/modules/audio_coding/include/audio_coding_module.h
+++ b/modules/audio_coding/include/audio_coding_module.h
@@ -12,11 +12,11 @@
 #define MODULES_AUDIO_CODING_INCLUDE_AUDIO_CODING_MODULE_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/function_view.h"
 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
diff --git a/modules/audio_coding/neteq/audio_decoder_unittest.cc b/modules/audio_coding/neteq/audio_decoder_unittest.cc
index a39b46b..ddcf020 100644
--- a/modules/audio_coding/neteq/audio_decoder_unittest.cc
+++ b/modules/audio_coding/neteq/audio_decoder_unittest.cc
@@ -419,7 +419,7 @@
 
 namespace {
 int SetAndGetTargetBitrate(AudioEncoder* audio_encoder, int rate) {
-  audio_encoder->OnReceivedUplinkBandwidth(rate, absl::nullopt);
+  audio_encoder->OnReceivedUplinkBandwidth(rate, std::nullopt);
   return audio_encoder->GetTargetBitrate();
 }
 void TestSetAndGetTargetBitratesWithFixedCodec(AudioEncoder* audio_encoder,
diff --git a/modules/audio_coding/neteq/decision_logic.cc b/modules/audio_coding/neteq/decision_logic.cc
index c05bea5..7d9f3a9 100644
--- a/modules/audio_coding/neteq/decision_logic.cc
+++ b/modules/audio_coding/neteq/decision_logic.cc
@@ -14,8 +14,8 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/neteq/neteq.h"
 #include "api/neteq/neteq_controller.h"
 #include "modules/audio_coding/neteq/packet_arrival_history.h"
@@ -171,13 +171,12 @@
   return buffer_level_filter_->filtered_current_level();
 }
 
-absl::optional<int> DecisionLogic::PacketArrived(
-    int fs_hz,
-    bool should_update_stats,
-    const PacketArrivedInfo& info) {
+std::optional<int> DecisionLogic::PacketArrived(int fs_hz,
+                                                bool should_update_stats,
+                                                const PacketArrivedInfo& info) {
   buffer_flush_ = buffer_flush_ || info.buffer_flush;
   if (!should_update_stats || info.is_cng_or_dtmf) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (info.packet_length_samples > 0 && fs_hz > 0 &&
       info.packet_length_samples != packet_length_samples_) {
@@ -188,7 +187,7 @@
                                                   info.packet_length_samples);
   if (!inserted || packet_arrival_history_->size() < 2) {
     // No meaningful delay estimate unless at least 2 packets have arrived.
-    return absl::nullopt;
+    return std::nullopt;
   }
   int arrival_delay_ms =
       packet_arrival_history_->GetDelayMs(info.main_timestamp);
diff --git a/modules/audio_coding/neteq/decision_logic.h b/modules/audio_coding/neteq/decision_logic.h
index c94aa49..21cbc56 100644
--- a/modules/audio_coding/neteq/decision_logic.h
+++ b/modules/audio_coding/neteq/decision_logic.h
@@ -70,9 +70,9 @@
 
   int UnlimitedTargetLevelMs() const override;
 
-  absl::optional<int> PacketArrived(int fs_hz,
-                                    bool should_update_stats,
-                                    const PacketArrivedInfo& info) override;
+  std::optional<int> PacketArrived(int fs_hz,
+                                   bool should_update_stats,
+                                   const PacketArrivedInfo& info) override;
 
   void RegisterEmptyPacket() override {}
 
diff --git a/modules/audio_coding/neteq/decision_logic_unittest.cc b/modules/audio_coding/neteq/decision_logic_unittest.cc
index d7c06ed..ecf353c 100644
--- a/modules/audio_coding/neteq/decision_logic_unittest.cc
+++ b/modules/audio_coding/neteq/decision_logic_unittest.cc
@@ -195,7 +195,7 @@
 
 TEST_F(DecisionLogicTest, CngTimeout) {
   auto status = CreateNetEqStatus(NetEq::Mode::kCodecInternalCng, 0);
-  status.next_packet = absl::nullopt;
+  status.next_packet = std::nullopt;
   status.generated_noise_samples = kSamplesPerMs * 500;
   bool reset_decoder = false;
   EXPECT_EQ(decision_logic_->GetDecision(status, &reset_decoder),
diff --git a/modules/audio_coding/neteq/decoder_database.cc b/modules/audio_coding/neteq/decoder_database.cc
index 28a985d..e97d59f 100644
--- a/modules/audio_coding/neteq/decoder_database.cc
+++ b/modules/audio_coding/neteq/decoder_database.cc
@@ -30,7 +30,7 @@
 DecoderDatabase::DecoderDatabase(
     const Environment& env,
     scoped_refptr<AudioDecoderFactory> decoder_factory,
-    absl::optional<AudioCodecPairId> codec_pair_id)
+    std::optional<AudioCodecPairId> codec_pair_id)
     : env_(env),
       active_decoder_type_(-1),
       active_cng_decoder_type_(-1),
@@ -42,7 +42,7 @@
 DecoderDatabase::DecoderInfo::DecoderInfo(
     const Environment& env,
     const SdpAudioFormat& audio_format,
-    absl::optional<AudioCodecPairId> codec_pair_id,
+    std::optional<AudioCodecPairId> codec_pair_id,
     AudioDecoderFactory* factory)
     : env_(env),
       audio_format_(audio_format),
@@ -73,7 +73,7 @@
   return absl::EqualsIgnoreCase(audio_format_.name, name);
 }
 
-absl::optional<DecoderDatabase::DecoderInfo::CngDecoder>
+std::optional<DecoderDatabase::DecoderInfo::CngDecoder>
 DecoderDatabase::DecoderInfo::CngDecoder::Create(const SdpAudioFormat& format) {
   if (absl::EqualsIgnoreCase(format.name, "CN")) {
     // CN has a 1:1 RTP clock rate to sample rate ratio.
@@ -82,7 +82,7 @@
                sample_rate_hz == 32000 || sample_rate_hz == 48000);
     return DecoderDatabase::DecoderInfo::CngDecoder{sample_rate_hz};
   } else {
-    return absl::nullopt;
+    return std::nullopt;
   }
 }
 
diff --git a/modules/audio_coding/neteq/decoder_database.h b/modules/audio_coding/neteq/decoder_database.h
index f70d255..9c1a1ec 100644
--- a/modules/audio_coding/neteq/decoder_database.h
+++ b/modules/audio_coding/neteq/decoder_database.h
@@ -42,7 +42,7 @@
    public:
     DecoderInfo(const Environment& env,
                 const SdpAudioFormat& audio_format,
-                absl::optional<AudioCodecPairId> codec_pair_id,
+                std::optional<AudioCodecPairId> codec_pair_id,
                 AudioDecoderFactory* factory);
     DecoderInfo(DecoderInfo&&);
     ~DecoderInfo();
@@ -86,16 +86,16 @@
    private:
     const Environment env_;
     const SdpAudioFormat audio_format_;
-    const absl::optional<AudioCodecPairId> codec_pair_id_;
+    const std::optional<AudioCodecPairId> codec_pair_id_;
     AudioDecoderFactory* const factory_;
     mutable std::unique_ptr<AudioDecoder> decoder_;
 
     // Set iff this is a comfort noise decoder.
     struct CngDecoder {
-      static absl::optional<CngDecoder> Create(const SdpAudioFormat& format);
+      static std::optional<CngDecoder> Create(const SdpAudioFormat& format);
       int sample_rate_hz;
     };
-    const absl::optional<CngDecoder> cng_decoder_;
+    const std::optional<CngDecoder> cng_decoder_;
 
     enum class Subtype : int8_t { kNormal, kComfortNoise, kDtmf, kRed };
 
@@ -110,7 +110,7 @@
 
   DecoderDatabase(const Environment& env,
                   scoped_refptr<AudioDecoderFactory> decoder_factory,
-                  absl::optional<AudioCodecPairId> codec_pair_id);
+                  std::optional<AudioCodecPairId> codec_pair_id);
 
   virtual ~DecoderDatabase();
 
@@ -192,7 +192,7 @@
   int active_cng_decoder_type_;
   mutable std::unique_ptr<ComfortNoiseDecoder> active_cng_decoder_;
   scoped_refptr<AudioDecoderFactory> decoder_factory_;
-  const absl::optional<AudioCodecPairId> codec_pair_id_;
+  const std::optional<AudioCodecPairId> codec_pair_id_;
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_coding/neteq/decoder_database_unittest.cc b/modules/audio_coding/neteq/decoder_database_unittest.cc
index 1dd84cf..fe551b6 100644
--- a/modules/audio_coding/neteq/decoder_database_unittest.cc
+++ b/modules/audio_coding/neteq/decoder_database_unittest.cc
@@ -28,16 +28,14 @@
 
 TEST(DecoderDatabase, CreateAndDestroy) {
   DecoderDatabase db(CreateEnvironment(),
-                     make_ref_counted<MockAudioDecoderFactory>(),
-                     absl::nullopt);
+                     make_ref_counted<MockAudioDecoderFactory>(), std::nullopt);
   EXPECT_EQ(0, db.Size());
   EXPECT_TRUE(db.Empty());
 }
 
 TEST(DecoderDatabase, InsertAndRemove) {
   DecoderDatabase db(CreateEnvironment(),
-                     make_ref_counted<MockAudioDecoderFactory>(),
-                     absl::nullopt);
+                     make_ref_counted<MockAudioDecoderFactory>(), std::nullopt);
   const uint8_t kPayloadType = 0;
   const std::string kCodecName = "Robert\'); DROP TABLE Students;";
   EXPECT_EQ(
@@ -52,8 +50,7 @@
 
 TEST(DecoderDatabase, InsertAndRemoveAll) {
   DecoderDatabase db(CreateEnvironment(),
-                     make_ref_counted<MockAudioDecoderFactory>(),
-                     absl::nullopt);
+                     make_ref_counted<MockAudioDecoderFactory>(), std::nullopt);
   const std::string kCodecName1 = "Robert\'); DROP TABLE Students;";
   const std::string kCodecName2 = "https://xkcd.com/327/";
   EXPECT_EQ(DecoderDatabase::kOK,
@@ -75,7 +72,7 @@
         EXPECT_EQ("pcmu", format.name);
         return absl::WrapUnique(decoder);
       }));
-  DecoderDatabase db(CreateEnvironment(), std::move(factory), absl::nullopt);
+  DecoderDatabase db(CreateEnvironment(), std::move(factory), std::nullopt);
   const uint8_t kPayloadType = 0;
   const std::string kCodecName = "pcmu";
   EXPECT_EQ(
@@ -93,7 +90,7 @@
 
 TEST(DecoderDatabase, GetDecoder) {
   DecoderDatabase db(CreateEnvironment(), CreateBuiltinAudioDecoderFactory(),
-                     absl::nullopt);
+                     std::nullopt);
   const uint8_t kPayloadType = 0;
   EXPECT_EQ(DecoderDatabase::kOK,
             db.RegisterPayload(kPayloadType, SdpAudioFormat("l16", 8000, 1)));
@@ -103,8 +100,7 @@
 
 TEST(DecoderDatabase, TypeTests) {
   DecoderDatabase db(CreateEnvironment(),
-                     make_ref_counted<MockAudioDecoderFactory>(),
-                     absl::nullopt);
+                     make_ref_counted<MockAudioDecoderFactory>(), std::nullopt);
   const uint8_t kPayloadTypePcmU = 0;
   const uint8_t kPayloadTypeCng = 13;
   const uint8_t kPayloadTypeDtmf = 100;
@@ -138,8 +134,7 @@
 TEST(DecoderDatabase, CheckPayloadTypes) {
   constexpr int kNumPayloads = 10;
   DecoderDatabase db(CreateEnvironment(),
-                     make_ref_counted<MockAudioDecoderFactory>(),
-                     absl::nullopt);
+                     make_ref_counted<MockAudioDecoderFactory>(), std::nullopt);
   // Load a number of payloads into the database. Payload types are 0, 1, ...,
   // while the decoder type is the same for all payload types (this does not
   // matter for the test).
@@ -181,7 +176,7 @@
 // Test the methods for setting and getting active speech and CNG decoders.
 TEST(DecoderDatabase, IF_ISAC(ActiveDecoders)) {
   DecoderDatabase db(CreateEnvironment(), CreateBuiltinAudioDecoderFactory(),
-                     absl::nullopt);
+                     std::nullopt);
   // Load payload types.
   ASSERT_EQ(DecoderDatabase::kOK,
             db.RegisterPayload(0, SdpAudioFormat("pcmu", 8000, 1)));
diff --git a/modules/audio_coding/neteq/delay_manager.h b/modules/audio_coding/neteq/delay_manager.h
index d678dcf..8cee36a 100644
--- a/modules/audio_coding/neteq/delay_manager.h
+++ b/modules/audio_coding/neteq/delay_manager.h
@@ -15,8 +15,8 @@
 
 #include <deque>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/neteq/tick_timer.h"
 #include "modules/audio_coding/neteq/histogram.h"
@@ -34,8 +34,8 @@
     // Options that can be configured via field trial.
     double quantile = 0.95;
     double forget_factor = 0.983;
-    absl::optional<double> start_forget_weight = 2;
-    absl::optional<int> resample_interval_ms = 500;
+    std::optional<double> start_forget_weight = 2;
+    std::optional<int> resample_interval_ms = 500;
 
     bool use_reorder_optimizer = true;
     double reorder_forget_factor = 0.9993;
diff --git a/modules/audio_coding/neteq/delay_manager_unittest.cc b/modules/audio_coding/neteq/delay_manager_unittest.cc
index 35ae22c..d59a038 100644
--- a/modules/audio_coding/neteq/delay_manager_unittest.cc
+++ b/modules/audio_coding/neteq/delay_manager_unittest.cc
@@ -15,8 +15,8 @@
 #include <math.h>
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "modules/audio_coding/neteq/histogram.h"
 #include "modules/audio_coding/neteq/mock/mock_histogram.h"
 #include "modules/audio_coding/neteq/mock/mock_statistics_calculator.h"
diff --git a/modules/audio_coding/neteq/expand_uma_logger.cc b/modules/audio_coding/neteq/expand_uma_logger.cc
index a91358b..e735a45 100644
--- a/modules/audio_coding/neteq/expand_uma_logger.cc
+++ b/modules/audio_coding/neteq/expand_uma_logger.cc
@@ -47,7 +47,7 @@
   last_value_ = samples;
   sample_rate_hz_ = sample_rate_hz;
   if (!last_logged_value_) {
-    last_logged_value_ = absl::optional<uint64_t>(samples);
+    last_logged_value_ = std::optional<uint64_t>(samples);
   }
 
   if (!timer_->Finished()) {
@@ -58,7 +58,7 @@
   RTC_DCHECK(last_logged_value_);
   RTC_DCHECK_GE(last_value_, *last_logged_value_);
   const uint64_t diff = last_value_ - *last_logged_value_;
-  last_logged_value_ = absl::optional<uint64_t>(last_value_);
+  last_logged_value_ = std::optional<uint64_t>(last_value_);
   // Calculate rate in percent.
   RTC_DCHECK_GT(sample_rate_hz, 0);
   const int rate = (100 * diff) / (sample_rate_hz * logging_period_s_);
diff --git a/modules/audio_coding/neteq/expand_uma_logger.h b/modules/audio_coding/neteq/expand_uma_logger.h
index cc5c20a..d6f8371 100644
--- a/modules/audio_coding/neteq/expand_uma_logger.h
+++ b/modules/audio_coding/neteq/expand_uma_logger.h
@@ -13,10 +13,10 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/neteq/tick_timer.h"
 
 namespace webrtc {
@@ -48,7 +48,7 @@
   const int logging_period_s_;
   const TickTimer& tick_timer_;
   std::unique_ptr<TickTimer::Countdown> timer_;
-  absl::optional<uint64_t> last_logged_value_;
+  std::optional<uint64_t> last_logged_value_;
   uint64_t last_value_ = 0;
   int sample_rate_hz_ = 0;
 };
diff --git a/modules/audio_coding/neteq/histogram.cc b/modules/audio_coding/neteq/histogram.cc
index 4360d1a..825c8ac 100644
--- a/modules/audio_coding/neteq/histogram.cc
+++ b/modules/audio_coding/neteq/histogram.cc
@@ -13,8 +13,8 @@
 #include <algorithm>
 #include <cstdlib>
 #include <numeric>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_conversions.h"
 
@@ -22,7 +22,7 @@
 
 Histogram::Histogram(size_t num_buckets,
                      int forget_factor,
-                     absl::optional<double> start_forget_weight)
+                     std::optional<double> start_forget_weight)
     : buckets_(num_buckets, 0),
       forget_factor_(0),
       base_forget_factor_(forget_factor),
diff --git a/modules/audio_coding/neteq/histogram.h b/modules/audio_coding/neteq/histogram.h
index 265a10e..169eb33 100644
--- a/modules/audio_coding/neteq/histogram.h
+++ b/modules/audio_coding/neteq/histogram.h
@@ -13,10 +13,9 @@
 
 #include <string.h>  // Provide access to size_t.
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
-
 namespace webrtc {
 
 class Histogram {
@@ -24,7 +23,7 @@
   // Creates histogram with capacity `num_buckets` and `forget_factor` in Q15.
   Histogram(size_t num_buckets,
             int forget_factor,
-            absl::optional<double> start_forget_weight = absl::nullopt);
+            std::optional<double> start_forget_weight = std::nullopt);
 
   virtual ~Histogram();
 
@@ -47,7 +46,7 @@
   // Accessors only intended for testing purposes.
   int base_forget_factor_for_testing() const { return base_forget_factor_; }
   int forget_factor_for_testing() const { return forget_factor_; }
-  absl::optional<double> start_forget_weight_for_testing() const {
+  std::optional<double> start_forget_weight_for_testing() const {
     return start_forget_weight_;
   }
 
@@ -56,7 +55,7 @@
   int forget_factor_;  // Q15
   const int base_forget_factor_;
   int add_count_;
-  const absl::optional<double> start_forget_weight_;
+  const std::optional<double> start_forget_weight_;
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_coding/neteq/mock/mock_decoder_database.h b/modules/audio_coding/neteq/mock/mock_decoder_database.h
index 3adae87..08e1215 100644
--- a/modules/audio_coding/neteq/mock/mock_decoder_database.h
+++ b/modules/audio_coding/neteq/mock/mock_decoder_database.h
@@ -24,7 +24,7 @@
   MockDecoderDatabase()
       : DecoderDatabase(CreateEnvironment(),
                         /*decoder_factory=*/nullptr,
-                        /*codec_pair_id=*/absl::nullopt) {}
+                        /*codec_pair_id=*/std::nullopt) {}
   ~MockDecoderDatabase() override { Die(); }
   MOCK_METHOD(void, Die, ());
   MOCK_METHOD(bool, Empty, (), (const, override));
diff --git a/modules/audio_coding/neteq/mock/mock_neteq_controller.h b/modules/audio_coding/neteq/mock/mock_neteq_controller.h
index dc5cab4..ea7809a 100644
--- a/modules/audio_coding/neteq/mock/mock_neteq_controller.h
+++ b/modules/audio_coding/neteq/mock/mock_neteq_controller.h
@@ -39,7 +39,7 @@
   MOCK_METHOD(void, ExpandDecision, (NetEq::Operation operation), (override));
   MOCK_METHOD(void, AddSampleMemory, (int32_t value), (override));
   MOCK_METHOD(int, TargetLevelMs, (), (const, override));
-  MOCK_METHOD(absl::optional<int>,
+  MOCK_METHOD(std::optional<int>,
               PacketArrived,
               (int fs_hz,
                bool should_update_stats,
diff --git a/modules/audio_coding/neteq/mock/mock_packet_buffer.h b/modules/audio_coding/neteq/mock/mock_packet_buffer.h
index fa44f60..85bc82b 100644
--- a/modules/audio_coding/neteq/mock/mock_packet_buffer.h
+++ b/modules/audio_coding/neteq/mock/mock_packet_buffer.h
@@ -36,7 +36,7 @@
               (uint32_t timestamp, uint32_t* next_timestamp),
               (const, override));
   MOCK_METHOD(const Packet*, PeekNextPacket, (), (const, override));
-  MOCK_METHOD(absl::optional<Packet>, GetNextPacket, (), (override));
+  MOCK_METHOD(std::optional<Packet>, GetNextPacket, (), (override));
   MOCK_METHOD(int, DiscardNextPacket, (), (override));
   MOCK_METHOD(void,
               DiscardOldPackets,
diff --git a/modules/audio_coding/neteq/nack_tracker.cc b/modules/audio_coding/neteq/nack_tracker.cc
index a1e973b..f6f6b80 100644
--- a/modules/audio_coding/neteq/nack_tracker.cc
+++ b/modules/audio_coding/neteq/nack_tracker.cc
@@ -98,7 +98,7 @@
   LimitNackListSize();
 }
 
-absl::optional<int> NackTracker::GetSamplesPerPacket(
+std::optional<int> NackTracker::GetSamplesPerPacket(
     uint16_t sequence_number_current_received_rtp,
     uint32_t timestamp_current_received_rtp) const {
   uint32_t timestamp_increase =
@@ -110,7 +110,7 @@
   if (samples_per_packet == 0 ||
       samples_per_packet > kMaxPacketSizeMs * sample_rate_khz_) {
     // Not a valid samples per packet.
-    return absl::nullopt;
+    return std::nullopt;
   }
   return samples_per_packet;
 }
@@ -125,7 +125,7 @@
              IsNewerSequenceNumber(sequence_number_current_received_rtp,
                                    sequence_num_last_decoded_rtp_));
 
-  absl::optional<int> samples_per_packet = GetSamplesPerPacket(
+  std::optional<int> samples_per_packet = GetSamplesPerPacket(
       sequence_number_current_received_rtp, timestamp_current_received_rtp);
   if (!samples_per_packet) {
     return;
diff --git a/modules/audio_coding/neteq/nack_tracker.h b/modules/audio_coding/neteq/nack_tracker.h
index c95496d..a11f483 100644
--- a/modules/audio_coding/neteq/nack_tracker.h
+++ b/modules/audio_coding/neteq/nack_tracker.h
@@ -15,9 +15,9 @@
 #include <stdint.h>
 
 #include <map>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "modules/include/module_common_types_public.h"
 #include "rtc_base/gtest_prod_util.h"
@@ -151,7 +151,7 @@
 
   // Returns a valid number of samples per packet given the current received
   // sequence number and timestamp or nullopt of none could be computed.
-  absl::optional<int> GetSamplesPerPacket(
+  std::optional<int> GetSamplesPerPacket(
       uint16_t sequence_number_current_received_rtp,
       uint32_t timestamp_current_received_rtp) const;
 
diff --git a/modules/audio_coding/neteq/neteq_decoder_plc_unittest.cc b/modules/audio_coding/neteq/neteq_decoder_plc_unittest.cc
index ec6ade9..223dfe4 100644
--- a/modules/audio_coding/neteq/neteq_decoder_plc_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_decoder_plc_unittest.cc
@@ -11,10 +11,10 @@
 // Test to verify correct operation when using the decoder-internal PLC.
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h"
 #include "modules/audio_coding/neteq/tools/audio_checksum.h"
 #include "modules/audio_coding/neteq/tools/audio_sink.h"
@@ -119,15 +119,15 @@
         burst_length_(burst_length),
         input_(std::move(input)) {}
 
-  absl::optional<int64_t> NextPacketTime() const override {
+  std::optional<int64_t> NextPacketTime() const override {
     return input_->NextPacketTime();
   }
 
-  absl::optional<int64_t> NextOutputEventTime() const override {
+  std::optional<int64_t> NextOutputEventTime() const override {
     return input_->NextOutputEventTime();
   }
 
-  absl::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override {
+  std::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override {
     return input_->NextSetMinimumDelayInfo();
   }
 
@@ -151,7 +151,7 @@
 
   bool ended() const override { return input_->ended(); }
 
-  absl::optional<RTPHeader> NextHeader() const override {
+  std::optional<RTPHeader> NextHeader() const override {
     return input_->NextHeader();
   }
 
diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc
index a93954f..3507510 100644
--- a/modules/audio_coding/neteq/neteq_impl.cc
+++ b/modules/audio_coding/neteq/neteq_impl.cc
@@ -201,7 +201,7 @@
 int NetEqImpl::GetAudio(AudioFrame* audio_frame,
                         bool* muted,
                         int* current_sample_rate_hz,
-                        absl::optional<Operation> action_override) {
+                        std::optional<Operation> action_override) {
   TRACE_EVENT0("webrtc", "NetEqImpl::GetAudio");
   MutexLock lock(&mutex_);
   if (GetAudioInternal(audio_frame, action_override) != 0) {
@@ -357,14 +357,14 @@
   return result;
 }
 
-absl::optional<uint32_t> NetEqImpl::GetPlayoutTimestamp() const {
+std::optional<uint32_t> NetEqImpl::GetPlayoutTimestamp() const {
   MutexLock lock(&mutex_);
   if (first_packet_ || last_mode_ == Mode::kRfc3389Cng ||
       last_mode_ == Mode::kCodecInternalCng) {
     // We don't have a valid RTP timestamp until we have decoded our first
     // RTP packet. Also, the RTP timestamp is not accurate while playing CNG,
     // which is indicated by returning an empty value.
-    return absl::nullopt;
+    return std::nullopt;
   }
   return timestamp_scaler_->ToExternal(playout_timestamp_);
 }
@@ -374,16 +374,15 @@
   return last_output_sample_rate_hz_;
 }
 
-absl::optional<NetEq::DecoderFormat> NetEqImpl::GetCurrentDecoderFormat()
-    const {
+std::optional<NetEq::DecoderFormat> NetEqImpl::GetCurrentDecoderFormat() const {
   MutexLock lock(&mutex_);
   if (!current_rtp_payload_type_.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   const DecoderDatabase::DecoderInfo* di =
       decoder_database_->GetDecoderInfo(*current_rtp_payload_type_);
   if (di == nullptr) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return DecoderFormat{
       /*payload_type=*/*current_rtp_payload_type_,
@@ -713,7 +712,7 @@
     if (current_cng_rtp_payload_type_ &&
         *current_cng_rtp_payload_type_ != payload_type) {
       // New CNG payload type implies new codec type.
-      current_rtp_payload_type_ = absl::nullopt;
+      current_rtp_payload_type_ = std::nullopt;
       changed = true;
     }
     current_cng_rtp_payload_type_ = payload_type;
@@ -724,7 +723,7 @@
         (current_cng_rtp_payload_type_ &&
          !EqualSampleRates(payload_type, *current_cng_rtp_payload_type_,
                            *decoder_database_))) {
-      current_cng_rtp_payload_type_ = absl::nullopt;
+      current_cng_rtp_payload_type_ = std::nullopt;
       changed = true;
     }
     current_rtp_payload_type_ = payload_type;
@@ -733,7 +732,7 @@
 }
 
 int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame,
-                                absl::optional<Operation> action_override) {
+                                std::optional<Operation> action_override) {
   PacketList packet_list;
   DtmfEvent dtmf_event;
   Operation operation;
@@ -987,7 +986,7 @@
                            PacketList* packet_list,
                            DtmfEvent* dtmf_event,
                            bool* play_dtmf,
-                           absl::optional<Operation> action_override) {
+                           std::optional<Operation> action_override) {
   // Initialize output variables.
   *play_dtmf = false;
   *operation = Operation::kUndefined;
@@ -1912,7 +1911,7 @@
   // Packet extraction loop.
   do {
     timestamp_ = next_packet->timestamp;
-    absl::optional<Packet> packet = packet_buffer_->GetNextPacket();
+    std::optional<Packet> packet = packet_buffer_->GetNextPacket();
     // `next_packet` may be invalid after the `packet_buffer_` operation.
     next_packet = nullptr;
     if (!packet) {
@@ -1980,7 +1979,7 @@
         !has_cng_packet;
 
     packet_list->push_back(std::move(*packet));  // Store packet in list.
-    packet = absl::nullopt;  // Ensure it's never used after the move.
+    packet = std::nullopt;  // Ensure it's never used after the move.
   } while (extracted_samples < required_samples && next_packet_available);
 
   if (extracted_samples > 0) {
diff --git a/modules/audio_coding/neteq/neteq_impl.h b/modules/audio_coding/neteq/neteq_impl.h
index 0ce80b7..2571927 100644
--- a/modules/audio_coding/neteq/neteq_impl.h
+++ b/modules/audio_coding/neteq/neteq_impl.h
@@ -18,7 +18,6 @@
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_frame.h"
 #include "api/environment/environment.h"
 #include "api/neteq/neteq.h"
@@ -138,7 +137,7 @@
       AudioFrame* audio_frame,
       bool* muted = nullptr,
       int* current_sample_rate_hz = nullptr,
-      absl::optional<Operation> action_override = absl::nullopt) override;
+      std::optional<Operation> action_override = std::nullopt) override;
 
   void SetCodecs(const std::map<int, SdpAudioFormat>& codecs) override;
 
@@ -173,11 +172,11 @@
 
   NetEqOperationsAndState GetOperationsAndState() const override;
 
-  absl::optional<uint32_t> GetPlayoutTimestamp() const override;
+  std::optional<uint32_t> GetPlayoutTimestamp() const override;
 
   int last_output_sample_rate_hz() const override;
 
-  absl::optional<DecoderFormat> GetCurrentDecoderFormat() const override;
+  std::optional<DecoderFormat> GetCurrentDecoderFormat() const override;
 
   // Flushes both the packet buffer and the sync buffer.
   void FlushBuffers() override;
@@ -219,7 +218,7 @@
   // Delivers 10 ms of audio data. The data is written to `audio_frame`.
   // Returns 0 on success, otherwise an error code.
   int GetAudioInternal(AudioFrame* audio_frame,
-                       absl::optional<Operation> action_override)
+                       std::optional<Operation> action_override)
       RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 
   // Provides a decision to the GetAudioInternal method. The decision what to
@@ -231,7 +230,7 @@
                   PacketList* packet_list,
                   DtmfEvent* dtmf_event,
                   bool* play_dtmf,
-                  absl::optional<Operation> action_override)
+                  std::optional<Operation> action_override)
       RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 
   // Decodes the speech packets in `packet_list`, and writes the results to
@@ -378,7 +377,7 @@
   size_t decoder_frame_length_ RTC_GUARDED_BY(mutex_);
   Mode last_mode_ RTC_GUARDED_BY(mutex_);
   Operation last_operation_ RTC_GUARDED_BY(mutex_);
-  absl::optional<AudioDecoder::SpeechType> last_decoded_type_
+  std::optional<AudioDecoder::SpeechType> last_decoded_type_
       RTC_GUARDED_BY(mutex_);
   size_t decoded_buffer_length_ RTC_GUARDED_BY(mutex_);
   std::unique_ptr<int16_t[]> decoded_buffer_ RTC_GUARDED_BY(mutex_);
@@ -386,8 +385,8 @@
   bool new_codec_ RTC_GUARDED_BY(mutex_);
   uint32_t timestamp_ RTC_GUARDED_BY(mutex_);
   bool reset_decoder_ RTC_GUARDED_BY(mutex_);
-  absl::optional<uint8_t> current_rtp_payload_type_ RTC_GUARDED_BY(mutex_);
-  absl::optional<uint8_t> current_cng_rtp_payload_type_ RTC_GUARDED_BY(mutex_);
+  std::optional<uint8_t> current_rtp_payload_type_ RTC_GUARDED_BY(mutex_);
+  std::optional<uint8_t> current_cng_rtp_payload_type_ RTC_GUARDED_BY(mutex_);
   bool first_packet_ RTC_GUARDED_BY(mutex_);
   bool enable_fast_accelerate_ RTC_GUARDED_BY(mutex_);
   std::unique_ptr<NackTracker> nack_ RTC_GUARDED_BY(mutex_);
diff --git a/modules/audio_coding/neteq/neteq_impl_unittest.cc b/modules/audio_coding/neteq/neteq_impl_unittest.cc
index 561a10e..740d969 100644
--- a/modules/audio_coding/neteq/neteq_impl_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_impl_unittest.cc
@@ -320,7 +320,7 @@
         return mock_decoder;
       }));
   DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("pcmu", 8000, 1),
-                                    absl::nullopt, mock_decoder_factory.get());
+                                    std::nullopt, mock_decoder_factory.get());
 
   // Expectations for decoder database.
   EXPECT_CALL(*mock_decoder_database_, GetDecoderInfo(kPayloadType))
@@ -532,10 +532,10 @@
   // The value of the last of the output samples is the same as the number of
   // samples played from the decoded packet. Thus, this number + the RTP
   // timestamp should match the playout timestamp.
-  // Wrap the expected value in an absl::optional to compare them as such.
+  // Wrap the expected value in an std::optional to compare them as such.
   EXPECT_EQ(
-      absl::optional<uint32_t>(rtp_header.timestamp +
-                               output.data()[output.samples_per_channel_ - 1]),
+      std::optional<uint32_t>(rtp_header.timestamp +
+                              output.data()[output.samples_per_channel_ - 1]),
       neteq_->GetPlayoutTimestamp());
 
   // Check the timestamp for the last value in the sync buffer. This should
@@ -1652,7 +1652,7 @@
         return dec;
       }));
   DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("pcmu", 8000, 1),
-                                    absl::nullopt, mock_decoder_factory.get());
+                                    std::nullopt, mock_decoder_factory.get());
   // Expectations for decoder database.
   EXPECT_CALL(*mock_decoder_database_, GetDecoderInfo(kPayloadType))
       .WillRepeatedly(Return(&info));
@@ -1734,7 +1734,7 @@
   header.timestamp = 1234;
   uint8_t payload[160] = {0};
 
-  absl::optional<NetEq::DecoderFormat> decoder =
+  std::optional<NetEq::DecoderFormat> decoder =
       neteq_->GetCurrentDecoderFormat();
   EXPECT_FALSE(decoder.has_value());
 
diff --git a/modules/audio_coding/neteq/neteq_network_stats_unittest.cc b/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
index 171bcae..a145bbb 100644
--- a/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
@@ -58,7 +58,7 @@
 
     size_t Duration() const override { return kPacketDuration; }
 
-    absl::optional<DecodeResult> Decode(
+    std::optional<DecodeResult> Decode(
         rtc::ArrayView<int16_t> decoded) const override {
       const size_t output_size =
           sizeof(int16_t) * kPacketDuration * num_channels_;
@@ -69,7 +69,7 @@
       } else {
         ADD_FAILURE() << "Expected decoded.size() to be >= output_size ("
                       << decoded.size() << " vs. " << output_size << ")";
-        return absl::nullopt;
+        return std::nullopt;
       }
     }
 
diff --git a/modules/audio_coding/neteq/neteq_unittest.cc b/modules/audio_coding/neteq/neteq_unittest.cc
index 2ddd9e3..1fc9710 100644
--- a/modules/audio_coding/neteq/neteq_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_unittest.cc
@@ -513,7 +513,7 @@
   ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted));
   ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
   EXPECT_EQ(AudioFrame::kNormalSpeech, out_frame_.speech_type_);
-  absl::optional<uint32_t> playout_timestamp = neteq_->GetPlayoutTimestamp();
+  std::optional<uint32_t> playout_timestamp = neteq_->GetPlayoutTimestamp();
   ASSERT_TRUE(playout_timestamp);
   EXPECT_EQ(first_speech_timestamp + kSamples - algorithmic_delay_samples,
             *playout_timestamp);
@@ -1005,7 +1005,7 @@
       {8, kRtpExtensionVideoTiming}};
   std::unique_ptr<NetEqInput> input = CreateNetEqRtpDumpInput(
       webrtc::test::ResourcePath("audio_coding/neteq_universal_new", "rtp"),
-      rtp_ext_map, absl::nullopt /*No SSRC filter*/);
+      rtp_ext_map, std::nullopt /*No SSRC filter*/);
   std::unique_ptr<TimeLimitedNetEqInput> input_time_limit(
       new TimeLimitedNetEqInput(std::move(input), 20000));
   std::unique_ptr<AudioSink> output(new VoidAudioSink);
diff --git a/modules/audio_coding/neteq/packet.h b/modules/audio_coding/neteq/packet.h
index 795c36d..9a1f919 100644
--- a/modules/audio_coding/neteq/packet.h
+++ b/modules/audio_coding/neteq/packet.h
@@ -74,7 +74,7 @@
   // Datagram excluding RTP header and header extension.
   rtc::Buffer payload;
   Priority priority;
-  absl::optional<RtpPacketInfo> packet_info;
+  std::optional<RtpPacketInfo> packet_info;
   std::unique_ptr<TickTimer::Stopwatch> waiting_time;
   std::unique_ptr<AudioDecoder::EncodedAudioFrame> frame;
 
diff --git a/modules/audio_coding/neteq/packet_buffer.cc b/modules/audio_coding/neteq/packet_buffer.cc
index 2abbbd9d..bcc6a85 100644
--- a/modules/audio_coding/neteq/packet_buffer.cc
+++ b/modules/audio_coding/neteq/packet_buffer.cc
@@ -151,13 +151,13 @@
   return buffer_.empty() ? nullptr : &buffer_.front();
 }
 
-absl::optional<Packet> PacketBuffer::GetNextPacket() {
+std::optional<Packet> PacketBuffer::GetNextPacket() {
   if (Empty()) {
     // Buffer is empty.
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  absl::optional<Packet> packet(std::move(buffer_.front()));
+  std::optional<Packet> packet(std::move(buffer_.front()));
   // Assert that the packet sanity checks in InsertPacket method works.
   RTC_DCHECK(!packet->empty());
   buffer_.pop_front();
diff --git a/modules/audio_coding/neteq/packet_buffer.h b/modules/audio_coding/neteq/packet_buffer.h
index 795dd4e..547e993 100644
--- a/modules/audio_coding/neteq/packet_buffer.h
+++ b/modules/audio_coding/neteq/packet_buffer.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_
 #define MODULES_AUDIO_CODING_NETEQ_PACKET_BUFFER_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/audio_coding/neteq/decoder_database.h"
 #include "modules/audio_coding/neteq/packet.h"
 #include "modules/include/module_common_types_public.h"  // IsNewerTimestamp
@@ -78,7 +79,7 @@
 
   // Extracts the first packet in the buffer and returns it.
   // Returns an empty optional if the buffer is empty.
-  virtual absl::optional<Packet> GetNextPacket();
+  virtual std::optional<Packet> GetNextPacket();
 
   // Discards the first packet in the buffer. The packet is deleted.
   // Returns PacketBuffer::kBufferEmpty if the buffer is empty,
diff --git a/modules/audio_coding/neteq/packet_buffer_unittest.cc b/modules/audio_coding/neteq/packet_buffer_unittest.cc
index 8f307a9..5bdb47d 100644
--- a/modules/audio_coding/neteq/packet_buffer_unittest.cc
+++ b/modules/audio_coding/neteq/packet_buffer_unittest.cc
@@ -36,7 +36,7 @@
 
   MOCK_METHOD(bool, IsDtxPacket, (), (const, override));
 
-  MOCK_METHOD(absl::optional<DecodeResult>,
+  MOCK_METHOD(std::optional<DecodeResult>,
               Decode,
               (rtc::ArrayView<int16_t> decoded),
               (const, override));
@@ -253,7 +253,7 @@
   EXPECT_EQ(kExpectPacketsInBuffer, buffer.NumPacketsInBuffer());
 
   for (size_t i = 0; i < kExpectPacketsInBuffer; ++i) {
-    const absl::optional<Packet> packet = buffer.GetNextPacket();
+    const std::optional<Packet> packet = buffer.GetNextPacket();
     EXPECT_EQ(packet, expect_order[i]);  // Compare contents.
   }
   EXPECT_TRUE(buffer.Empty());
@@ -356,7 +356,7 @@
   // Extract them and make sure that come out in the right order.
   uint32_t current_ts = start_ts;
   for (int i = 0; i < 10; ++i) {
-    const absl::optional<Packet> packet = buffer.GetNextPacket();
+    const std::optional<Packet> packet = buffer.GetNextPacket();
     ASSERT_TRUE(packet);
     EXPECT_EQ(current_ts, packet->timestamp);
     current_ts += ts_increment;
diff --git a/modules/audio_coding/neteq/red_payload_splitter_unittest.cc b/modules/audio_coding/neteq/red_payload_splitter_unittest.cc
index 5e84c75..8a17d85 100644
--- a/modules/audio_coding/neteq/red_payload_splitter_unittest.cc
+++ b/modules/audio_coding/neteq/red_payload_splitter_unittest.cc
@@ -299,7 +299,7 @@
   // easier to just register the payload types and let the actual implementation
   // do its job.
   DecoderDatabase decoder_database(
-      env, make_ref_counted<MockAudioDecoderFactory>(), absl::nullopt);
+      env, make_ref_counted<MockAudioDecoderFactory>(), std::nullopt);
   decoder_database.RegisterPayload(0, SdpAudioFormat("cn", 8000, 1));
   decoder_database.RegisterPayload(1, SdpAudioFormat("pcmu", 8000, 1));
   decoder_database.RegisterPayload(2,
@@ -335,7 +335,7 @@
   // easier to just register the payload types and let the actual implementation
   // do its job.
   DecoderDatabase decoder_database(
-      env, make_ref_counted<MockAudioDecoderFactory>(), absl::nullopt);
+      env, make_ref_counted<MockAudioDecoderFactory>(), std::nullopt);
   decoder_database.RegisterPayload(kRedPayloadType,
                                    SdpAudioFormat("red", 8000, 1));
 
diff --git a/modules/audio_coding/neteq/reorder_optimizer.cc b/modules/audio_coding/neteq/reorder_optimizer.cc
index f6e073f..be96de1 100644
--- a/modules/audio_coding/neteq/reorder_optimizer.cc
+++ b/modules/audio_coding/neteq/reorder_optimizer.cc
@@ -25,7 +25,7 @@
 
 ReorderOptimizer::ReorderOptimizer(int forget_factor,
                                    int ms_per_loss_percent,
-                                   absl::optional<int> start_forget_weight)
+                                   std::optional<int> start_forget_weight)
     : histogram_(kDelayBuckets, forget_factor, start_forget_weight),
       ms_per_loss_percent_(ms_per_loss_percent) {}
 
diff --git a/modules/audio_coding/neteq/reorder_optimizer.h b/modules/audio_coding/neteq/reorder_optimizer.h
index 06f6bc7..3c5e8fa 100644
--- a/modules/audio_coding/neteq/reorder_optimizer.h
+++ b/modules/audio_coding/neteq/reorder_optimizer.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_REORDER_OPTIMIZER_H_
 #define MODULES_AUDIO_CODING_NETEQ_REORDER_OPTIMIZER_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/audio_coding/neteq/histogram.h"
 
 namespace webrtc {
@@ -23,11 +24,11 @@
  public:
   ReorderOptimizer(int forget_factor,
                    int ms_per_loss_percent,
-                   absl::optional<int> start_forget_weight);
+                   std::optional<int> start_forget_weight);
 
   void Update(int relative_delay_ms, bool reordered, int base_delay_ms);
 
-  absl::optional<int> GetOptimalDelayMs() const { return optimal_delay_ms_; }
+  std::optional<int> GetOptimalDelayMs() const { return optimal_delay_ms_; }
 
   void Reset();
 
@@ -36,7 +37,7 @@
 
   Histogram histogram_;
   const int ms_per_loss_percent_;
-  absl::optional<int> optimal_delay_ms_;
+  std::optional<int> optimal_delay_ms_;
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_coding/neteq/test/neteq_decoding_test.cc b/modules/audio_coding/neteq/test/neteq_decoding_test.cc
index b5f7919..a817276 100644
--- a/modules/audio_coding/neteq/test/neteq_decoding_test.cc
+++ b/modules/audio_coding/neteq/test/neteq_decoding_test.cc
@@ -269,7 +269,7 @@
     ASSERT_EQ(1u, output.num_channels_);
 
     // Expect delay (in samples) to be less than 2 packets.
-    absl::optional<uint32_t> playout_timestamp = neteq_->GetPlayoutTimestamp();
+    std::optional<uint32_t> playout_timestamp = neteq_->GetPlayoutTimestamp();
     ASSERT_TRUE(playout_timestamp);
     EXPECT_LE(timestamp - *playout_timestamp,
               static_cast<uint32_t>(kSamples * 2));
@@ -314,7 +314,7 @@
   }
 
   EXPECT_EQ(AudioFrame::kNormalSpeech, out_frame_.speech_type_);
-  absl::optional<uint32_t> playout_timestamp = neteq_->GetPlayoutTimestamp();
+  std::optional<uint32_t> playout_timestamp = neteq_->GetPlayoutTimestamp();
   ASSERT_TRUE(playout_timestamp);
   int32_t delay_before = timestamp - *playout_timestamp;
 
diff --git a/modules/audio_coding/neteq/timestamp_scaler_unittest.cc b/modules/audio_coding/neteq/timestamp_scaler_unittest.cc
index 804e4d8..e880004 100644
--- a/modules/audio_coding/neteq/timestamp_scaler_unittest.cc
+++ b/modules/audio_coding/neteq/timestamp_scaler_unittest.cc
@@ -30,7 +30,7 @@
   auto factory = CreateBuiltinAudioDecoderFactory();
   // Use PCMu, because it doesn't use scaled timestamps.
   const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("pcmu", 8000, 1),
-                                          absl::nullopt, factory.get());
+                                          std::nullopt, factory.get());
   static const uint8_t kRtpPayloadType = 0;
   EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
       .WillRepeatedly(Return(&info));
@@ -53,7 +53,7 @@
   auto factory = CreateBuiltinAudioDecoderFactory();
   // Use PCMu, because it doesn't use scaled timestamps.
   const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("pcmu", 8000, 1),
-                                          absl::nullopt, factory.get());
+                                          std::nullopt, factory.get());
   static const uint8_t kRtpPayloadType = 0;
   EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
       .WillRepeatedly(Return(&info));
@@ -81,7 +81,7 @@
   auto factory = CreateBuiltinAudioDecoderFactory();
   // Use G722, which has a factor 2 scaling.
   const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("g722", 8000, 1),
-                                          absl::nullopt, factory.get());
+                                          std::nullopt, factory.get());
   static const uint8_t kRtpPayloadType = 17;
   EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
       .WillRepeatedly(Return(&info));
@@ -108,7 +108,7 @@
   auto factory = CreateBuiltinAudioDecoderFactory();
   // Use G722, which has a factor 2 scaling.
   const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("g722", 8000, 1),
-                                          absl::nullopt, factory.get());
+                                          std::nullopt, factory.get());
   static const uint8_t kRtpPayloadType = 17;
   EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
       .WillRepeatedly(Return(&info));
@@ -139,9 +139,9 @@
   auto factory = CreateBuiltinAudioDecoderFactory();
   // Use G722, which has a factor 2 scaling.
   const DecoderDatabase::DecoderInfo info_g722(
-      env, SdpAudioFormat("g722", 8000, 1), absl::nullopt, factory.get());
+      env, SdpAudioFormat("g722", 8000, 1), std::nullopt, factory.get());
   const DecoderDatabase::DecoderInfo info_cng(
-      env, SdpAudioFormat("cn", 16000, 1), absl::nullopt, factory.get());
+      env, SdpAudioFormat("cn", 16000, 1), std::nullopt, factory.get());
   static const uint8_t kRtpPayloadTypeG722 = 17;
   static const uint8_t kRtpPayloadTypeCng = 13;
   EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadTypeG722))
@@ -184,7 +184,7 @@
   auto factory = CreateBuiltinAudioDecoderFactory();
   // Use G722, which has a factor 2 scaling.
   const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("g722", 8000, 1),
-                                          absl::nullopt, factory.get());
+                                          std::nullopt, factory.get());
   static const uint8_t kRtpPayloadType = 17;
   EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
       .WillRepeatedly(Return(&info));
@@ -215,7 +215,7 @@
   auto factory = CreateBuiltinAudioDecoderFactory();
   // Use G722, which has a factor 2 scaling.
   const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("g722", 8000, 1),
-                                          absl::nullopt, factory.get());
+                                          std::nullopt, factory.get());
   static const uint8_t kRtpPayloadType = 17;
   EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
       .WillRepeatedly(Return(&info));
@@ -250,7 +250,7 @@
   auto factory = CreateBuiltinAudioDecoderFactory();
   // Use G722, which has a factor 2 scaling.
   const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("g722", 8000, 1),
-                                          absl::nullopt, factory.get());
+                                          std::nullopt, factory.get());
   static const uint8_t kRtpPayloadType = 17;
   EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
       .WillRepeatedly(Return(&info));
@@ -292,7 +292,7 @@
   MockDecoderDatabase db;
   auto factory = CreateBuiltinAudioDecoderFactory();
   const DecoderDatabase::DecoderInfo info(env, SdpAudioFormat("opus", 48000, 2),
-                                          absl::nullopt, factory.get());
+                                          std::nullopt, factory.get());
   static const uint8_t kRtpPayloadType = 17;
   EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
       .WillRepeatedly(Return(&info));
diff --git a/modules/audio_coding/neteq/tools/encode_neteq_input.cc b/modules/audio_coding/neteq/tools/encode_neteq_input.cc
index 87b987d..f0c9102 100644
--- a/modules/audio_coding/neteq/tools/encode_neteq_input.cc
+++ b/modules/audio_coding/neteq/tools/encode_neteq_input.cc
@@ -29,12 +29,12 @@
 
 EncodeNetEqInput::~EncodeNetEqInput() = default;
 
-absl::optional<int64_t> EncodeNetEqInput::NextPacketTime() const {
+std::optional<int64_t> EncodeNetEqInput::NextPacketTime() const {
   RTC_DCHECK(packet_data_);
   return static_cast<int64_t>(packet_data_->time_ms);
 }
 
-absl::optional<int64_t> EncodeNetEqInput::NextOutputEventTime() const {
+std::optional<int64_t> EncodeNetEqInput::NextOutputEventTime() const {
   return next_output_event_ms_;
 }
 
@@ -56,7 +56,7 @@
   return next_output_event_ms_ > input_duration_ms_;
 }
 
-absl::optional<RTPHeader> EncodeNetEqInput::NextHeader() const {
+std::optional<RTPHeader> EncodeNetEqInput::NextHeader() const {
   RTC_DCHECK(packet_data_);
   return packet_data_->header;
 }
diff --git a/modules/audio_coding/neteq/tools/encode_neteq_input.h b/modules/audio_coding/neteq/tools/encode_neteq_input.h
index f2ed4b1..a92d1b1 100644
--- a/modules/audio_coding/neteq/tools/encode_neteq_input.h
+++ b/modules/audio_coding/neteq/tools/encode_neteq_input.h
@@ -37,12 +37,12 @@
                    int64_t input_duration_ms);
   ~EncodeNetEqInput() override;
 
-  absl::optional<int64_t> NextPacketTime() const override;
+  std::optional<int64_t> NextPacketTime() const override;
 
-  absl::optional<int64_t> NextOutputEventTime() const override;
+  std::optional<int64_t> NextOutputEventTime() const override;
 
-  absl::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override {
-    return absl::nullopt;
+  std::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override {
+    return std::nullopt;
   }
 
   std::unique_ptr<PacketData> PopPacket() override;
@@ -53,7 +53,7 @@
 
   bool ended() const override;
 
-  absl::optional<RTPHeader> NextHeader() const override;
+  std::optional<RTPHeader> NextHeader() const override;
 
  private:
   static constexpr int64_t kOutputPeriodMs = 10;
diff --git a/modules/audio_coding/neteq/tools/fake_decode_from_file.cc b/modules/audio_coding/neteq/tools/fake_decode_from_file.cc
index ad52239..bd6c204 100644
--- a/modules/audio_coding/neteq/tools/fake_decode_from_file.cc
+++ b/modules/audio_coding/neteq/tools/fake_decode_from_file.cc
@@ -32,7 +32,7 @@
 
   size_t Duration() const override { return duration_; }
 
-  absl::optional<DecodeResult> Decode(
+  std::optional<DecodeResult> Decode(
       rtc::ArrayView<int16_t> decoded) const override {
     if (is_dtx_) {
       std::fill_n(decoded.data(), duration_, 0);
diff --git a/modules/audio_coding/neteq/tools/fake_decode_from_file.h b/modules/audio_coding/neteq/tools/fake_decode_from_file.h
index 050a29d..e62950a 100644
--- a/modules/audio_coding/neteq/tools/fake_decode_from_file.h
+++ b/modules/audio_coding/neteq/tools/fake_decode_from_file.h
@@ -12,8 +12,8 @@
 #define MODULES_AUDIO_CODING_NETEQ_TOOLS_FAKE_DECODE_FROM_FILE_H_
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "modules/audio_coding/neteq/tools/input_audio_file.h"
@@ -67,7 +67,7 @@
 
  private:
   std::unique_ptr<InputAudioFile> input_;
-  absl::optional<uint32_t> next_timestamp_from_input_;
+  std::optional<uint32_t> next_timestamp_from_input_;
   const int sample_rate_hz_;
   const bool stereo_;
 };
diff --git a/modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.cc b/modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.cc
index 763078e..b41d773 100644
--- a/modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.cc
+++ b/modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.cc
@@ -27,17 +27,16 @@
       packets_to_insert_(number_of_initial_packets),
       sample_rate_hz_(sample_rate_hz) {}
 
-absl::optional<int64_t> InitialPacketInserterNetEqInput::NextPacketTime()
-    const {
+std::optional<int64_t> InitialPacketInserterNetEqInput::NextPacketTime() const {
   return source_->NextPacketTime();
 }
 
-absl::optional<int64_t> InitialPacketInserterNetEqInput::NextOutputEventTime()
+std::optional<int64_t> InitialPacketInserterNetEqInput::NextOutputEventTime()
     const {
   return source_->NextOutputEventTime();
 }
 
-absl::optional<NetEqInput::SetMinimumDelayInfo>
+std::optional<NetEqInput::SetMinimumDelayInfo>
 InitialPacketInserterNetEqInput::NextSetMinimumDelayInfo() const {
   return source_->NextSetMinimumDelayInfo();
 }
@@ -80,7 +79,7 @@
   return source_->ended();
 }
 
-absl::optional<RTPHeader> InitialPacketInserterNetEqInput::NextHeader() const {
+std::optional<RTPHeader> InitialPacketInserterNetEqInput::NextHeader() const {
   return source_->NextHeader();
 }
 
diff --git a/modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.h b/modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.h
index 7246949..f72c21c 100644
--- a/modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.h
+++ b/modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.h
@@ -27,14 +27,14 @@
   InitialPacketInserterNetEqInput(std::unique_ptr<NetEqInput> source,
                                   int number_of_initial_packets,
                                   int sample_rate_hz);
-  absl::optional<int64_t> NextPacketTime() const override;
-  absl::optional<int64_t> NextOutputEventTime() const override;
-  absl::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override;
+  std::optional<int64_t> NextPacketTime() const override;
+  std::optional<int64_t> NextOutputEventTime() const override;
+  std::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override;
   std::unique_ptr<PacketData> PopPacket() override;
   void AdvanceOutputEvent() override;
   void AdvanceSetMinimumDelay() override;
   bool ended() const override;
-  absl::optional<RTPHeader> NextHeader() const override;
+  std::optional<RTPHeader> NextHeader() const override;
 
  private:
   const std::unique_ptr<NetEqInput> source_;
diff --git a/modules/audio_coding/neteq/tools/neteq_delay_analyzer.h b/modules/audio_coding/neteq/tools/neteq_delay_analyzer.h
index ffcba58..cdf178b 100644
--- a/modules/audio_coding/neteq/tools/neteq_delay_analyzer.h
+++ b/modules/audio_coding/neteq/tools/neteq_delay_analyzer.h
@@ -12,12 +12,12 @@
 #define MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_DELAY_ANALYZER_H_
 
 #include <map>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "modules/audio_coding/neteq/tools/neteq_input.h"
 #include "modules/audio_coding/neteq/tools/neteq_test.h"
 
@@ -57,10 +57,10 @@
   struct TimingData {
     explicit TimingData(int64_t at) : arrival_time_ms(at) {}
     int64_t arrival_time_ms;
-    absl::optional<int64_t> decode_get_audio_count;
-    absl::optional<int64_t> sync_delay_ms;
-    absl::optional<int> target_delay_ms;
-    absl::optional<int> current_delay_ms;
+    std::optional<int64_t> decode_get_audio_count;
+    std::optional<int64_t> sync_delay_ms;
+    std::optional<int> target_delay_ms;
+    std::optional<int> current_delay_ms;
   };
   std::map<uint32_t, TimingData> data_;
   std::vector<int64_t> get_audio_time_ms_;
diff --git a/modules/audio_coding/neteq/tools/neteq_event_log_input.cc b/modules/audio_coding/neteq/tools/neteq_event_log_input.cc
index 0ca855b..d42a31b 100644
--- a/modules/audio_coding/neteq/tools/neteq_event_log_input.cc
+++ b/modules/audio_coding/neteq/tools/neteq_event_log_input.cc
@@ -26,7 +26,7 @@
                      const std::vector<LoggedAudioPlayoutEvent>& output_events,
                      const std::vector<LoggedNetEqSetMinimumDelayEvent>&
                          neteq_set_minimum_delay_events,
-                     absl::optional<int64_t> end_time_ms)
+                     std::optional<int64_t> end_time_ms)
       : packet_stream_(packet_stream),
         packet_stream_it_(packet_stream_.begin()),
         output_events_(output_events),
@@ -43,34 +43,34 @@
     }
   }
 
-  absl::optional<int64_t> NextPacketTime() const override {
+  std::optional<int64_t> NextPacketTime() const override {
     if (packet_stream_it_ == packet_stream_.end()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (end_time_ms_ && packet_stream_it_->rtp.log_time_ms() > *end_time_ms_) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return packet_stream_it_->rtp.log_time_ms();
   }
 
-  absl::optional<int64_t> NextOutputEventTime() const override {
+  std::optional<int64_t> NextOutputEventTime() const override {
     if (output_events_it_ == output_events_.end()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (end_time_ms_ && output_events_it_->log_time_ms() > *end_time_ms_) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return output_events_it_->log_time_ms();
   }
 
-  absl::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override {
+  std::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override {
     if (neteq_set_minimum_delay_events_it_ ==
         neteq_set_minimum_delay_events_.end()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (end_time_ms_ &&
         neteq_set_minimum_delay_events_it_->log_time_ms() > *end_time_ms_) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return SetMinimumDelayInfo(
         neteq_set_minimum_delay_events_it_->log_time_ms(),
@@ -110,9 +110,9 @@
 
   bool ended() const override { return !NextEventTime(); }
 
-  absl::optional<RTPHeader> NextHeader() const override {
+  std::optional<RTPHeader> NextHeader() const override {
     if (packet_stream_it_ == packet_stream_.end()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return packet_stream_it_->rtp.header;
   }
@@ -126,14 +126,14 @@
       neteq_set_minimum_delay_events_;
   std::vector<LoggedNetEqSetMinimumDelayEvent>::const_iterator
       neteq_set_minimum_delay_events_it_;
-  const absl::optional<int64_t> end_time_ms_;
+  const std::optional<int64_t> end_time_ms_;
 };
 
 }  // namespace
 
 std::unique_ptr<NetEqInput> CreateNetEqEventLogInput(
     const ParsedRtcEventLog& parsed_log,
-    absl::optional<uint32_t> ssrc) {
+    std::optional<uint32_t> ssrc) {
   if (parsed_log.incoming_audio_ssrcs().empty()) {
     return nullptr;
   }
diff --git a/modules/audio_coding/neteq/tools/neteq_event_log_input.h b/modules/audio_coding/neteq/tools/neteq_event_log_input.h
index a84de84..cdfd62d 100644
--- a/modules/audio_coding/neteq/tools/neteq_event_log_input.h
+++ b/modules/audio_coding/neteq/tools/neteq_event_log_input.h
@@ -11,8 +11,9 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_EVENT_LOG_INPUT_H_
 #define MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_EVENT_LOG_INPUT_H_
 
+#include <optional>
+
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "logging/rtc_event_log/rtc_event_log_parser.h"
 #include "modules/audio_coding/neteq/tools/neteq_input.h"
 
@@ -21,7 +22,7 @@
 
 std::unique_ptr<NetEqInput> CreateNetEqEventLogInput(
     const ParsedRtcEventLog& parsed_log,
-    absl::optional<uint32_t> ssrc);
+    std::optional<uint32_t> ssrc);
 
 }  // namespace test
 }  // namespace webrtc
diff --git a/modules/audio_coding/neteq/tools/neteq_input.cc b/modules/audio_coding/neteq/tools/neteq_input.cc
index 57160b9..2bcc59b 100644
--- a/modules/audio_coding/neteq/tools/neteq_input.cc
+++ b/modules/audio_coding/neteq/tools/neteq_input.cc
@@ -50,17 +50,17 @@
 
 TimeLimitedNetEqInput::~TimeLimitedNetEqInput() = default;
 
-absl::optional<int64_t> TimeLimitedNetEqInput::NextPacketTime() const {
-  return ended_ ? absl::nullopt : input_->NextPacketTime();
+std::optional<int64_t> TimeLimitedNetEqInput::NextPacketTime() const {
+  return ended_ ? std::nullopt : input_->NextPacketTime();
 }
 
-absl::optional<int64_t> TimeLimitedNetEqInput::NextOutputEventTime() const {
-  return ended_ ? absl::nullopt : input_->NextOutputEventTime();
+std::optional<int64_t> TimeLimitedNetEqInput::NextOutputEventTime() const {
+  return ended_ ? std::nullopt : input_->NextOutputEventTime();
 }
 
-absl::optional<NetEqInput::SetMinimumDelayInfo>
+std::optional<NetEqInput::SetMinimumDelayInfo>
 TimeLimitedNetEqInput::NextSetMinimumDelayInfo() const {
-  return ended_ ? absl::nullopt : input_->NextSetMinimumDelayInfo();
+  return ended_ ? std::nullopt : input_->NextSetMinimumDelayInfo();
 }
 
 std::unique_ptr<NetEqInput::PacketData> TimeLimitedNetEqInput::PopPacket() {
@@ -90,8 +90,8 @@
   return ended_ || input_->ended();
 }
 
-absl::optional<RTPHeader> TimeLimitedNetEqInput::NextHeader() const {
-  return ended_ ? absl::nullopt : input_->NextHeader();
+std::optional<RTPHeader> TimeLimitedNetEqInput::NextHeader() const {
+  return ended_ ? std::nullopt : input_->NextHeader();
 }
 
 void TimeLimitedNetEqInput::MaybeSetEnded() {
diff --git a/modules/audio_coding/neteq/tools/neteq_input.h b/modules/audio_coding/neteq/tools/neteq_input.h
index 56b0212..127cf19 100644
--- a/modules/audio_coding/neteq/tools/neteq_input.h
+++ b/modules/audio_coding/neteq/tools/neteq_input.h
@@ -13,9 +13,9 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "modules/audio_coding/neteq/tools/packet.h"
 #include "modules/audio_coding/neteq/tools/packet_source.h"
 #include "rtc_base/buffer.h"
@@ -47,21 +47,21 @@
 
   // Returns at what time (in ms) NetEq::InsertPacket should be called next, or
   // empty if the source is out of packets.
-  virtual absl::optional<int64_t> NextPacketTime() const = 0;
+  virtual std::optional<int64_t> NextPacketTime() const = 0;
 
   // Returns at what time (in ms) NetEq::GetAudio should be called next, or
   // empty if no more output events are available.
-  virtual absl::optional<int64_t> NextOutputEventTime() const = 0;
+  virtual std::optional<int64_t> NextOutputEventTime() const = 0;
 
   // Returns the information related to the next NetEq set minimum delay event
   // if available.
-  virtual absl::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo()
+  virtual std::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo()
       const = 0;
 
   // Returns the time (in ms) for the next event (packet, output or set minimum
   // delay event) or empty if there are no more events.
-  absl::optional<int64_t> NextEventTime() const {
-    absl::optional<int64_t> next_event_time = NextPacketTime();
+  std::optional<int64_t> NextEventTime() const {
+    std::optional<int64_t> next_event_time = NextPacketTime();
     const auto next_output_time = NextOutputEventTime();
     // Return the minimum of non-empty `a` and `b`, or empty if both are empty.
     if (next_output_time) {
@@ -102,7 +102,7 @@
 
   // Returns the RTP header for the next packet, i.e., the packet that will be
   // delivered next by PopPacket().
-  virtual absl::optional<RTPHeader> NextHeader() const = 0;
+  virtual std::optional<RTPHeader> NextHeader() const = 0;
 };
 
 // Wrapper class to impose a time limit on a NetEqInput object, typically
@@ -112,20 +112,20 @@
  public:
   TimeLimitedNetEqInput(std::unique_ptr<NetEqInput> input, int64_t duration_ms);
   ~TimeLimitedNetEqInput() override;
-  absl::optional<int64_t> NextPacketTime() const override;
-  absl::optional<int64_t> NextOutputEventTime() const override;
-  absl::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override;
+  std::optional<int64_t> NextPacketTime() const override;
+  std::optional<int64_t> NextOutputEventTime() const override;
+  std::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override;
   std::unique_ptr<PacketData> PopPacket() override;
   void AdvanceOutputEvent() override;
   void AdvanceSetMinimumDelay() override;
   bool ended() const override;
-  absl::optional<RTPHeader> NextHeader() const override;
+  std::optional<RTPHeader> NextHeader() const override;
 
  private:
   void MaybeSetEnded();
 
   std::unique_ptr<NetEqInput> input_;
-  const absl::optional<int64_t> start_time_ms_;
+  const std::optional<int64_t> start_time_ms_;
   const int64_t duration_ms_;
   bool ended_ = false;
 };
diff --git a/modules/audio_coding/neteq/tools/neteq_replacement_input.cc b/modules/audio_coding/neteq/tools/neteq_replacement_input.cc
index f2648d7..2fb53d8 100644
--- a/modules/audio_coding/neteq/tools/neteq_replacement_input.cc
+++ b/modules/audio_coding/neteq/tools/neteq_replacement_input.cc
@@ -30,17 +30,17 @@
   ReplacePacket();
 }
 
-absl::optional<int64_t> NetEqReplacementInput::NextPacketTime() const {
+std::optional<int64_t> NetEqReplacementInput::NextPacketTime() const {
   return packet_
-             ? absl::optional<int64_t>(static_cast<int64_t>(packet_->time_ms))
-             : absl::nullopt;
+             ? std::optional<int64_t>(static_cast<int64_t>(packet_->time_ms))
+             : std::nullopt;
 }
 
-absl::optional<int64_t> NetEqReplacementInput::NextOutputEventTime() const {
+std::optional<int64_t> NetEqReplacementInput::NextOutputEventTime() const {
   return source_->NextOutputEventTime();
 }
 
-absl::optional<NetEqInput::SetMinimumDelayInfo>
+std::optional<NetEqInput::SetMinimumDelayInfo>
 NetEqReplacementInput::NextSetMinimumDelayInfo() const {
   return source_->NextSetMinimumDelayInfo();
 }
@@ -72,7 +72,7 @@
   return source_->ended();
 }
 
-absl::optional<RTPHeader> NetEqReplacementInput::NextHeader() const {
+std::optional<RTPHeader> NetEqReplacementInput::NextHeader() const {
   return source_->NextHeader();
 }
 
@@ -98,7 +98,7 @@
     return;
   }
 
-  absl::optional<RTPHeader> next_hdr = source_->NextHeader();
+  std::optional<RTPHeader> next_hdr = source_->NextHeader();
   RTC_DCHECK(next_hdr);
   uint8_t payload[12];
   constexpr uint32_t kMaxFrameSize = 120 * 48;
diff --git a/modules/audio_coding/neteq/tools/neteq_replacement_input.h b/modules/audio_coding/neteq/tools/neteq_replacement_input.h
index 23e4bea..33d8138 100644
--- a/modules/audio_coding/neteq/tools/neteq_replacement_input.h
+++ b/modules/audio_coding/neteq/tools/neteq_replacement_input.h
@@ -28,14 +28,14 @@
                         const std::set<uint8_t>& comfort_noise_types,
                         const std::set<uint8_t>& forbidden_types);
 
-  absl::optional<int64_t> NextPacketTime() const override;
-  absl::optional<int64_t> NextOutputEventTime() const override;
-  absl::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override;
+  std::optional<int64_t> NextPacketTime() const override;
+  std::optional<int64_t> NextOutputEventTime() const override;
+  std::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override;
   std::unique_ptr<PacketData> PopPacket() override;
   void AdvanceOutputEvent() override;
   void AdvanceSetMinimumDelay() override;
   bool ended() const override;
-  absl::optional<RTPHeader> NextHeader() const override;
+  std::optional<RTPHeader> NextHeader() const override;
 
  private:
   void ReplacePacket();
diff --git a/modules/audio_coding/neteq/tools/neteq_rtp_dump_input.cc b/modules/audio_coding/neteq/tools/neteq_rtp_dump_input.cc
index 20e092b..b3c29c1 100644
--- a/modules/audio_coding/neteq/tools/neteq_rtp_dump_input.cc
+++ b/modules/audio_coding/neteq/tools/neteq_rtp_dump_input.cc
@@ -22,7 +22,7 @@
  public:
   NetEqRtpDumpInput(absl::string_view file_name,
                     const std::map<int, RTPExtensionType>& hdr_ext_map,
-                    absl::optional<uint32_t> ssrc_filter)
+                    std::optional<uint32_t> ssrc_filter)
       : source_(RtpFileSource::Create(file_name, ssrc_filter)) {
     for (const auto& ext_pair : hdr_ext_map) {
       source_->RegisterRtpHeaderExtension(ext_pair.second, ext_pair.first);
@@ -30,12 +30,12 @@
     LoadNextPacket();
   }
 
-  absl::optional<int64_t> NextOutputEventTime() const override {
+  std::optional<int64_t> NextOutputEventTime() const override {
     return next_output_event_ms_;
   }
 
-  absl::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override {
-    return absl::nullopt;
+  std::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override {
+    return std::nullopt;
   }
 
   void AdvanceOutputEvent() override {
@@ -43,16 +43,16 @@
       *next_output_event_ms_ += kOutputPeriodMs;
     }
     if (!NextPacketTime()) {
-      next_output_event_ms_ = absl::nullopt;
+      next_output_event_ms_ = std::nullopt;
     }
   }
 
   void AdvanceSetMinimumDelay() override {}
 
-  absl::optional<int64_t> NextPacketTime() const override {
-    return packet_ ? absl::optional<int64_t>(
+  std::optional<int64_t> NextPacketTime() const override {
+    return packet_ ? std::optional<int64_t>(
                          static_cast<int64_t>(packet_->time_ms()))
-                   : absl::nullopt;
+                   : std::nullopt;
   }
 
   std::unique_ptr<PacketData> PopPacket() override {
@@ -78,9 +78,8 @@
     return packet_data;
   }
 
-  absl::optional<RTPHeader> NextHeader() const override {
-    return packet_ ? absl::optional<RTPHeader>(packet_->header())
-                   : absl::nullopt;
+  std::optional<RTPHeader> NextHeader() const override {
+    return packet_ ? std::optional<RTPHeader>(packet_->header()) : std::nullopt;
   }
 
   bool ended() const override { return !next_output_event_ms_; }
@@ -88,7 +87,7 @@
  private:
   void LoadNextPacket() { packet_ = source_->NextPacket(); }
 
-  absl::optional<int64_t> next_output_event_ms_ = 0;
+  std::optional<int64_t> next_output_event_ms_ = 0;
   static constexpr int64_t kOutputPeriodMs = 10;
 
   std::unique_ptr<RtpFileSource> source_;
@@ -100,7 +99,7 @@
 std::unique_ptr<NetEqInput> CreateNetEqRtpDumpInput(
     absl::string_view file_name,
     const std::map<int, RTPExtensionType>& hdr_ext_map,
-    absl::optional<uint32_t> ssrc_filter) {
+    std::optional<uint32_t> ssrc_filter) {
   return std::make_unique<NetEqRtpDumpInput>(file_name, hdr_ext_map,
                                              ssrc_filter);
 }
diff --git a/modules/audio_coding/neteq/tools/neteq_rtp_dump_input.h b/modules/audio_coding/neteq/tools/neteq_rtp_dump_input.h
index e68ebb2..da03732 100644
--- a/modules/audio_coding/neteq/tools/neteq_rtp_dump_input.h
+++ b/modules/audio_coding/neteq/tools/neteq_rtp_dump_input.h
@@ -13,9 +13,9 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "modules/audio_coding/neteq/tools/neteq_input.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 
@@ -25,7 +25,7 @@
 std::unique_ptr<NetEqInput> CreateNetEqRtpDumpInput(
     absl::string_view file_name,
     const std::map<int, RTPExtensionType>& hdr_ext_map,
-    absl::optional<uint32_t> ssrc_filter);
+    std::optional<uint32_t> ssrc_filter);
 
 }  // namespace test
 }  // namespace webrtc
diff --git a/modules/audio_coding/neteq/tools/neteq_rtpplay.cc b/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
index b274069..a7db337 100644
--- a/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
+++ b/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
@@ -9,12 +9,12 @@
  */
 
 #include <iostream>
+#include <optional>
 #include <string>
 
 #include "absl/flags/flag.h"
 #include "absl/flags/parse.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "modules/audio_coding/neteq/tools/neteq_test.h"
 #include "modules/audio_coding/neteq/tools/neteq_test_factory.h"
 #include "rtc_base/strings/string_builder.h"
@@ -262,13 +262,13 @@
   return true;
 }
 
-absl::optional<std::string> CreateOptionalOutputFileName(
+std::optional<std::string> CreateOptionalOutputFileName(
     bool output_requested,
     absl::string_view basename,
     absl::string_view output_audio_filename,
     absl::string_view suffix) {
   if (!output_requested) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (!basename.empty()) {
     // Override the automatic assignment.
@@ -283,7 +283,7 @@
     return sb.str();
   }
   std::cout << "Error: invalid text log file parameters.";
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace
@@ -394,7 +394,7 @@
     uint32_t ssrc;
     RTC_CHECK(ParseSsrc(absl::GetFlag(FLAGS_ssrc), &ssrc))
         << "Flag verification has failed.";
-    config.ssrc_filter = absl::make_optional(ssrc);
+    config.ssrc_filter = std::make_optional(ssrc);
   }
 
   std::unique_ptr<webrtc::test::NetEqTest> test =
diff --git a/modules/audio_coding/neteq/tools/neteq_test.cc b/modules/audio_coding/neteq/tools/neteq_test.cc
index 4487ac5..76ab544 100644
--- a/modules/audio_coding/neteq/tools/neteq_test.cc
+++ b/modules/audio_coding/neteq/tools/neteq_test.cc
@@ -25,20 +25,20 @@
 namespace test {
 namespace {
 
-absl::optional<NetEq::Operation> ActionToOperations(
-    absl::optional<NetEqSimulator::Action> a) {
+std::optional<NetEq::Operation> ActionToOperations(
+    std::optional<NetEqSimulator::Action> a) {
   if (!a) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   switch (*a) {
     case NetEqSimulator::Action::kAccelerate:
-      return absl::make_optional(NetEq::Operation::kAccelerate);
+      return std::make_optional(NetEq::Operation::kAccelerate);
     case NetEqSimulator::Action::kExpand:
-      return absl::make_optional(NetEq::Operation::kExpand);
+      return std::make_optional(NetEq::Operation::kExpand);
     case NetEqSimulator::Action::kNormal:
-      return absl::make_optional(NetEq::Operation::kNormal);
+      return std::make_optional(NetEq::Operation::kNormal);
     case NetEqSimulator::Action::kPreemptiveExpand:
-      return absl::make_optional(NetEq::Operation::kPreemptiveExpand);
+      return std::make_optional(NetEq::Operation::kPreemptiveExpand);
   }
 }
 
@@ -166,9 +166,9 @@
                    << ", buffer size: " << std::setw(4)
                    << ops_state.current_buffer_size_ms << std::endl;
       }
-      last_packet_time_ms_ = absl::make_optional<int>(time_now_ms);
+      last_packet_time_ms_ = std::make_optional<int>(time_now_ms);
       last_packet_timestamp_ =
-          absl::make_optional<uint32_t>(packet_data->header.timestamp);
+          std::make_optional<uint32_t>(packet_data->header.timestamp);
     }
 
     if (input_->NextSetMinimumDelayInfo().has_value() &&
@@ -187,7 +187,7 @@
       AudioFrame out_frame;
       int error = neteq_->GetAudio(&out_frame, nullptr, nullptr,
                                    ActionToOperations(next_action_));
-      next_action_ = absl::nullopt;
+      next_action_ = std::nullopt;
       if (error != NetEq::kOK) {
         if (callbacks_.error_callback) {
           callbacks_.error_callback->OnGetAudioError();
@@ -292,7 +292,7 @@
 }
 
 void NetEqTest::SetNextAction(NetEqTest::Action next_operation) {
-  next_action_ = absl::optional<Action>(next_operation);
+  next_action_ = std::optional<Action>(next_operation);
 }
 
 NetEqTest::NetEqState NetEqTest::GetNetEqState() {
diff --git a/modules/audio_coding/neteq/tools/neteq_test.h b/modules/audio_coding/neteq/tools/neteq_test.h
index 89506a8..5f826e2 100644
--- a/modules/audio_coding/neteq/tools/neteq_test.h
+++ b/modules/audio_coding/neteq/tools/neteq_test.h
@@ -14,10 +14,10 @@
 #include <fstream>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_decoder_factory.h"
 #include "api/environment/environment.h"
 #include "api/neteq/neteq.h"
@@ -115,8 +115,8 @@
   std::unique_ptr<NetEqInput> input_;
   SimulatedClock clock_;
   const Environment env_;
-  absl::optional<Action> next_action_;
-  absl::optional<int> last_packet_time_ms_;
+  std::optional<Action> next_action_;
+  std::optional<int> last_packet_time_ms_;
   std::unique_ptr<NetEq> neteq_;
   std::unique_ptr<AudioSink> output_;
   Callbacks callbacks_;
@@ -124,7 +124,7 @@
   NetEqState current_state_;
   NetEqOperationsAndState prev_ops_state_;
   NetEqLifetimeStatistics prev_lifetime_stats_;
-  absl::optional<uint32_t> last_packet_timestamp_;
+  std::optional<uint32_t> last_packet_timestamp_;
   std::unique_ptr<std::ofstream> text_log_;
 };
 
diff --git a/modules/audio_coding/neteq/tools/neteq_test_factory.cc b/modules/audio_coding/neteq/tools/neteq_test_factory.cc
index 766a092..1f79c44 100644
--- a/modules/audio_coding/neteq/tools/neteq_test_factory.cc
+++ b/modules/audio_coding/neteq/tools/neteq_test_factory.cc
@@ -47,7 +47,7 @@
 namespace test {
 namespace {
 
-absl::optional<int> CodecSampleRate(
+std::optional<int> CodecSampleRate(
     uint8_t payload_type,
     webrtc::test::NetEqTestFactory::Config config) {
   if (payload_type == config.pcmu || payload_type == config.pcma ||
@@ -66,7 +66,7 @@
     return 48000;
   if (payload_type == config.red)
     return 0;
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace
@@ -98,7 +98,7 @@
 
  private:
   NetEqPostInsertPacket* other_callback_;
-  absl::optional<uint32_t> last_ssrc_;
+  std::optional<uint32_t> last_ssrc_;
 };
 
 NetEqTestFactory::NetEqTestFactory() = default;
@@ -197,9 +197,9 @@
   }
 
   // Check the sample rate.
-  absl::optional<int> sample_rate_hz;
+  std::optional<int> sample_rate_hz;
   std::set<std::pair<int, uint32_t>> discarded_pt_and_ssrc;
-  while (absl::optional<RTPHeader> first_rtp_header = input->NextHeader()) {
+  while (std::optional<RTPHeader> first_rtp_header = input->NextHeader()) {
     RTC_DCHECK(first_rtp_header);
     sample_rate_hz = CodecSampleRate(first_rtp_header->payloadType, config);
     if (sample_rate_hz) {
@@ -295,7 +295,7 @@
     decoder_factory = rtc::make_ref_counted<FunctionAudioDecoderFactory>(
         [decoder_factory, config](
             const Environment& env, const SdpAudioFormat& format,
-            absl::optional<AudioCodecPairId> codec_pair_id) {
+            std::optional<AudioCodecPairId> codec_pair_id) {
           std::unique_ptr<AudioDecoder> decoder =
               decoder_factory->Create(env, format, codec_pair_id);
           if (!decoder && format.name == "replacement") {
diff --git a/modules/audio_coding/neteq/tools/neteq_test_factory.h b/modules/audio_coding/neteq/tools/neteq_test_factory.h
index 6091749..3a34171 100644
--- a/modules/audio_coding/neteq/tools/neteq_test_factory.h
+++ b/modules/audio_coding/neteq/tools/neteq_test_factory.h
@@ -12,10 +12,10 @@
 #define MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_TEST_FACTORY_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "modules/audio_coding/neteq/tools/neteq_test.h"
 
 namespace webrtc {
@@ -98,7 +98,7 @@
     // A PCM file that will be used to populate dummy RTP packets.
     std::string replacement_audio_file;
     // Only use packets with this SSRC.
-    absl::optional<uint32_t> ssrc_filter;
+    std::optional<uint32_t> ssrc_filter;
     // Extension ID for audio level (RFC 6464).
     static constexpr int default_audio_level() { return 1; }
     int audio_level = default_audio_level();
@@ -136,11 +136,11 @@
     bool textlog = false;
     // If specified and `textlog` is true, the output of `textlog` is written to
     // the specified file name.
-    absl::optional<std::string> textlog_filename;
+    std::optional<std::string> textlog_filename;
     // Base name for the output script files for plotting the delay profile.
-    absl::optional<std::string> plot_scripts_basename;
+    std::optional<std::string> plot_scripts_basename;
     // Path to the output audio file.
-    absl::optional<std::string> output_audio_filename;
+    std::optional<std::string> output_audio_filename;
     // Field trials to use during the simulation.
     std::string field_trial_string;
   };
diff --git a/modules/audio_coding/neteq/tools/rtp_file_source.cc b/modules/audio_coding/neteq/tools/rtp_file_source.cc
index 7a8daef..056b30d 100644
--- a/modules/audio_coding/neteq/tools/rtp_file_source.cc
+++ b/modules/audio_coding/neteq/tools/rtp_file_source.cc
@@ -27,7 +27,7 @@
 namespace test {
 
 RtpFileSource* RtpFileSource::Create(absl::string_view file_name,
-                                     absl::optional<uint32_t> ssrc_filter) {
+                                     std::optional<uint32_t> ssrc_filter) {
   RtpFileSource* source = new RtpFileSource(ssrc_filter);
   RTC_CHECK(source->OpenFile(file_name));
   return source;
@@ -79,7 +79,7 @@
   }
 }
 
-RtpFileSource::RtpFileSource(absl::optional<uint32_t> ssrc_filter)
+RtpFileSource::RtpFileSource(std::optional<uint32_t> ssrc_filter)
     : PacketSource(), ssrc_filter_(ssrc_filter) {}
 
 bool RtpFileSource::OpenFile(absl::string_view file_name) {
diff --git a/modules/audio_coding/neteq/tools/rtp_file_source.h b/modules/audio_coding/neteq/tools/rtp_file_source.h
index 55505be..300981a 100644
--- a/modules/audio_coding/neteq/tools/rtp_file_source.h
+++ b/modules/audio_coding/neteq/tools/rtp_file_source.h
@@ -14,10 +14,10 @@
 #include <stdio.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "modules/audio_coding/neteq/tools/packet_source.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 
@@ -33,7 +33,7 @@
   // opened, or has the wrong format, NULL will be returned.
   static RtpFileSource* Create(
       absl::string_view file_name,
-      absl::optional<uint32_t> ssrc_filter = absl::nullopt);
+      std::optional<uint32_t> ssrc_filter = std::nullopt);
 
   // Checks whether a files is a valid RTP dump or PCAP (Wireshark) file.
   static bool ValidRtpDump(absl::string_view file_name);
@@ -54,12 +54,12 @@
   static const int kRtpFileHeaderSize = 4 + 4 + 4 + 2 + 2;
   static const size_t kPacketHeaderSize = 8;
 
-  explicit RtpFileSource(absl::optional<uint32_t> ssrc_filter);
+  explicit RtpFileSource(std::optional<uint32_t> ssrc_filter);
 
   bool OpenFile(absl::string_view file_name);
 
   std::unique_ptr<RtpFileReader> rtp_reader_;
-  const absl::optional<uint32_t> ssrc_filter_;
+  const std::optional<uint32_t> ssrc_filter_;
   RtpHeaderExtensionMap rtp_header_extension_map_;
 };
 
diff --git a/modules/audio_coding/neteq/underrun_optimizer.cc b/modules/audio_coding/neteq/underrun_optimizer.cc
index baed812..d1f12e9 100644
--- a/modules/audio_coding/neteq/underrun_optimizer.cc
+++ b/modules/audio_coding/neteq/underrun_optimizer.cc
@@ -24,15 +24,15 @@
 UnderrunOptimizer::UnderrunOptimizer(const TickTimer* tick_timer,
                                      int histogram_quantile,
                                      int forget_factor,
-                                     absl::optional<int> start_forget_weight,
-                                     absl::optional<int> resample_interval_ms)
+                                     std::optional<int> start_forget_weight,
+                                     std::optional<int> resample_interval_ms)
     : tick_timer_(tick_timer),
       histogram_(kDelayBuckets, forget_factor, start_forget_weight),
       histogram_quantile_(histogram_quantile),
       resample_interval_ms_(resample_interval_ms) {}
 
 void UnderrunOptimizer::Update(int relative_delay_ms) {
-  absl::optional<int> histogram_update;
+  std::optional<int> histogram_update;
   if (resample_interval_ms_) {
     if (!resample_stopwatch_) {
       resample_stopwatch_ = tick_timer_->GetNewStopwatch();
diff --git a/modules/audio_coding/neteq/underrun_optimizer.h b/modules/audio_coding/neteq/underrun_optimizer.h
index b37ce18..20a46ff 100644
--- a/modules/audio_coding/neteq/underrun_optimizer.h
+++ b/modules/audio_coding/neteq/underrun_optimizer.h
@@ -12,8 +12,8 @@
 #define MODULES_AUDIO_CODING_NETEQ_UNDERRUN_OPTIMIZER_H_
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/neteq/tick_timer.h"
 #include "modules/audio_coding/neteq/histogram.h"
 
@@ -27,12 +27,12 @@
   UnderrunOptimizer(const TickTimer* tick_timer,
                     int histogram_quantile,
                     int forget_factor,
-                    absl::optional<int> start_forget_weight,
-                    absl::optional<int> resample_interval_ms);
+                    std::optional<int> start_forget_weight,
+                    std::optional<int> resample_interval_ms);
 
   void Update(int relative_delay_ms);
 
-  absl::optional<int> GetOptimalDelayMs() const { return optimal_delay_ms_; }
+  std::optional<int> GetOptimalDelayMs() const { return optimal_delay_ms_; }
 
   void Reset();
 
@@ -40,10 +40,10 @@
   const TickTimer* tick_timer_;
   Histogram histogram_;
   const int histogram_quantile_;  // In Q30.
-  const absl::optional<int> resample_interval_ms_;
+  const std::optional<int> resample_interval_ms_;
   std::unique_ptr<TickTimer::Stopwatch> resample_stopwatch_;
   int max_delay_in_interval_ms_ = 0;
-  absl::optional<int> optimal_delay_ms_;
+  std::optional<int> optimal_delay_ms_;
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_coding/neteq/underrun_optimizer_unittest.cc b/modules/audio_coding/neteq/underrun_optimizer_unittest.cc
index a86e9cf..0988e03 100644
--- a/modules/audio_coding/neteq/underrun_optimizer_unittest.cc
+++ b/modules/audio_coding/neteq/underrun_optimizer_unittest.cc
@@ -25,7 +25,7 @@
   TickTimer tick_timer;
   constexpr int kResampleIntervalMs = 500;
   UnderrunOptimizer underrun_optimizer(&tick_timer, kDefaultHistogramQuantile,
-                                       kForgetFactor, absl::nullopt,
+                                       kForgetFactor, std::nullopt,
                                        kResampleIntervalMs);
 
   // The histogram should be updated once with the maximum delay observed for
diff --git a/modules/audio_coding/test/PCMFile.h b/modules/audio_coding/test/PCMFile.h
index 5320aa6..64af5df 100644
--- a/modules/audio_coding/test/PCMFile.h
+++ b/modules/audio_coding/test/PCMFile.h
@@ -14,10 +14,10 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/audio/audio_frame.h"
 
 namespace webrtc {
@@ -68,7 +68,7 @@
   uint32_t timestamp_;
   bool read_stereo_;
   bool save_stereo_;
-  absl::optional<int> num_10ms_blocks_to_read_;
+  std::optional<int> num_10ms_blocks_to_read_;
   int blocks_read_ = 0;
 };
 
diff --git a/modules/audio_coding/test/TestRedFec.cc b/modules/audio_coding/test/TestRedFec.cc
index c2b42cc..b4d138b 100644
--- a/modules/audio_coding/test/TestRedFec.cc
+++ b/modules/audio_coding/test/TestRedFec.cc
@@ -103,7 +103,7 @@
   _outFileB.Close();
 #endif
 
-  RegisterSendCodec(_acmA, {"opus", 48000, 2}, absl::nullopt, false);
+  RegisterSendCodec(_acmA, {"opus", 48000, 2}, std::nullopt, false);
 
   // _channelA2B imposes 25% packet loss rate.
   EXPECT_EQ(0, _acmA->SetPacketLossRate(25));
@@ -116,11 +116,11 @@
   Run();
 
   // Switch to L16 with RED.
-  RegisterSendCodec(_acmA, {"L16", 8000, 1}, absl::nullopt, true);
+  RegisterSendCodec(_acmA, {"L16", 8000, 1}, std::nullopt, true);
   Run();
 
   // Switch to Opus again.
-  RegisterSendCodec(_acmA, {"opus", 48000, 2}, absl::nullopt, false);
+  RegisterSendCodec(_acmA, {"opus", 48000, 2}, std::nullopt, false);
   _acmA->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* enc) {
     EXPECT_EQ(true, (*enc)->SetFec(false));
   });
@@ -135,7 +135,7 @@
 void TestRedFec::RegisterSendCodec(
     const std::unique_ptr<AudioCodingModule>& acm,
     const SdpAudioFormat& codec_format,
-    absl::optional<Vad::Aggressiveness> vad_mode,
+    std::optional<Vad::Aggressiveness> vad_mode,
     bool use_red) {
   constexpr int payload_type = 17, cn_payload_type = 27, red_payload_type = 37;
 
diff --git a/modules/audio_coding/test/TestRedFec.h b/modules/audio_coding/test/TestRedFec.h
index 8c43c1d..56a6495 100644
--- a/modules/audio_coding/test/TestRedFec.h
+++ b/modules/audio_coding/test/TestRedFec.h
@@ -35,7 +35,7 @@
  private:
   void RegisterSendCodec(const std::unique_ptr<AudioCodingModule>& acm,
                          const SdpAudioFormat& codec_format,
-                         absl::optional<Vad::Aggressiveness> vad_mode,
+                         std::optional<Vad::Aggressiveness> vad_mode,
                          bool use_red);
   void Run();
   void OpenOutFile(int16_t testNumber);
diff --git a/modules/audio_coding/test/TestVADDTX.cc b/modules/audio_coding/test/TestVADDTX.cc
index 50781a7..ac87ae1 100644
--- a/modules/audio_coding/test/TestVADDTX.cc
+++ b/modules/audio_coding/test/TestVADDTX.cc
@@ -86,7 +86,7 @@
 }
 
 bool TestVadDtx::RegisterCodec(const SdpAudioFormat& codec_format,
-                               absl::optional<Vad::Aggressiveness> vad_mode) {
+                               std::optional<Vad::Aggressiveness> vad_mode) {
   constexpr int payload_type = 17, cn_payload_type = 117;
   bool added_comfort_noise = false;
 
@@ -190,7 +190,7 @@
 // Test various configurations on VAD/DTX.
 void TestWebRtcVadDtx::RunTestCases(const SdpAudioFormat& codec_format) {
   Test(/*new_outfile=*/true,
-       /*expect_dtx_enabled=*/RegisterCodec(codec_format, absl::nullopt));
+       /*expect_dtx_enabled=*/RegisterCodec(codec_format, std::nullopt));
 
   Test(/*new_outfile=*/false,
        /*expect_dtx_enabled=*/RegisterCodec(codec_format, Vad::kVadAggressive));
@@ -225,7 +225,7 @@
   // Register Opus as send codec
   std::string out_filename =
       webrtc::test::OutputPath() + "testOpusDtx_outFile_mono.pcm";
-  RegisterCodec({"opus", 48000, 2}, absl::nullopt);
+  RegisterCodec({"opus", 48000, 2}, std::nullopt);
   acm_send_->ModifyEncoder([](std::unique_ptr<AudioEncoder>* encoder_ptr) {
     (*encoder_ptr)->SetDtx(false);
   });
diff --git a/modules/audio_coding/test/TestVADDTX.h b/modules/audio_coding/test/TestVADDTX.h
index 427c94c..b7f90a3 100644
--- a/modules/audio_coding/test/TestVADDTX.h
+++ b/modules/audio_coding/test/TestVADDTX.h
@@ -64,7 +64,7 @@
  protected:
   // Returns true iff CN was added.
   bool RegisterCodec(const SdpAudioFormat& codec_format,
-                     absl::optional<Vad::Aggressiveness> vad_mode);
+                     std::optional<Vad::Aggressiveness> vad_mode);
 
   // Encoding a file and see if the numbers that various packets occur follow
   // the expectation. Saves result to a file.
diff --git a/modules/audio_device/BUILD.gn b/modules/audio_device/BUILD.gn
index d4eee0b..b69ada7 100644
--- a/modules/audio_device/BUILD.gn
+++ b/modules/audio_device/BUILD.gn
@@ -78,7 +78,6 @@
     "../../rtc_base/synchronization:mutex",
     "../../system_wrappers",
     "../../system_wrappers:metrics",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -166,7 +165,6 @@
       "../../rtc_base/win:scoped_com_initializer",
       "../../rtc_base/win:windows_version",
       "//third_party/abseil-cpp/absl/strings:strings",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
@@ -204,7 +202,6 @@
       "../../rtc_base/synchronization:mutex",
       "../../rtc_base/task_utils:repeating_task",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
@@ -437,7 +434,6 @@
     "../../api:make_ref_counted",
     "../../api/audio:audio_device",
     "../../test:test_support",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -479,7 +475,6 @@
       "../../test:fileutils",
       "../../test:test_support",
       "../../test/time_controller",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
     if (is_linux || is_chromeos || is_mac || is_win) {
       sources += [ "audio_device_unittest.cc" ]
diff --git a/modules/audio_device/audio_device_buffer.cc b/modules/audio_device/audio_device_buffer.cc
index 38ed633..95096da 100644
--- a/modules/audio_device/audio_device_buffer.cc
+++ b/modules/audio_device/audio_device_buffer.cc
@@ -245,13 +245,13 @@
 
 int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audio_buffer,
                                              size_t samples_per_channel) {
-  return SetRecordedBuffer(audio_buffer, samples_per_channel, absl::nullopt);
+  return SetRecordedBuffer(audio_buffer, samples_per_channel, std::nullopt);
 }
 
 int32_t AudioDeviceBuffer::SetRecordedBuffer(
     const void* audio_buffer,
     size_t samples_per_channel,
-    absl::optional<int64_t> capture_timestamp_ns) {
+    std::optional<int64_t> capture_timestamp_ns) {
   // Copy the complete input buffer to the local buffer.
   const size_t old_size = rec_buffer_.size();
   rec_buffer_.SetData(static_cast<const int16_t*>(audio_buffer),
diff --git a/modules/audio_device/audio_device_buffer.h b/modules/audio_device/audio_device_buffer.h
index e9a90ab..99a4cb7 100644
--- a/modules/audio_device/audio_device_buffer.h
+++ b/modules/audio_device/audio_device_buffer.h
@@ -110,7 +110,7 @@
   virtual int32_t SetRecordedBuffer(
       const void* audio_buffer,
       size_t samples_per_channel,
-      absl::optional<int64_t> capture_timestamp_ns);
+      std::optional<int64_t> capture_timestamp_ns);
   virtual void SetVQEData(int play_delay_ms, int rec_delay_ms);
   virtual int32_t DeliverRecordedData();
   uint32_t NewMicLevel() const;
@@ -200,11 +200,11 @@
   int rec_delay_ms_;
 
   // Capture timestamp.
-  absl::optional<int64_t> capture_timestamp_ns_;
+  std::optional<int64_t> capture_timestamp_ns_;
   // The last time the Timestamp Aligner was used to estimate clock offset
   // between system clock and capture time from audio.
   // This is used to prevent estimating the clock offset too often.
-  absl::optional<int64_t> align_offsync_estimation_time_;
+  std::optional<int64_t> align_offsync_estimation_time_;
 
   // Counts number of times LogStats() has been called.
   size_t num_stat_reports_ RTC_GUARDED_BY(task_queue_);
diff --git a/modules/audio_device/audio_device_data_observer.cc b/modules/audio_device/audio_device_data_observer.cc
index 9643f75..6f4a177 100644
--- a/modules/audio_device/audio_device_data_observer.cc
+++ b/modules/audio_device/audio_device_data_observer.cc
@@ -58,7 +58,7 @@
     return RecordedDataIsAvailable(
         audioSamples, nSamples, nBytesPerSample, nChannels, samples_per_sec,
         total_delay_ms, clockDrift, currentMicLevel, keyPressed, newMicLevel,
-        /*capture_timestamp_ns=*/absl::nullopt);
+        /*capture_timestamp_ns=*/std::nullopt);
   }
 
   // AudioTransport methods overrides.
@@ -73,7 +73,7 @@
       uint32_t currentMicLevel,
       bool keyPressed,
       uint32_t& newMicLevel,
-      absl::optional<int64_t> capture_timestamp_ns) override {
+      std::optional<int64_t> capture_timestamp_ns) override {
     int32_t res = 0;
     // Capture PCM data of locally captured audio.
     if (observer_) {
diff --git a/modules/audio_device/audio_device_unittest.cc b/modules/audio_device/audio_device_unittest.cc
index 8275f21..8090cc5 100644
--- a/modules/audio_device/audio_device_unittest.cc
+++ b/modules/audio_device/audio_device_unittest.cc
@@ -15,8 +15,8 @@
 #include <list>
 #include <memory>
 #include <numeric>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/scoped_refptr.h"
 #include "api/sequence_checker.h"
@@ -320,7 +320,7 @@
   SequenceChecker read_thread_checker_;
   SequenceChecker write_thread_checker_;
 
-  absl::optional<int64_t> pulse_time_ RTC_GUARDED_BY(lock_);
+  std::optional<int64_t> pulse_time_ RTC_GUARDED_BY(lock_);
   std::vector<int> latencies_ RTC_GUARDED_BY(race_checker_);
   size_t read_count_ RTC_GUARDED_BY(read_thread_checker_) = 0;
   size_t write_count_ RTC_GUARDED_BY(write_thread_checker_) = 0;
diff --git a/modules/audio_device/fine_audio_buffer.cc b/modules/audio_device/fine_audio_buffer.cc
index f483b8d..c872988 100644
--- a/modules/audio_device/fine_audio_buffer.cc
+++ b/modules/audio_device/fine_audio_buffer.cc
@@ -109,7 +109,7 @@
 void FineAudioBuffer::DeliverRecordedData(
     rtc::ArrayView<const int16_t> audio_buffer,
     int record_delay_ms,
-    absl::optional<int64_t> capture_time_ns) {
+    std::optional<int64_t> capture_time_ns) {
   RTC_DCHECK(IsReadyForRecord());
   // Always append new data and grow the buffer when needed.
   record_buffer_.AppendData(audio_buffer.data(), audio_buffer.size());
diff --git a/modules/audio_device/fine_audio_buffer.h b/modules/audio_device/fine_audio_buffer.h
index 7af41d3..cd5dedd 100644
--- a/modules/audio_device/fine_audio_buffer.h
+++ b/modules/audio_device/fine_audio_buffer.h
@@ -13,8 +13,8 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "rtc_base/buffer.h"
 
@@ -66,11 +66,11 @@
   // cache. Call #3 restarts the scheme above.
   void DeliverRecordedData(rtc::ArrayView<const int16_t> audio_buffer,
                            int record_delay_ms) {
-    DeliverRecordedData(audio_buffer, record_delay_ms, absl::nullopt);
+    DeliverRecordedData(audio_buffer, record_delay_ms, std::nullopt);
   }
   void DeliverRecordedData(rtc::ArrayView<const int16_t> audio_buffer,
                            int record_delay_ms,
-                           absl::optional<int64_t> capture_time_ns);
+                           std::optional<int64_t> capture_time_ns);
 
  private:
   // Device buffer that works with 10ms chunks of data both for playout and
diff --git a/modules/audio_device/include/mock_audio_transport.h b/modules/audio_device/include/mock_audio_transport.h
index cde0e53..56f6905 100644
--- a/modules/audio_device/include/mock_audio_transport.h
+++ b/modules/audio_device/include/mock_audio_transport.h
@@ -48,7 +48,7 @@
                uint32_t currentMicLevel,
                bool keyPressed,
                uint32_t& newMicLevel,
-               absl::optional<int64_t> estimated_capture_time_ns),
+               std::optional<int64_t> estimated_capture_time_ns),
               (override));
 
   MOCK_METHOD(int32_t,
diff --git a/modules/audio_device/include/test_audio_device_unittest.cc b/modules/audio_device/include/test_audio_device_unittest.cc
index 165a4fb..a0eb240 100644
--- a/modules/audio_device/include/test_audio_device_unittest.cc
+++ b/modules/audio_device/include/test_audio_device_unittest.cc
@@ -13,9 +13,9 @@
 #include <algorithm>
 #include <array>
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/audio_device_defines.h"
 #include "api/task_queue/task_queue_factory.h"
@@ -366,7 +366,7 @@
       uint32_t current_mic_level,
       bool key_pressed,
       uint32_t& new_mic_level,
-      absl::optional<int64_t> estimated_capture_time_ns) override {
+      std::optional<int64_t> estimated_capture_time_ns) override {
     new_mic_level = 1;
 
     if (mode_ != Mode::kRecording) {
diff --git a/modules/audio_device/mock_audio_device_buffer.h b/modules/audio_device/mock_audio_device_buffer.h
index 0b27618..d9c9a48 100644
--- a/modules/audio_device/mock_audio_device_buffer.h
+++ b/modules/audio_device/mock_audio_device_buffer.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_AUDIO_DEVICE_MOCK_AUDIO_DEVICE_BUFFER_H_
 #define MODULES_AUDIO_DEVICE_MOCK_AUDIO_DEVICE_BUFFER_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/audio_device/audio_device_buffer.h"
 #include "test/gmock.h"
 
@@ -27,7 +28,7 @@
               SetRecordedBuffer,
               (const void* audioBuffer,
                size_t nSamples,
-               absl::optional<int64_t> capture_time_ns),
+               std::optional<int64_t> capture_time_ns),
               (override));
   MOCK_METHOD(void, SetVQEData, (int playDelayMS, int recDelayMS), (override));
   MOCK_METHOD(int32_t, DeliverRecordedData, (), (override));
diff --git a/modules/audio_device/test_audio_device_impl.cc b/modules/audio_device/test_audio_device_impl.cc
index a3742ea..914a04d 100644
--- a/modules/audio_device/test_audio_device_impl.cc
+++ b/modules/audio_device/test_audio_device_impl.cc
@@ -10,9 +10,9 @@
 #include "modules/audio_device/test_audio_device_impl.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/task_queue/task_queue_factory.h"
 #include "api/units/time_delta.h"
@@ -169,7 +169,7 @@
       audio_buffer_->SetRecordedBuffer(
           recording_buffer_.data(),
           recording_buffer_.size() / capturer_->NumChannels(),
-          absl::make_optional(rtc::TimeNanos()));
+          std::make_optional(rtc::TimeNanos()));
       audio_buffer_->DeliverRecordedData();
     }
     if (!keep_capturing) {
diff --git a/modules/audio_device/test_audio_device_impl_test.cc b/modules/audio_device/test_audio_device_impl_test.cc
index ad15ad5..6b6b0a6 100644
--- a/modules/audio_device/test_audio_device_impl_test.cc
+++ b/modules/audio_device/test_audio_device_impl_test.cc
@@ -10,9 +10,9 @@
 #include "modules/audio_device/test_audio_device_impl.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/audio/audio_device_defines.h"
 #include "api/task_queue/task_queue_factory.h"
@@ -52,7 +52,7 @@
       uint32_t current_mic_level,
       bool key_pressed,
       uint32_t& new_mic_level,
-      absl::optional<int64_t> estimated_capture_time_ns) override {
+      std::optional<int64_t> estimated_capture_time_ns) override {
     new_mic_level = 1;
 
     if (mode_ != Mode::kRecording) {
diff --git a/modules/audio_device/win/core_audio_base_win.h b/modules/audio_device/win/core_audio_base_win.h
index 6c1357e..2d42dfc 100644
--- a/modules/audio_device/win/core_audio_base_win.h
+++ b/modules/audio_device/win/core_audio_base_win.h
@@ -14,10 +14,10 @@
 #include <atomic>
 #include <functional>
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/sequence_checker.h"
 #include "modules/audio_device/win/core_audio_utility_win.h"
 #include "rtc_base/platform_thread.h"
@@ -140,7 +140,7 @@
   bool is_active_ = false;
   int64_t num_data_callbacks_ = 0;
   int latency_ms_ = 0;
-  absl::optional<uint32_t> sample_rate_;
+  std::optional<uint32_t> sample_rate_;
 
  private:
   const Direction direction_;
diff --git a/modules/audio_device/win/core_audio_input_win.cc b/modules/audio_device/win/core_audio_input_win.cc
index 17790da..f70330e 100644
--- a/modules/audio_device/win/core_audio_input_win.cc
+++ b/modules/audio_device/win/core_audio_input_win.cc
@@ -317,7 +317,7 @@
     // Update input delay estimate but only about once per second to save
     // resources. The estimate is usually stable.
     if (num_data_callbacks_ % 100 == 0) {
-      absl::optional<int> opt_record_delay_ms;
+      std::optional<int> opt_record_delay_ms;
       // TODO(henrika): note that FineAudioBuffer adds latency as well.
       opt_record_delay_ms = EstimateLatencyMillis(capture_time_100ns);
       if (opt_record_delay_ms) {
@@ -392,10 +392,10 @@
   return true;
 }
 
-absl::optional<int> CoreAudioInput::EstimateLatencyMillis(
+std::optional<int> CoreAudioInput::EstimateLatencyMillis(
     uint64_t capture_time_100ns) {
   if (!qpc_to_100ns_) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   // Input parameter `capture_time_100ns` contains the performance counter at
   // the time that the audio endpoint device recorded the device position of
@@ -406,7 +406,7 @@
   // - subtracting `capture_time_100ns` from now_time_100ns.
   LARGE_INTEGER perf_counter_now = {};
   if (!::QueryPerformanceCounter(&perf_counter_now)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   uint64_t qpc_now_raw = perf_counter_now.QuadPart;
   uint64_t now_time_100ns = qpc_now_raw * (*qpc_to_100ns_);
diff --git a/modules/audio_device/win/core_audio_input_win.h b/modules/audio_device/win/core_audio_input_win.h
index be290f9..ecf536a 100644
--- a/modules/audio_device/win/core_audio_input_win.h
+++ b/modules/audio_device/win/core_audio_input_win.h
@@ -12,9 +12,9 @@
 #define MODULES_AUDIO_DEVICE_WIN_CORE_AUDIO_INPUT_WIN_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "modules/audio_device/win/audio_device_module_win.h"
 #include "modules/audio_device/win/core_audio_base_win.h"
 
@@ -58,12 +58,12 @@
   void ReleaseCOMObjects();
   bool OnDataCallback(uint64_t device_frequency);
   bool OnErrorCallback(ErrorType error);
-  absl::optional<int> EstimateLatencyMillis(uint64_t capture_time_100ns);
+  std::optional<int> EstimateLatencyMillis(uint64_t capture_time_100ns);
   bool HandleStreamDisconnected();
 
   std::unique_ptr<FineAudioBuffer> fine_audio_buffer_;
   Microsoft::WRL::ComPtr<IAudioCaptureClient> audio_capture_client_;
-  absl::optional<double> qpc_to_100ns_;
+  std::optional<double> qpc_to_100ns_;
 };
 
 }  // namespace webrtc_win
diff --git a/modules/audio_mixer/BUILD.gn b/modules/audio_mixer/BUILD.gn
index bb6d080..38c4e95 100644
--- a/modules/audio_mixer/BUILD.gn
+++ b/modules/audio_mixer/BUILD.gn
@@ -124,7 +124,6 @@
       "../../rtc_base:task_queue_for_test",
       "../../system_wrappers:metrics",
       "../../test:test_support",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
diff --git a/modules/audio_mixer/audio_mixer_impl_unittest.cc b/modules/audio_mixer/audio_mixer_impl_unittest.cc
index b04b706..00e2f7a 100644
--- a/modules/audio_mixer/audio_mixer_impl_unittest.cc
+++ b/modules/audio_mixer/audio_mixer_impl_unittest.cc
@@ -15,11 +15,11 @@
 #include <cstdint>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_mixer.h"
 #include "api/rtp_packet_info.h"
 #include "api/rtp_packet_infos.h"
@@ -448,7 +448,7 @@
   const uint32_t kCsrc3 = 23;
   const int kAudioLevel0 = 10;
   const int kAudioLevel1 = 40;
-  const absl::optional<uint32_t> kAudioLevel2 = absl::nullopt;
+  const std::optional<uint32_t> kAudioLevel2 = std::nullopt;
   const uint32_t kRtpTimestamp0 = 300;
   const uint32_t kRtpTimestamp1 = 400;
   const Timestamp kReceiveTime0 = Timestamp::Millis(10);
diff --git a/modules/audio_mixer/frame_combiner_unittest.cc b/modules/audio_mixer/frame_combiner_unittest.cc
index 80c2b99..4218f4e 100644
--- a/modules/audio_mixer/frame_combiner_unittest.cc
+++ b/modules/audio_mixer/frame_combiner_unittest.cc
@@ -13,11 +13,11 @@
 #include <cstdint>
 #include <initializer_list>
 #include <numeric>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/rtp_packet_info.h"
 #include "api/rtp_packet_infos.h"
diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn
index c403a95..1f4bc7e 100644
--- a/modules/audio_processing/BUILD.gn
+++ b/modules/audio_processing/BUILD.gn
@@ -93,7 +93,6 @@
     ":audio_frame_view",
     "../../api/audio:audio_processing",
     "//third_party/abseil-cpp/absl/base:core_headers",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -194,7 +193,6 @@
     "//third_party/abseil-cpp/absl/base:nullability",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 
   deps += [
@@ -233,7 +231,6 @@
     "../../rtc_base:checks",
     "../../rtc_base:logging",
     "../../system_wrappers:metrics",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -246,7 +243,6 @@
   deps = [
     "../../api:array_view",
     "../../rtc_base:checks",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -281,7 +277,6 @@
     "../../rtc_base:checks",
     "../../rtc_base:stringutils",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   defines = []
 }
@@ -404,7 +399,6 @@
         "vad:vad_unittests",
         "//testing/gtest",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
 
       defines = []
@@ -495,7 +489,6 @@
       "../../rtc_base:safe_conversions",
       "../../rtc_base:safe_minmax",
       "agc2:gain_map",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -547,7 +540,6 @@
         "//third_party/abseil-cpp/absl/flags:flag",
         "//third_party/abseil-cpp/absl/flags:parse",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }  # audioproc_f_impl
   }
@@ -625,7 +617,6 @@
     "../audio_coding:neteq_input_audio_tools",
     "//testing/gtest",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/modules/audio_processing/aec3/BUILD.gn b/modules/audio_processing/aec3/BUILD.gn
index 0f84e24..12a32b8 100644
--- a/modules/audio_processing/aec3/BUILD.gn
+++ b/modules/audio_processing/aec3/BUILD.gn
@@ -157,7 +157,6 @@
     "../../../system_wrappers:metrics",
     "../utility:cascaded_biquad_filter",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 
   if (current_cpu == "x86" || current_cpu == "x64") {
@@ -228,7 +227,6 @@
     "../../../api:array_view",
     "../../../rtc_base:gtest_prod",
     "../../../rtc_base/system:arch",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -326,7 +324,6 @@
       "../../../test:field_trial",
       "../../../test:test_support",
       "../utility:cascaded_biquad_filter",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
 
     defines = []
diff --git a/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc b/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc
index a13764c..162cf54 100644
--- a/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc
+++ b/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc
@@ -484,7 +484,7 @@
   std::vector<float> y(kBlockSize, 0.f);
   AecState aec_state(EchoCanceller3Config{}, num_capture_channels);
   RenderSignalAnalyzer render_signal_analyzer(config);
-  absl::optional<DelayEstimate> delay_estimate;
+  std::optional<DelayEstimate> delay_estimate;
   std::vector<float> e(kBlockSize, 0.f);
   std::array<float, kFftLength> s_scratch;
   std::vector<SubtractorOutput> output(num_capture_channels);
diff --git a/modules/audio_processing/aec3/aec_state.cc b/modules/audio_processing/aec3/aec_state.cc
index 81fd91f..e3e9795 100644
--- a/modules/audio_processing/aec3/aec_state.cc
+++ b/modules/audio_processing/aec3/aec_state.cc
@@ -14,9 +14,9 @@
 
 #include <algorithm>
 #include <numeric>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
@@ -170,7 +170,7 @@
 }
 
 void AecState::Update(
-    const absl::optional<DelayEstimate>& external_delay,
+    const std::optional<DelayEstimate>& external_delay,
     rtc::ArrayView<const std::vector<std::array<float, kFftLengthBy2Plus1>>>
         adaptive_filter_frequency_responses,
     rtc::ArrayView<const std::vector<float>> adaptive_filter_impulse_responses,
@@ -359,7 +359,7 @@
 
 void AecState::FilterDelay::Update(
     rtc::ArrayView<const int> analyzer_filter_delay_estimates_blocks,
-    const absl::optional<DelayEstimate>& external_delay,
+    const std::optional<DelayEstimate>& external_delay,
     size_t blocks_with_proper_filter_adaptation) {
   // Update the delay based on the external delay.
   if (external_delay &&
@@ -405,7 +405,7 @@
     bool active_render,
     bool transparent_mode,
     bool saturated_capture,
-    const absl::optional<DelayEstimate>& external_delay,
+    const std::optional<DelayEstimate>& external_delay,
     bool any_filter_converged) {
   // Update blocks counter.
   const bool filter_update = active_render && !saturated_capture;
diff --git a/modules/audio_processing/aec3/aec_state.h b/modules/audio_processing/aec3/aec_state.h
index a39325c..e80b377 100644
--- a/modules/audio_processing/aec3/aec_state.h
+++ b/modules/audio_processing/aec3/aec_state.h
@@ -16,9 +16,9 @@
 #include <array>
 #include <atomic>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
@@ -138,7 +138,7 @@
   // Updates the aec state.
   // TODO(bugs.webrtc.org/10913): Compute multi-channel ERL.
   void Update(
-      const absl::optional<DelayEstimate>& external_delay,
+      const std::optional<DelayEstimate>& external_delay,
       rtc::ArrayView<const std::vector<std::array<float, kFftLengthBy2Plus1>>>
           adaptive_filter_frequency_responses,
       rtc::ArrayView<const std::vector<float>>
@@ -213,7 +213,7 @@
     // Updates the delay estimates based on new data.
     void Update(
         rtc::ArrayView<const int> analyzer_filter_delay_estimates_blocks,
-        const absl::optional<DelayEstimate>& external_delay,
+        const std::optional<DelayEstimate>& external_delay,
         size_t blocks_with_proper_filter_adaptation);
 
    private:
@@ -221,7 +221,7 @@
     bool external_delay_reported_ = false;
     std::vector<int> filter_delays_blocks_;
     int min_filter_delay_;
-    absl::optional<DelayEstimate> external_delay_;
+    std::optional<DelayEstimate> external_delay_;
   } delay_state_;
 
   // Classifier for toggling transparent mode when there is no echo.
@@ -253,7 +253,7 @@
     void Update(bool active_render,
                 bool transparent_mode,
                 bool saturated_capture,
-                const absl::optional<DelayEstimate>& external_delay,
+                const std::optional<DelayEstimate>& external_delay,
                 bool any_filter_converged);
 
    private:
diff --git a/modules/audio_processing/aec3/aec_state_unittest.cc b/modules/audio_processing/aec3/aec_state_unittest.cc
index 6662c8f..2caf677 100644
--- a/modules/audio_processing/aec3/aec_state_unittest.cc
+++ b/modules/audio_processing/aec3/aec_state_unittest.cc
@@ -28,7 +28,7 @@
   ApmDataDumper data_dumper(42);
   EchoCanceller3Config config;
   AecState state(config, num_capture_channels);
-  absl::optional<DelayEstimate> delay_estimate =
+  std::optional<DelayEstimate> delay_estimate =
       DelayEstimate(DelayEstimate::Quality::kRefined, 10);
   std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
       RenderDelayBuffer::Create(config, kSampleRateHz, num_render_channels));
@@ -247,7 +247,7 @@
   AecState state(config, kNumCaptureChannels);
   std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
       RenderDelayBuffer::Create(config, 48000, 1));
-  absl::optional<DelayEstimate> delay_estimate;
+  std::optional<DelayEstimate> delay_estimate;
   std::vector<std::array<float, kFftLengthBy2Plus1>> E2_refined(
       kNumCaptureChannels);
   std::vector<std::array<float, kFftLengthBy2Plus1>> Y2(kNumCaptureChannels);
diff --git a/modules/audio_processing/aec3/block_processor.cc b/modules/audio_processing/aec3/block_processor.cc
index 63e3d9c..ad3702e 100644
--- a/modules/audio_processing/aec3/block_processor.cc
+++ b/modules/audio_processing/aec3/block_processor.cc
@@ -13,10 +13,10 @@
 
 #include <atomic>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "api/audio/echo_control.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
@@ -76,7 +76,7 @@
   BlockProcessorMetrics metrics_;
   RenderDelayBuffer::BufferingEvent render_event_;
   size_t capture_call_counter_ = 0;
-  absl::optional<DelayEstimate> estimated_delay_;
+  std::optional<DelayEstimate> estimated_delay_;
 };
 
 std::atomic<int> BlockProcessorImpl::instance_count_(0);
@@ -223,7 +223,7 @@
 void BlockProcessorImpl::GetMetrics(EchoControl::Metrics* metrics) const {
   echo_remover_->GetMetrics(metrics);
   constexpr int block_size_ms = 4;
-  absl::optional<size_t> delay = render_buffer_->Delay();
+  std::optional<size_t> delay = render_buffer_->Delay();
   metrics->delay_ms = delay ? static_cast<int>(*delay) * block_size_ms : 0;
 }
 
diff --git a/modules/audio_processing/aec3/block_processor_unittest.cc b/modules/audio_processing/aec3/block_processor_unittest.cc
index aba5c41..123dffd 100644
--- a/modules/audio_processing/aec3/block_processor_unittest.cc
+++ b/modules/audio_processing/aec3/block_processor_unittest.cc
@@ -315,19 +315,18 @@
   }
 
   EXPECT_CALL(*echo_remover_mock_pointer, ProcessCapture)
-      .WillRepeatedly(
-          [](EchoPathVariability /*echo_path_variability*/,
-             bool /*capture_signal_saturation*/,
-             const absl::optional<DelayEstimate>& /*external_delay*/,
-             RenderBuffer* render_buffer, Block* /*linear_output*/,
-             Block* capture) {
-            const auto& render = render_buffer->GetBlock(0);
-            const auto render_view = render.View(/*band=*/0, /*channel=*/0);
-            const auto capture_view = capture->View(/*band=*/0, /*channel=*/0);
-            for (size_t i = 0; i < kBlockSize; ++i) {
-              EXPECT_FLOAT_EQ(render_view[i], capture_view[i]);
-            }
-          });
+      .WillRepeatedly([](EchoPathVariability /*echo_path_variability*/,
+                         bool /*capture_signal_saturation*/,
+                         const std::optional<DelayEstimate>& /*external_delay*/,
+                         RenderBuffer* render_buffer, Block* /*linear_output*/,
+                         Block* capture) {
+        const auto& render = render_buffer->GetBlock(0);
+        const auto render_view = render.View(/*band=*/0, /*channel=*/0);
+        const auto capture_view = capture->View(/*band=*/0, /*channel=*/0);
+        for (size_t i = 0; i < kBlockSize; ++i) {
+          EXPECT_FLOAT_EQ(render_view[i], capture_view[i]);
+        }
+      });
 
   FillSampleVector(++capture_call_counter, kDelayInBlocks,
                    capture_block.View(/*band=*/0, /*capture=*/0));
diff --git a/modules/audio_processing/aec3/config_selector.cc b/modules/audio_processing/aec3/config_selector.cc
index c55344d..e6bd829 100644
--- a/modules/audio_processing/aec3/config_selector.cc
+++ b/modules/audio_processing/aec3/config_selector.cc
@@ -47,7 +47,7 @@
 
 ConfigSelector::ConfigSelector(
     const EchoCanceller3Config& config,
-    const absl::optional<EchoCanceller3Config>& multichannel_config,
+    const std::optional<EchoCanceller3Config>& multichannel_config,
     int num_render_input_channels)
     : config_(config), multichannel_config_(multichannel_config) {
   if (multichannel_config_.has_value()) {
diff --git a/modules/audio_processing/aec3/config_selector.h b/modules/audio_processing/aec3/config_selector.h
index 3b3f94e..f56f7ba 100644
--- a/modules/audio_processing/aec3/config_selector.h
+++ b/modules/audio_processing/aec3/config_selector.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_CONFIG_SELECTOR_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_CONFIG_SELECTOR_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/audio/echo_canceller3_config.h"
 
 namespace webrtc {
@@ -19,10 +20,9 @@
 // Selects the config to use.
 class ConfigSelector {
  public:
-  ConfigSelector(
-      const EchoCanceller3Config& config,
-      const absl::optional<EchoCanceller3Config>& multichannel_config,
-      int num_render_input_channels);
+  ConfigSelector(const EchoCanceller3Config& config,
+                 const std::optional<EchoCanceller3Config>& multichannel_config,
+                 int num_render_input_channels);
 
   // Updates the config selection based on the detection of multichannel
   // content.
@@ -32,7 +32,7 @@
 
  private:
   const EchoCanceller3Config config_;
-  const absl::optional<EchoCanceller3Config> multichannel_config_;
+  const std::optional<EchoCanceller3Config> multichannel_config_;
   const EchoCanceller3Config* active_config_ = nullptr;
 };
 
diff --git a/modules/audio_processing/aec3/config_selector_unittest.cc b/modules/audio_processing/aec3/config_selector_unittest.cc
index 1826bfc..91a60d8 100644
--- a/modules/audio_processing/aec3/config_selector_unittest.cc
+++ b/modules/audio_processing/aec3/config_selector_unittest.cc
@@ -10,9 +10,9 @@
 
 #include "modules/audio_processing/aec3/config_selector.h"
 
+#include <optional>
 #include <tuple>
 
-#include "absl/types/optional.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "test/gtest.h"
 
@@ -39,7 +39,7 @@
   const auto [num_channels, detect_stereo_content] = GetParam();
   EchoCanceller3Config config;
   config.multi_channel.detect_stereo_content = detect_stereo_content;
-  absl::optional<EchoCanceller3Config> multichannel_config;
+  std::optional<EchoCanceller3Config> multichannel_config;
 
   config.delay.default_delay = config.delay.default_delay + 1;
   const size_t custom_delay_value_in_config = config.delay.default_delay;
@@ -63,7 +63,7 @@
   const auto [num_channels, detect_stereo_content] = GetParam();
   EchoCanceller3Config config;
   config.multi_channel.detect_stereo_content = detect_stereo_content;
-  absl::optional<EchoCanceller3Config> multichannel_config = config;
+  std::optional<EchoCanceller3Config> multichannel_config = config;
 
   config.delay.default_delay += 1;
   const size_t custom_delay_value_in_config = config.delay.default_delay;
@@ -87,7 +87,7 @@
   const int num_channels = GetParam();
   EchoCanceller3Config config;
   config.multi_channel.detect_stereo_content = true;
-  absl::optional<EchoCanceller3Config> multichannel_config = config;
+  std::optional<EchoCanceller3Config> multichannel_config = config;
 
   config.delay.default_delay += 1;
   const size_t custom_delay_value_in_config = config.delay.default_delay;
diff --git a/modules/audio_processing/aec3/echo_audibility.cc b/modules/audio_processing/aec3/echo_audibility.cc
index 142a33d..d52b5ff 100644
--- a/modules/audio_processing/aec3/echo_audibility.cc
+++ b/modules/audio_processing/aec3/echo_audibility.cc
@@ -45,7 +45,7 @@
 void EchoAudibility::Reset() {
   render_stationarity_.Reset();
   non_zero_render_seen_ = false;
-  render_spectrum_write_prev_ = absl::nullopt;
+  render_spectrum_write_prev_ = std::nullopt;
 }
 
 void EchoAudibility::UpdateRenderStationarityFlags(
diff --git a/modules/audio_processing/aec3/echo_audibility.h b/modules/audio_processing/aec3/echo_audibility.h
index b9d6f87..0bf20cd 100644
--- a/modules/audio_processing/aec3/echo_audibility.h
+++ b/modules/audio_processing/aec3/echo_audibility.h
@@ -13,7 +13,8 @@
 
 #include <stddef.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/block_buffer.h"
 #include "modules/audio_processing/aec3/render_buffer.h"
@@ -73,7 +74,7 @@
   // values.
   bool IsRenderTooLow(const BlockBuffer& block_buffer);
 
-  absl::optional<int> render_spectrum_write_prev_;
+  std::optional<int> render_spectrum_write_prev_;
   int render_block_write_prev_;
   bool non_zero_render_seen_;
   const bool use_render_stationarity_at_init_;
diff --git a/modules/audio_processing/aec3/echo_canceller3.cc b/modules/audio_processing/aec3/echo_canceller3.cc
index 4c500f4..00010ce 100644
--- a/modules/audio_processing/aec3/echo_canceller3.cc
+++ b/modules/audio_processing/aec3/echo_canceller3.cc
@@ -718,7 +718,7 @@
 
 EchoCanceller3::EchoCanceller3(
     const EchoCanceller3Config& config,
-    const absl::optional<EchoCanceller3Config>& multichannel_config,
+    const std::optional<EchoCanceller3Config>& multichannel_config,
     int sample_rate_hz,
     size_t num_render_channels,
     size_t num_capture_channels)
diff --git a/modules/audio_processing/aec3/echo_canceller3.h b/modules/audio_processing/aec3/echo_canceller3.h
index 7bf8e51..b05b3d9 100644
--- a/modules/audio_processing/aec3/echo_canceller3.h
+++ b/modules/audio_processing/aec3/echo_canceller3.h
@@ -15,9 +15,9 @@
 
 #include <atomic>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "api/audio/echo_control.h"
@@ -88,12 +88,11 @@
 // AnalyzeRender call which can be called concurrently with the other methods.
 class EchoCanceller3 : public EchoControl {
  public:
-  EchoCanceller3(
-      const EchoCanceller3Config& config,
-      const absl::optional<EchoCanceller3Config>& multichannel_config,
-      int sample_rate_hz,
-      size_t num_render_channels,
-      size_t num_capture_channels);
+  EchoCanceller3(const EchoCanceller3Config& config,
+                 const std::optional<EchoCanceller3Config>& multichannel_config,
+                 int sample_rate_hz,
+                 size_t num_render_channels,
+                 size_t num_capture_channels);
 
   ~EchoCanceller3() override;
 
diff --git a/modules/audio_processing/aec3/echo_canceller3_unittest.cc b/modules/audio_processing/aec3/echo_canceller3_unittest.cc
index 10957fd..9cc11df 100644
--- a/modules/audio_processing/aec3/echo_canceller3_unittest.cc
+++ b/modules/audio_processing/aec3/echo_canceller3_unittest.cc
@@ -241,7 +241,7 @@
   // output.
   void RunCaptureTransportVerificationTest() {
     EchoCanceller3 aec3(EchoCanceller3Config(),
-                        /*multichannel_config=*/absl::nullopt, sample_rate_hz_,
+                        /*multichannel_config=*/std::nullopt, sample_rate_hz_,
                         1, 1);
     aec3.SetBlockProcessorForTesting(
         std::make_unique<CaptureTransportVerificationProcessor>(num_bands_));
@@ -267,7 +267,7 @@
   // block processor.
   void RunRenderTransportVerificationTest() {
     EchoCanceller3 aec3(EchoCanceller3Config(),
-                        /*multichannel_config=*/absl::nullopt, sample_rate_hz_,
+                        /*multichannel_config=*/std::nullopt, sample_rate_hz_,
                         1, 1);
     aec3.SetBlockProcessorForTesting(
         std::make_unique<RenderTransportVerificationProcessor>(num_bands_));
@@ -338,7 +338,7 @@
     }
 
     EchoCanceller3 aec3(EchoCanceller3Config(),
-                        /*multichannel_config=*/absl::nullopt, sample_rate_hz_,
+                        /*multichannel_config=*/std::nullopt, sample_rate_hz_,
                         1, 1);
     aec3.SetBlockProcessorForTesting(std::move(block_processor_mock));
 
@@ -420,7 +420,7 @@
     }
 
     EchoCanceller3 aec3(EchoCanceller3Config(),
-                        /*multichannel_config=*/absl::nullopt, sample_rate_hz_,
+                        /*multichannel_config=*/std::nullopt, sample_rate_hz_,
                         1, 1);
     aec3.SetBlockProcessorForTesting(std::move(block_processor_mock));
 
@@ -508,7 +508,7 @@
     }
 
     EchoCanceller3 aec3(EchoCanceller3Config(),
-                        /*multichannel_config=*/absl::nullopt, sample_rate_hz_,
+                        /*multichannel_config=*/std::nullopt, sample_rate_hz_,
                         1, 1);
     aec3.SetBlockProcessorForTesting(std::move(block_processor_mock));
     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
@@ -548,7 +548,7 @@
   // capture and render API calls.
   void RunRenderSwapQueueVerificationTest() {
     const EchoCanceller3Config config;
-    EchoCanceller3 aec3(config, /*multichannel_config=*/absl::nullopt,
+    EchoCanceller3 aec3(config, /*multichannel_config=*/std::nullopt,
                         sample_rate_hz_, 1, 1);
     aec3.SetBlockProcessorForTesting(
         std::make_unique<RenderTransportVerificationProcessor>(num_bands_));
@@ -598,7 +598,7 @@
   // properly reported.
   void RunRenderPipelineSwapQueueOverrunReturnValueTest() {
     EchoCanceller3 aec3(EchoCanceller3Config(),
-                        /*multichannel_config=*/absl::nullopt, sample_rate_hz_,
+                        /*multichannel_config=*/std::nullopt, sample_rate_hz_,
                         1, 1);
 
     constexpr size_t kRenderTransferQueueSize = 30;
@@ -625,7 +625,7 @@
     // way that the number of bands for the rates are different.
     const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
     EchoCanceller3 aec3(EchoCanceller3Config(),
-                        /*multichannel_config=*/absl::nullopt,
+                        /*multichannel_config=*/std::nullopt,
                         aec3_sample_rate_hz, 1, 1);
     PopulateInputFrame(frame_length_, 0, &render_buffer_.channels_f()[0][0], 0);
 
@@ -640,7 +640,7 @@
     // way that the number of bands for the rates are different.
     const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
     EchoCanceller3 aec3(EchoCanceller3Config(),
-                        /*multichannel_config=*/absl::nullopt,
+                        /*multichannel_config=*/std::nullopt,
                         aec3_sample_rate_hz, 1, 1);
     PopulateInputFrame(frame_length_, num_bands_, 0,
                        &capture_buffer_.split_bands_f(0)[0], 100);
@@ -947,7 +947,7 @@
   constexpr size_t kNumBlocksForMonoConfig = 1;
   constexpr size_t kNumBlocksForSurroundConfig = 2;
   EchoCanceller3Config mono_config;
-  absl::optional<EchoCanceller3Config> multichannel_config;
+  std::optional<EchoCanceller3Config> multichannel_config;
 
   mono_config.multi_channel.detect_stereo_content = true;
   mono_config.multi_channel.stereo_detection_threshold = 0.0f;
@@ -993,7 +993,7 @@
   constexpr size_t kNumBlocksForMonoConfig = 1;
   constexpr size_t kNumBlocksForSurroundConfig = 2;
   EchoCanceller3Config mono_config;
-  absl::optional<EchoCanceller3Config> multichannel_config;
+  std::optional<EchoCanceller3Config> multichannel_config;
 
   constexpr float kStereoDetectionThreshold = 2.0f;
   mono_config.multi_channel.detect_stereo_content = true;
@@ -1043,7 +1043,7 @@
   constexpr size_t kNumBlocksForMonoConfig = 1;
   constexpr size_t kNumBlocksForSurroundConfig = 2;
   EchoCanceller3Config mono_config;
-  absl::optional<EchoCanceller3Config> surround_config;
+  std::optional<EchoCanceller3Config> surround_config;
 
   mono_config.multi_channel.detect_stereo_content = true;
   mono_config.multi_channel.stereo_detection_hysteresis_seconds = 0.5f;
@@ -1101,7 +1101,7 @@
   constexpr size_t kNumBlocksForMonoConfig = 1;
   constexpr size_t kNumBlocksForSurroundConfig = 2;
   EchoCanceller3Config mono_config;
-  absl::optional<EchoCanceller3Config> multichannel_config;
+  std::optional<EchoCanceller3Config> multichannel_config;
 
   for (bool detect_stereo_content : {false, true}) {
     mono_config.multi_channel.detect_stereo_content = detect_stereo_content;
@@ -1149,7 +1149,7 @@
 TEST(EchoCanceller3InputCheckDeathTest, NullCaptureProcessingParameter) {
   EXPECT_DEATH(
       EchoCanceller3(EchoCanceller3Config(),
-                     /*multichannel_config_=*/absl::nullopt, 16000, 1, 1)
+                     /*multichannel_config_=*/std::nullopt, 16000, 1, 1)
           .ProcessCapture(nullptr, false),
       "");
 }
@@ -1161,7 +1161,7 @@
   ApmDataDumper data_dumper(0);
   EXPECT_DEATH(
       EchoCanceller3(EchoCanceller3Config(),
-                     /*multichannel_config_=*/absl::nullopt, 8001, 1, 1),
+                     /*multichannel_config_=*/std::nullopt, 8001, 1, 1),
       "");
 }
 
diff --git a/modules/audio_processing/aec3/echo_path_delay_estimator.cc b/modules/audio_processing/aec3/echo_path_delay_estimator.cc
index 510e4b8..1326779 100644
--- a/modules/audio_processing/aec3/echo_path_delay_estimator.cc
+++ b/modules/audio_processing/aec3/echo_path_delay_estimator.cc
@@ -58,7 +58,7 @@
   Reset(true, reset_delay_confidence);
 }
 
-absl::optional<DelayEstimate> EchoPathDelayEstimator::EstimateDelay(
+std::optional<DelayEstimate> EchoPathDelayEstimator::EstimateDelay(
     const DownsampledRenderBuffer& render_buffer,
     const Block& capture) {
   std::array<float, kBlockSize> downsampled_capture_data;
@@ -74,7 +74,7 @@
   matched_filter_.Update(render_buffer, downsampled_capture,
                          matched_filter_lag_aggregator_.ReliableDelayFound());
 
-  absl::optional<DelayEstimate> aggregated_matched_filter_lag =
+  std::optional<DelayEstimate> aggregated_matched_filter_lag =
       matched_filter_lag_aggregator_.Aggregate(
           matched_filter_.GetBestLagEstimate());
 
@@ -121,7 +121,7 @@
     matched_filter_lag_aggregator_.Reset(reset_delay_confidence);
   }
   matched_filter_.Reset(/*full_reset=*/reset_lag_aggregator);
-  old_aggregated_lag_ = absl::nullopt;
+  old_aggregated_lag_ = std::nullopt;
   consistent_estimate_counter_ = 0;
 }
 }  // namespace webrtc
diff --git a/modules/audio_processing/aec3/echo_path_delay_estimator.h b/modules/audio_processing/aec3/echo_path_delay_estimator.h
index b24d0a2..bd5c3b0 100644
--- a/modules/audio_processing/aec3/echo_path_delay_estimator.h
+++ b/modules/audio_processing/aec3/echo_path_delay_estimator.h
@@ -13,7 +13,8 @@
 
 #include <stddef.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/alignment_mixer.h"
 #include "modules/audio_processing/aec3/block.h"
@@ -45,7 +46,7 @@
   void Reset(bool reset_delay_confidence);
 
   // Produce a delay estimate if such is avaliable.
-  absl::optional<DelayEstimate> EstimateDelay(
+  std::optional<DelayEstimate> EstimateDelay(
       const DownsampledRenderBuffer& render_buffer,
       const Block& capture);
 
@@ -68,7 +69,7 @@
   Decimator capture_decimator_;
   MatchedFilter matched_filter_;
   MatchedFilterLagAggregator matched_filter_lag_aggregator_;
-  absl::optional<DelayEstimate> old_aggregated_lag_;
+  std::optional<DelayEstimate> old_aggregated_lag_;
   size_t consistent_estimate_counter_ = 0;
   ClockdriftDetector clockdrift_detector_;
 
diff --git a/modules/audio_processing/aec3/echo_path_delay_estimator_unittest.cc b/modules/audio_processing/aec3/echo_path_delay_estimator_unittest.cc
index e2c101f..4b8fdc9 100644
--- a/modules/audio_processing/aec3/echo_path_delay_estimator_unittest.cc
+++ b/modules/audio_processing/aec3/echo_path_delay_estimator_unittest.cc
@@ -88,7 +88,7 @@
       EchoPathDelayEstimator estimator(&data_dumper, config,
                                        kNumCaptureChannels);
 
-      absl::optional<DelayEstimate> estimated_delay_samples;
+      std::optional<DelayEstimate> estimated_delay_samples;
       for (size_t k = 0; k < (500 + (delay_samples) / kBlockSize); ++k) {
         RandomizeSampleVector(&random_generator,
                               render.View(/*band=*/0, /*channel=*/0));
diff --git a/modules/audio_processing/aec3/echo_remover.cc b/modules/audio_processing/aec3/echo_remover.cc
index 673d88a..e5c1b4c 100644
--- a/modules/audio_processing/aec3/echo_remover.cc
+++ b/modules/audio_processing/aec3/echo_remover.cc
@@ -120,7 +120,7 @@
   // signal.
   void ProcessCapture(EchoPathVariability echo_path_variability,
                       bool capture_signal_saturation,
-                      const absl::optional<DelayEstimate>& external_delay,
+                      const std::optional<DelayEstimate>& external_delay,
                       RenderBuffer* render_buffer,
                       Block* linear_output,
                       Block* capture) override;
@@ -239,7 +239,7 @@
 void EchoRemoverImpl::ProcessCapture(
     EchoPathVariability echo_path_variability,
     bool capture_signal_saturation,
-    const absl::optional<DelayEstimate>& external_delay,
+    const std::optional<DelayEstimate>& external_delay,
     RenderBuffer* render_buffer,
     Block* linear_output,
     Block* capture) {
diff --git a/modules/audio_processing/aec3/echo_remover.h b/modules/audio_processing/aec3/echo_remover.h
index f2f4f5e..db3992c 100644
--- a/modules/audio_processing/aec3/echo_remover.h
+++ b/modules/audio_processing/aec3/echo_remover.h
@@ -11,9 +11,9 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_ECHO_REMOVER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_ECHO_REMOVER_H_
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "api/audio/echo_control.h"
 #include "modules/audio_processing/aec3/block.h"
@@ -41,7 +41,7 @@
   virtual void ProcessCapture(
       EchoPathVariability echo_path_variability,
       bool capture_signal_saturation,
-      const absl::optional<DelayEstimate>& external_delay,
+      const std::optional<DelayEstimate>& external_delay,
       RenderBuffer* render_buffer,
       Block* linear_output,
       Block* capture) = 0;
diff --git a/modules/audio_processing/aec3/echo_remover_unittest.cc b/modules/audio_processing/aec3/echo_remover_unittest.cc
index 66168ab..9934a11 100644
--- a/modules/audio_processing/aec3/echo_remover_unittest.cc
+++ b/modules/audio_processing/aec3/echo_remover_unittest.cc
@@ -53,7 +53,7 @@
 TEST_P(EchoRemoverMultiChannel, BasicApiCalls) {
   const size_t num_render_channels = std::get<0>(GetParam());
   const size_t num_capture_channels = std::get<1>(GetParam());
-  absl::optional<DelayEstimate> delay_estimate;
+  std::optional<DelayEstimate> delay_estimate;
   for (auto rate : {16000, 32000, 48000}) {
     SCOPED_TRACE(ProduceDebugText(rate));
     std::unique_ptr<EchoRemover> remover(
@@ -95,7 +95,7 @@
 // TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
 // tests on test bots has been fixed.c
 TEST(EchoRemoverDeathTest, DISABLED_WrongCaptureNumBands) {
-  absl::optional<DelayEstimate> delay_estimate;
+  std::optional<DelayEstimate> delay_estimate;
   for (auto rate : {16000, 32000, 48000}) {
     SCOPED_TRACE(ProduceDebugText(rate));
     std::unique_ptr<EchoRemover> remover(
@@ -114,7 +114,7 @@
 
 // Verifies the check for non-null capture block.
 TEST(EchoRemoverDeathTest, NullCapture) {
-  absl::optional<DelayEstimate> delay_estimate;
+  std::optional<DelayEstimate> delay_estimate;
   std::unique_ptr<EchoRemover> remover(
       EchoRemover::Create(EchoCanceller3Config(), 16000, 1, 1));
   std::unique_ptr<RenderDelayBuffer> render_buffer(
@@ -134,7 +134,7 @@
 TEST(EchoRemover, BasicEchoRemoval) {
   constexpr int kNumBlocksToProcess = 500;
   Random random_generator(42U);
-  absl::optional<DelayEstimate> delay_estimate;
+  std::optional<DelayEstimate> delay_estimate;
   for (size_t num_channels : {1, 2, 4}) {
     for (auto rate : {16000, 32000, 48000}) {
       Block x(NumBandsForRate(rate), num_channels);
diff --git a/modules/audio_processing/aec3/erle_estimator.h b/modules/audio_processing/aec3/erle_estimator.h
index 5579759..ac9c738 100644
--- a/modules/audio_processing/aec3/erle_estimator.h
+++ b/modules/audio_processing/aec3/erle_estimator.h
@@ -15,9 +15,9 @@
 
 #include <array>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
@@ -91,7 +91,7 @@
   // vector with content between 0 and 1 where 1 indicates that, at this current
   // time instant, the linear filter is reaching its maximum subtraction
   // performance.
-  rtc::ArrayView<const absl::optional<float>> GetInstLinearQualityEstimates()
+  rtc::ArrayView<const std::optional<float>> GetInstLinearQualityEstimates()
       const {
     return fullband_erle_estimator_.GetInstLinearQualityEstimates();
   }
diff --git a/modules/audio_processing/aec3/fullband_erle_estimator.cc b/modules/audio_processing/aec3/fullband_erle_estimator.cc
index e56674e..5545b93 100644
--- a/modules/audio_processing/aec3/fullband_erle_estimator.cc
+++ b/modules/audio_processing/aec3/fullband_erle_estimator.cc
@@ -13,8 +13,8 @@
 #include <algorithm>
 #include <memory>
 #include <numeric>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
@@ -142,7 +142,7 @@
 }
 
 void FullBandErleEstimator::ErleInstantaneous::ResetAccumulators() {
-  erle_log2_ = absl::nullopt;
+  erle_log2_ = std::nullopt;
   inst_quality_estimate_ = 0.f;
   num_points_ = 0;
   E2_acum_ = 0.f;
diff --git a/modules/audio_processing/aec3/fullband_erle_estimator.h b/modules/audio_processing/aec3/fullband_erle_estimator.h
index 7a08217..cc828b2 100644
--- a/modules/audio_processing/aec3/fullband_erle_estimator.h
+++ b/modules/audio_processing/aec3/fullband_erle_estimator.h
@@ -12,9 +12,9 @@
 #define MODULES_AUDIO_PROCESSING_AEC3_FULLBAND_ERLE_ESTIMATOR_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
@@ -49,7 +49,7 @@
 
   // Returns an estimation of the current linear filter quality. It returns a
   // float number between 0 and 1 mapping 1 to the highest possible quality.
-  rtc::ArrayView<const absl::optional<float>> GetInstLinearQualityEstimates()
+  rtc::ArrayView<const std::optional<float>> GetInstLinearQualityEstimates()
       const {
     return linear_filters_qualities_;
   }
@@ -73,10 +73,10 @@
     // Resets the members related with an instantaneous estimate.
     void ResetAccumulators();
     // Returns the instantaneous ERLE in log2 units.
-    absl::optional<float> GetInstErleLog2() const { return erle_log2_; }
+    std::optional<float> GetInstErleLog2() const { return erle_log2_; }
     // Gets an indication between 0 and 1 of the performance of the linear
     // filter for the current time instant.
-    absl::optional<float> GetQualityEstimate() const {
+    std::optional<float> GetQualityEstimate() const {
       if (erle_log2_) {
         float value = inst_quality_estimate_;
         if (clamp_inst_quality_to_zero_) {
@@ -85,9 +85,9 @@
         if (clamp_inst_quality_to_one_) {
           value = std::min(1.f, value);
         }
-        return absl::optional<float>(value);
+        return std::optional<float>(value);
       }
-      return absl::nullopt;
+      return std::nullopt;
     }
     void Dump(const std::unique_ptr<ApmDataDumper>& data_dumper) const;
 
@@ -96,7 +96,7 @@
     void UpdateQualityEstimate();
     const bool clamp_inst_quality_to_zero_;
     const bool clamp_inst_quality_to_one_;
-    absl::optional<float> erle_log2_;
+    std::optional<float> erle_log2_;
     float inst_quality_estimate_;
     float max_erle_log2_;
     float min_erle_log2_;
@@ -110,7 +110,7 @@
   std::vector<int> hold_counters_instantaneous_erle_;
   std::vector<float> erle_time_domain_log2_;
   std::vector<ErleInstantaneous> instantaneous_erle_;
-  std::vector<absl::optional<float>> linear_filters_qualities_;
+  std::vector<std::optional<float>> linear_filters_qualities_;
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_processing/aec3/matched_filter.cc b/modules/audio_processing/aec3/matched_filter.cc
index a22c952..59a3b46 100644
--- a/modules/audio_processing/aec3/matched_filter.cc
+++ b/modules/audio_processing/aec3/matched_filter.cc
@@ -23,8 +23,8 @@
 #include <initializer_list>
 #include <iterator>
 #include <numeric>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/downsampled_render_buffer.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
@@ -647,8 +647,8 @@
     std::fill(f.begin(), f.end(), 0.f);
   }
 
-  winner_lag_ = absl::nullopt;
-  reported_lag_estimate_ = absl::nullopt;
+  winner_lag_ = std::nullopt;
+  reported_lag_estimate_ = std::nullopt;
   if (full_reset) {
     for (auto& e : accumulated_error_) {
       std::fill(e.begin(), e.end(), 1.0f);
@@ -677,10 +677,10 @@
 
   // Apply all matched filters.
   float winner_error_sum = error_sum_anchor;
-  winner_lag_ = absl::nullopt;
-  reported_lag_estimate_ = absl::nullopt;
+  winner_lag_ = std::nullopt;
+  reported_lag_estimate_ = std::nullopt;
   size_t alignment_shift = 0;
-  absl::optional<size_t> previous_lag_estimate;
+  std::optional<size_t> previous_lag_estimate;
   const int num_filters = static_cast<int>(filters_.size());
   int winner_index = -1;
   for (int n = 0; n < num_filters; ++n) {
diff --git a/modules/audio_processing/aec3/matched_filter.h b/modules/audio_processing/aec3/matched_filter.h
index fcdecbd..bb111c5 100644
--- a/modules/audio_processing/aec3/matched_filter.h
+++ b/modules/audio_processing/aec3/matched_filter.h
@@ -13,9 +13,9 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "rtc_base/gtest_prod_util.h"
@@ -133,7 +133,7 @@
   void Reset(bool full_reset);
 
   // Returns the current lag estimates.
-  absl::optional<const MatchedFilter::LagEstimate> GetBestLagEstimate() const {
+  std::optional<const MatchedFilter::LagEstimate> GetBestLagEstimate() const {
     return reported_lag_estimate_;
   }
 
@@ -158,8 +158,8 @@
   std::vector<std::vector<float>> accumulated_error_;
   std::vector<float> instantaneous_accumulated_error_;
   std::vector<float> scratch_memory_;
-  absl::optional<MatchedFilter::LagEstimate> reported_lag_estimate_;
-  absl::optional<size_t> winner_lag_;
+  std::optional<MatchedFilter::LagEstimate> reported_lag_estimate_;
+  std::optional<size_t> winner_lag_;
   int last_detected_best_lag_filter_ = -1;
   std::vector<size_t> filters_offsets_;
   int number_pre_echo_updates_ = 0;
diff --git a/modules/audio_processing/aec3/matched_filter_lag_aggregator.cc b/modules/audio_processing/aec3/matched_filter_lag_aggregator.cc
index 0ece2a6..a7c886a 100644
--- a/modules/audio_processing/aec3/matched_filter_lag_aggregator.cc
+++ b/modules/audio_processing/aec3/matched_filter_lag_aggregator.cc
@@ -62,8 +62,8 @@
   }
 }
 
-absl::optional<DelayEstimate> MatchedFilterLagAggregator::Aggregate(
-    const absl::optional<const MatchedFilter::LagEstimate>& lag_estimate) {
+std::optional<DelayEstimate> MatchedFilterLagAggregator::Aggregate(
+    const std::optional<const MatchedFilter::LagEstimate>& lag_estimate) {
   if (lag_estimate && pre_echo_lag_aggregator_) {
     pre_echo_lag_aggregator_->Dump(data_dumper_);
     pre_echo_lag_aggregator_->Aggregate(
@@ -90,7 +90,7 @@
     }
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 MatchedFilterLagAggregator::HighestPeakAggregator::HighestPeakAggregator(
diff --git a/modules/audio_processing/aec3/matched_filter_lag_aggregator.h b/modules/audio_processing/aec3/matched_filter_lag_aggregator.h
index 1e80a21..9022424 100644
--- a/modules/audio_processing/aec3/matched_filter_lag_aggregator.h
+++ b/modules/audio_processing/aec3/matched_filter_lag_aggregator.h
@@ -11,9 +11,9 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_MATCHED_FILTER_LAG_AGGREGATOR_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_MATCHED_FILTER_LAG_AGGREGATOR_H_
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/delay_estimate.h"
 #include "modules/audio_processing/aec3/matched_filter.h"
@@ -41,8 +41,8 @@
   void Reset(bool hard_reset);
 
   // Aggregates the provided lag estimates.
-  absl::optional<DelayEstimate> Aggregate(
-      const absl::optional<const MatchedFilter::LagEstimate>& lag_estimate);
+  std::optional<DelayEstimate> Aggregate(
+      const std::optional<const MatchedFilter::LagEstimate>& lag_estimate);
 
   // Returns whether a reliable delay estimate has been found.
   bool ReliableDelayFound() const { return significant_candidate_found_; }
diff --git a/modules/audio_processing/aec3/matched_filter_lag_aggregator_unittest.cc b/modules/audio_processing/aec3/matched_filter_lag_aggregator_unittest.cc
index 6804102..25c62fe 100644
--- a/modules/audio_processing/aec3/matched_filter_lag_aggregator_unittest.cc
+++ b/modules/audio_processing/aec3/matched_filter_lag_aggregator_unittest.cc
@@ -36,7 +36,7 @@
   MatchedFilterLagAggregator aggregator(&data_dumper, /*max_filter_lag=*/100,
                                         config.delay);
 
-  absl::optional<DelayEstimate> aggregated_lag;
+  std::optional<DelayEstimate> aggregated_lag;
   for (size_t k = 0; k < kNumLagsBeforeDetection; ++k) {
     aggregated_lag = aggregator.Aggregate(
         MatchedFilter::LagEstimate(/*lag=*/10, /*pre_echo_lag=*/10));
@@ -66,7 +66,7 @@
   MatchedFilterLagAggregator aggregator(&data_dumper, /*max_filter_lag=*/kLag,
                                         config.delay);
   for (size_t k = 0; k < kNumLagsBeforeDetection * 10; ++k) {
-    absl::optional<DelayEstimate> aggregated_lag = aggregator.Aggregate(
+    std::optional<DelayEstimate> aggregated_lag = aggregator.Aggregate(
         MatchedFilter::LagEstimate(/*lag=*/kLag, /*pre_echo_lag=*/kLag));
     EXPECT_FALSE(aggregated_lag);
     EXPECT_EQ(kLag, aggregated_lag->delay);
@@ -84,7 +84,7 @@
   std::vector<MatchedFilter::LagEstimate> lag_estimates(1);
   MatchedFilterLagAggregator aggregator(&data_dumper, std::max(kLag1, kLag2),
                                         config.delay);
-  absl::optional<DelayEstimate> aggregated_lag;
+  std::optional<DelayEstimate> aggregated_lag;
   for (size_t k = 0; k < kNumLagsBeforeDetection; ++k) {
     aggregated_lag = aggregator.Aggregate(
         MatchedFilter::LagEstimate(/*lag=*/kLag1, /*pre_echo_lag=*/kLag1));
diff --git a/modules/audio_processing/aec3/mock/mock_echo_remover.h b/modules/audio_processing/aec3/mock/mock_echo_remover.h
index 31f075e..0be4a65 100644
--- a/modules/audio_processing/aec3/mock/mock_echo_remover.h
+++ b/modules/audio_processing/aec3/mock/mock_echo_remover.h
@@ -11,9 +11,9 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_MOCK_MOCK_ECHO_REMOVER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_MOCK_MOCK_ECHO_REMOVER_H_
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "modules/audio_processing/aec3/echo_path_variability.h"
 #include "modules/audio_processing/aec3/echo_remover.h"
 #include "modules/audio_processing/aec3/render_buffer.h"
@@ -31,7 +31,7 @@
               ProcessCapture,
               (EchoPathVariability echo_path_variability,
                bool capture_signal_saturation,
-               const absl::optional<DelayEstimate>& delay_estimate,
+               const std::optional<DelayEstimate>& delay_estimate,
                RenderBuffer* render_buffer,
                Block* linear_output,
                Block* capture),
diff --git a/modules/audio_processing/aec3/mock/mock_render_delay_controller.h b/modules/audio_processing/aec3/mock/mock_render_delay_controller.h
index 14d499d..3395044 100644
--- a/modules/audio_processing/aec3/mock/mock_render_delay_controller.h
+++ b/modules/audio_processing/aec3/mock/mock_render_delay_controller.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_MOCK_MOCK_RENDER_DELAY_CONTROLLER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_MOCK_MOCK_RENDER_DELAY_CONTROLLER_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/downsampled_render_buffer.h"
 #include "modules/audio_processing/aec3/render_delay_controller.h"
@@ -27,7 +28,7 @@
 
   MOCK_METHOD(void, Reset, (bool reset_delay_statistics), (override));
   MOCK_METHOD(void, LogRenderCall, (), (override));
-  MOCK_METHOD(absl::optional<DelayEstimate>,
+  MOCK_METHOD(std::optional<DelayEstimate>,
               GetDelay,
               (const DownsampledRenderBuffer& render_buffer,
                size_t render_delay_buffer_delay,
diff --git a/modules/audio_processing/aec3/multi_channel_content_detector.cc b/modules/audio_processing/aec3/multi_channel_content_detector.cc
index 9806896..2b07585 100644
--- a/modules/audio_processing/aec3/multi_channel_content_detector.cc
+++ b/modules/audio_processing/aec3/multi_channel_content_detector.cc
@@ -94,9 +94,9 @@
       detection_threshold_(detection_threshold),
       detection_timeout_threshold_frames_(
           stereo_detection_timeout_threshold_seconds > 0
-              ? absl::make_optional(stereo_detection_timeout_threshold_seconds *
-                                    kNumFramesPerSecond)
-              : absl::nullopt),
+              ? std::make_optional(stereo_detection_timeout_threshold_seconds *
+                                   kNumFramesPerSecond)
+              : std::nullopt),
       stereo_detection_hysteresis_frames_(static_cast<int>(
           stereo_detection_hysteresis_seconds * kNumFramesPerSecond)),
       metrics_logger_((detect_stereo_content && num_render_input_channels > 1)
diff --git a/modules/audio_processing/aec3/multi_channel_content_detector.h b/modules/audio_processing/aec3/multi_channel_content_detector.h
index be8717f..2b2f3b8 100644
--- a/modules/audio_processing/aec3/multi_channel_content_detector.h
+++ b/modules/audio_processing/aec3/multi_channel_content_detector.h
@@ -14,10 +14,9 @@
 #include <stddef.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
-
 namespace webrtc {
 
 // Analyzes audio content to determine whether the contained audio is proper
@@ -76,7 +75,7 @@
 
   const bool detect_stereo_content_;
   const float detection_threshold_;
-  const absl::optional<int> detection_timeout_threshold_frames_;
+  const std::optional<int> detection_timeout_threshold_frames_;
   const int stereo_detection_hysteresis_frames_;
 
   // Collects and reports metrics on the amount of multichannel content
diff --git a/modules/audio_processing/aec3/refined_filter_update_gain_unittest.cc b/modules/audio_processing/aec3/refined_filter_update_gain_unittest.cc
index c77c5b5..2a05f18 100644
--- a/modules/audio_processing/aec3/refined_filter_update_gain_unittest.cc
+++ b/modules/audio_processing/aec3/refined_filter_update_gain_unittest.cc
@@ -91,7 +91,7 @@
       RenderDelayBuffer::Create(config, kSampleRateHz, kNumRenderChannels));
   AecState aec_state(config, kNumCaptureChannels);
   RenderSignalAnalyzer render_signal_analyzer(config);
-  absl::optional<DelayEstimate> delay_estimate;
+  std::optional<DelayEstimate> delay_estimate;
   std::array<float, kFftLength> s_scratch;
   std::array<float, kBlockSize> s;
   FftData S;
diff --git a/modules/audio_processing/aec3/render_delay_buffer.cc b/modules/audio_processing/aec3/render_delay_buffer.cc
index ca77a58..f4721d4 100644
--- a/modules/audio_processing/aec3/render_delay_buffer.cc
+++ b/modules/audio_processing/aec3/render_delay_buffer.cc
@@ -17,9 +17,9 @@
 #include <cmath>
 #include <memory>
 #include <numeric>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
@@ -80,7 +80,7 @@
   BlockBuffer blocks_;
   SpectrumBuffer spectra_;
   FftBuffer ffts_;
-  absl::optional<size_t> delay_;
+  std::optional<size_t> delay_;
   RenderBuffer echo_remover_buffer_;
   DownsampledRenderBuffer low_rate_;
   AlignmentMixer render_mixer_;
@@ -95,7 +95,7 @@
   int64_t render_call_counter_ = 0;
   bool render_activity_ = false;
   size_t render_activity_counter_ = 0;
-  absl::optional<int> external_audio_buffer_delay_;
+  std::optional<int> external_audio_buffer_delay_;
   bool external_audio_buffer_delay_verified_after_reset_ = false;
   size_t min_latency_blocks_ = 0;
   size_t excess_render_detection_counter_ = 0;
@@ -193,7 +193,7 @@
     ApplyTotalDelay(config_.delay.default_delay);
 
     // Unset the delays which are set by AlignFromDelay.
-    delay_ = absl::nullopt;
+    delay_ = std::nullopt;
   }
 }
 
diff --git a/modules/audio_processing/aec3/render_delay_controller.cc b/modules/audio_processing/aec3/render_delay_controller.cc
index 465e77f..df594ea 100644
--- a/modules/audio_processing/aec3/render_delay_controller.cc
+++ b/modules/audio_processing/aec3/render_delay_controller.cc
@@ -14,8 +14,8 @@
 #include <algorithm>
 #include <atomic>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
@@ -44,7 +44,7 @@
   ~RenderDelayControllerImpl() override;
   void Reset(bool reset_delay_confidence) override;
   void LogRenderCall() override;
-  absl::optional<DelayEstimate> GetDelay(
+  std::optional<DelayEstimate> GetDelay(
       const DownsampledRenderBuffer& render_buffer,
       size_t render_delay_buffer_delay,
       const Block& capture) override;
@@ -54,17 +54,17 @@
   static std::atomic<int> instance_count_;
   std::unique_ptr<ApmDataDumper> data_dumper_;
   const int hysteresis_limit_blocks_;
-  absl::optional<DelayEstimate> delay_;
+  std::optional<DelayEstimate> delay_;
   EchoPathDelayEstimator delay_estimator_;
   RenderDelayControllerMetrics metrics_;
-  absl::optional<DelayEstimate> delay_samples_;
+  std::optional<DelayEstimate> delay_samples_;
   size_t capture_call_counter_ = 0;
   int delay_change_counter_ = 0;
   DelayEstimate::Quality last_delay_estimate_quality_;
 };
 
 DelayEstimate ComputeBufferDelay(
-    const absl::optional<DelayEstimate>& current_delay,
+    const std::optional<DelayEstimate>& current_delay,
     int hysteresis_limit_blocks,
     DelayEstimate estimated_delay) {
   // Compute the buffer delay increase required to achieve the desired latency.
@@ -100,8 +100,8 @@
 RenderDelayControllerImpl::~RenderDelayControllerImpl() = default;
 
 void RenderDelayControllerImpl::Reset(bool reset_delay_confidence) {
-  delay_ = absl::nullopt;
-  delay_samples_ = absl::nullopt;
+  delay_ = std::nullopt;
+  delay_samples_ = std::nullopt;
   delay_estimator_.Reset(reset_delay_confidence);
   delay_change_counter_ = 0;
   if (reset_delay_confidence) {
@@ -111,7 +111,7 @@
 
 void RenderDelayControllerImpl::LogRenderCall() {}
 
-absl::optional<DelayEstimate> RenderDelayControllerImpl::GetDelay(
+std::optional<DelayEstimate> RenderDelayControllerImpl::GetDelay(
     const DownsampledRenderBuffer& render_buffer,
     size_t render_delay_buffer_delay,
     const Block& capture) {
@@ -155,11 +155,10 @@
     last_delay_estimate_quality_ = delay_samples_->quality;
   }
 
-  metrics_.Update(
-      delay_samples_ ? absl::optional<size_t>(delay_samples_->delay)
-                     : absl::nullopt,
-      delay_ ? absl::optional<size_t>(delay_->delay) : absl::nullopt,
-      delay_estimator_.Clockdrift());
+  metrics_.Update(delay_samples_ ? std::optional<size_t>(delay_samples_->delay)
+                                 : std::nullopt,
+                  delay_ ? std::optional<size_t>(delay_->delay) : std::nullopt,
+                  delay_estimator_.Clockdrift());
 
   data_dumper_->DumpRaw("aec3_render_delay_controller_delay",
                         delay_samples ? delay_samples->delay : 0);
diff --git a/modules/audio_processing/aec3/render_delay_controller.h b/modules/audio_processing/aec3/render_delay_controller.h
index 4a18a11..b74c161 100644
--- a/modules/audio_processing/aec3/render_delay_controller.h
+++ b/modules/audio_processing/aec3/render_delay_controller.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_RENDER_DELAY_CONTROLLER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_RENDER_DELAY_CONTROLLER_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/block.h"
@@ -38,7 +39,7 @@
   virtual void LogRenderCall() = 0;
 
   // Aligns the render buffer content with the capture signal.
-  virtual absl::optional<DelayEstimate> GetDelay(
+  virtual std::optional<DelayEstimate> GetDelay(
       const DownsampledRenderBuffer& render_buffer,
       size_t render_delay_buffer_delay,
       const Block& capture) = 0;
diff --git a/modules/audio_processing/aec3/render_delay_controller_metrics.cc b/modules/audio_processing/aec3/render_delay_controller_metrics.cc
index 1e0a0f4..8d3f415 100644
--- a/modules/audio_processing/aec3/render_delay_controller_metrics.cc
+++ b/modules/audio_processing/aec3/render_delay_controller_metrics.cc
@@ -42,8 +42,8 @@
 RenderDelayControllerMetrics::RenderDelayControllerMetrics() = default;
 
 void RenderDelayControllerMetrics::Update(
-    absl::optional<size_t> delay_samples,
-    absl::optional<size_t> buffer_delay_blocks,
+    std::optional<size_t> delay_samples,
+    std::optional<size_t> buffer_delay_blocks,
     ClockdriftDetector::Level clockdrift) {
   ++call_counter_;
 
diff --git a/modules/audio_processing/aec3/render_delay_controller_metrics.h b/modules/audio_processing/aec3/render_delay_controller_metrics.h
index b81833b..0a6f30e 100644
--- a/modules/audio_processing/aec3/render_delay_controller_metrics.h
+++ b/modules/audio_processing/aec3/render_delay_controller_metrics.h
@@ -13,7 +13,8 @@
 
 #include <stddef.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/audio_processing/aec3/clockdrift_detector.h"
 
 namespace webrtc {
@@ -28,8 +29,8 @@
       delete;
 
   // Updates the metric with new data.
-  void Update(absl::optional<size_t> delay_samples,
-              absl::optional<size_t> buffer_delay_blocks,
+  void Update(std::optional<size_t> delay_samples,
+              std::optional<size_t> buffer_delay_blocks,
               ClockdriftDetector::Level clockdrift);
 
  private:
diff --git a/modules/audio_processing/aec3/render_delay_controller_metrics_unittest.cc b/modules/audio_processing/aec3/render_delay_controller_metrics_unittest.cc
index cf9df6b..22739e7 100644
--- a/modules/audio_processing/aec3/render_delay_controller_metrics_unittest.cc
+++ b/modules/audio_processing/aec3/render_delay_controller_metrics_unittest.cc
@@ -10,7 +10,8 @@
 
 #include "modules/audio_processing/aec3/render_delay_controller_metrics.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "system_wrappers/include/metrics.h"
 #include "test/gtest.h"
@@ -27,7 +28,7 @@
 
   for (int j = 0; j < 3; ++j) {
     for (int k = 0; k < kMetricsReportingIntervalBlocks - 1; ++k) {
-      metrics.Update(absl::nullopt, absl::nullopt,
+      metrics.Update(std::nullopt, std::nullopt,
                      ClockdriftDetector::Level::kNone);
     }
     EXPECT_METRIC_EQ(
@@ -49,7 +50,7 @@
     // We expect metric reports every kMetricsReportingIntervalBlocks blocks.
     ++expected_num_metric_reports;
 
-    metrics.Update(absl::nullopt, absl::nullopt,
+    metrics.Update(std::nullopt, std::nullopt,
                    ClockdriftDetector::Level::kNone);
     EXPECT_METRIC_EQ(
         metrics::NumSamples("WebRTC.Audio.EchoCanceller.EchoPathDelay"),
diff --git a/modules/audio_processing/aec3/render_delay_controller_unittest.cc b/modules/audio_processing/aec3/render_delay_controller_unittest.cc
index e1a54fc..adb5344 100644
--- a/modules/audio_processing/aec3/render_delay_controller_unittest.cc
+++ b/modules/audio_processing/aec3/render_delay_controller_unittest.cc
@@ -85,7 +85,7 @@
   for (size_t num_capture_channels : {1, 2, 4}) {
     for (size_t num_render_channels : {1, 2, 8}) {
       Block capture_block(/*num_bands=*/1, num_capture_channels);
-      absl::optional<DelayEstimate> delay_blocks;
+      std::optional<DelayEstimate> delay_blocks;
       for (size_t num_matched_filters = 4; num_matched_filters <= 10;
            num_matched_filters++) {
         for (auto down_sampling_factor : kDownSamplingFactors) {
@@ -140,7 +140,7 @@
             Block render_block(NumBandsForRate(rate), num_render_channels);
 
             for (size_t delay_samples : {15, 50, 150, 200, 800, 4000}) {
-              absl::optional<DelayEstimate> delay_blocks;
+              std::optional<DelayEstimate> delay_blocks;
               SCOPED_TRACE(ProduceDebugText(rate, delay_samples,
                                             num_render_channels,
                                             num_capture_channels));
@@ -203,7 +203,7 @@
             Block capture_block(NumBandsForRate(rate), num_capture_channels);
 
             for (int delay_samples : {-15, -50, -150, -200}) {
-              absl::optional<DelayEstimate> delay_blocks;
+              std::optional<DelayEstimate> delay_blocks;
               SCOPED_TRACE(ProduceDebugText(rate, -delay_samples,
                                             num_render_channels,
                                             num_capture_channels));
@@ -259,7 +259,7 @@
           for (auto rate : {16000, 32000, 48000}) {
             Block render_block(NumBandsForRate(rate), num_render_channels);
             for (size_t delay_samples : {15, 50, 300, 800}) {
-              absl::optional<DelayEstimate> delay_blocks;
+              std::optional<DelayEstimate> delay_blocks;
               SCOPED_TRACE(ProduceDebugText(rate, delay_samples,
                                             num_render_channels,
                                             num_capture_channels));
diff --git a/modules/audio_processing/aec3/render_signal_analyzer.cc b/modules/audio_processing/aec3/render_signal_analyzer.cc
index bfbeb0e..a3e78e4 100644
--- a/modules/audio_processing/aec3/render_signal_analyzer.cc
+++ b/modules/audio_processing/aec3/render_signal_analyzer.cc
@@ -27,7 +27,7 @@
 // Identifies local bands with narrow characteristics.
 void IdentifySmallNarrowBandRegions(
     const RenderBuffer& render_buffer,
-    const absl::optional<size_t>& delay_partitions,
+    const std::optional<size_t>& delay_partitions,
     std::array<size_t, kFftLengthBy2 - 1>* narrow_band_counters) {
   RTC_DCHECK(narrow_band_counters);
 
@@ -56,14 +56,14 @@
 // Identifies whether the signal has a single strong narrow-band component.
 void IdentifyStrongNarrowBandComponent(const RenderBuffer& render_buffer,
                                        int strong_peak_freeze_duration,
-                                       absl::optional<int>* narrow_peak_band,
+                                       std::optional<int>* narrow_peak_band,
                                        size_t* narrow_peak_counter) {
   RTC_DCHECK(narrow_peak_band);
   RTC_DCHECK(narrow_peak_counter);
   if (*narrow_peak_band &&
       ++(*narrow_peak_counter) >
           static_cast<size_t>(strong_peak_freeze_duration)) {
-    *narrow_peak_band = absl::nullopt;
+    *narrow_peak_band = std::nullopt;
   }
 
   const Block& x_latest = render_buffer.GetBlock(0);
@@ -125,7 +125,7 @@
 
 void RenderSignalAnalyzer::Update(
     const RenderBuffer& render_buffer,
-    const absl::optional<size_t>& delay_partitions) {
+    const std::optional<size_t>& delay_partitions) {
   // Identify bands of narrow nature.
   IdentifySmallNarrowBandRegions(render_buffer, delay_partitions,
                                  &narrow_band_counters_);
diff --git a/modules/audio_processing/aec3/render_signal_analyzer.h b/modules/audio_processing/aec3/render_signal_analyzer.h
index 2e4aaa4..058b292 100644
--- a/modules/audio_processing/aec3/render_signal_analyzer.h
+++ b/modules/audio_processing/aec3/render_signal_analyzer.h
@@ -14,8 +14,8 @@
 #include <algorithm>
 #include <array>
 #include <cstddef>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/aec3/render_buffer.h"
@@ -34,7 +34,7 @@
 
   // Updates the render signal analysis with the most recent render signal.
   void Update(const RenderBuffer& render_buffer,
-              const absl::optional<size_t>& delay_partitions);
+              const std::optional<size_t>& delay_partitions);
 
   // Returns true if the render signal is poorly exciting.
   bool PoorSignalExcitation() const {
@@ -48,12 +48,12 @@
   void MaskRegionsAroundNarrowBands(
       std::array<float, kFftLengthBy2Plus1>* v) const;
 
-  absl::optional<int> NarrowPeakBand() const { return narrow_peak_band_; }
+  std::optional<int> NarrowPeakBand() const { return narrow_peak_band_; }
 
  private:
   const int strong_peak_freeze_duration_;
   std::array<size_t, kFftLengthBy2 - 1> narrow_band_counters_;
-  absl::optional<int> narrow_peak_band_;
+  std::optional<int> narrow_peak_band_;
   size_t narrow_peak_counter_;
 };
 
diff --git a/modules/audio_processing/aec3/render_signal_analyzer_unittest.cc b/modules/audio_processing/aec3/render_signal_analyzer_unittest.cc
index 16f6280..ca428ba 100644
--- a/modules/audio_processing/aec3/render_signal_analyzer_unittest.cc
+++ b/modules/audio_processing/aec3/render_signal_analyzer_unittest.cc
@@ -84,7 +84,7 @@
       render_delay_buffer->PrepareCaptureProcessing();
 
       analyzer.Update(*render_delay_buffer->GetRenderBuffer(),
-                      known_delay ? absl::optional<size_t>(0) : absl::nullopt);
+                      known_delay ? std::optional<size_t>(0) : std::nullopt);
     }
   };
 
@@ -149,7 +149,7 @@
       render_delay_buffer->PrepareCaptureProcessing();
 
       analyzer.Update(*render_delay_buffer->GetRenderBuffer(),
-                      absl::optional<size_t>(0));
+                      std::optional<size_t>(0));
     }
 
     mask.fill(1.f);
diff --git a/modules/audio_processing/aec3/residual_echo_estimator.h b/modules/audio_processing/aec3/residual_echo_estimator.h
index c468764..3bed698 100644
--- a/modules/audio_processing/aec3/residual_echo_estimator.h
+++ b/modules/audio_processing/aec3/residual_echo_estimator.h
@@ -13,8 +13,8 @@
 
 #include <array>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/aec3/aec_state.h"
diff --git a/modules/audio_processing/aec3/residual_echo_estimator_unittest.cc b/modules/audio_processing/aec3/residual_echo_estimator_unittest.cc
index 9a7bf0a..6ca5bd4 100644
--- a/modules/audio_processing/aec3/residual_echo_estimator_unittest.cc
+++ b/modules/audio_processing/aec3/residual_echo_estimator_unittest.cc
@@ -120,7 +120,7 @@
   Random random_generator_;
   std::vector<SubtractorOutput> output_;
   std::array<float, kBlockSize> y_;
-  absl::optional<DelayEstimate> delay_estimate_;
+  std::optional<DelayEstimate> delay_estimate_;
   bool first_frame_ = true;
 };
 
diff --git a/modules/audio_processing/aec3/reverb_decay_estimator.cc b/modules/audio_processing/aec3/reverb_decay_estimator.cc
index 2daf376..ddff1c9 100644
--- a/modules/audio_processing/aec3/reverb_decay_estimator.cc
+++ b/modules/audio_processing/aec3/reverb_decay_estimator.cc
@@ -102,7 +102,7 @@
 ReverbDecayEstimator::~ReverbDecayEstimator() = default;
 
 void ReverbDecayEstimator::Update(rtc::ArrayView<const float> filter,
-                                  const absl::optional<float>& filter_quality,
+                                  const std::optional<float>& filter_quality,
                                   int filter_delay_blocks,
                                   bool usable_linear_filter,
                                   bool stationary_signal) {
diff --git a/modules/audio_processing/aec3/reverb_decay_estimator.h b/modules/audio_processing/aec3/reverb_decay_estimator.h
index fee5421..6d9d849 100644
--- a/modules/audio_processing/aec3/reverb_decay_estimator.h
+++ b/modules/audio_processing/aec3/reverb_decay_estimator.h
@@ -12,9 +12,9 @@
 #define MODULES_AUDIO_PROCESSING_AEC3_REVERB_DECAY_ESTIMATOR_H_
 
 #include <array>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/aec3_common.h"  // kMaxAdaptiveFilter...
 
@@ -30,7 +30,7 @@
   ~ReverbDecayEstimator();
   // Updates the decay estimate.
   void Update(rtc::ArrayView<const float> filter,
-              const absl::optional<float>& filter_quality,
+              const std::optional<float>& filter_quality,
               int filter_delay_blocks,
               bool usable_linear_filter,
               bool stationary_signal);
diff --git a/modules/audio_processing/aec3/reverb_frequency_response.cc b/modules/audio_processing/aec3/reverb_frequency_response.cc
index 6e7282a..e96930a 100644
--- a/modules/audio_processing/aec3/reverb_frequency_response.cc
+++ b/modules/audio_processing/aec3/reverb_frequency_response.cc
@@ -62,7 +62,7 @@
     const std::vector<std::array<float, kFftLengthBy2Plus1>>&
         frequency_response,
     int filter_delay_blocks,
-    const absl::optional<float>& linear_filter_quality,
+    const std::optional<float>& linear_filter_quality,
     bool stationary_block) {
   if (stationary_block || !linear_filter_quality) {
     return;
diff --git a/modules/audio_processing/aec3/reverb_frequency_response.h b/modules/audio_processing/aec3/reverb_frequency_response.h
index 69b16b5..8bb9313 100644
--- a/modules/audio_processing/aec3/reverb_frequency_response.h
+++ b/modules/audio_processing/aec3/reverb_frequency_response.h
@@ -12,9 +12,9 @@
 #define MODULES_AUDIO_PROCESSING_AEC3_REVERB_FREQUENCY_RESPONSE_H_
 
 #include <array>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 
@@ -31,7 +31,7 @@
   void Update(const std::vector<std::array<float, kFftLengthBy2Plus1>>&
                   frequency_response,
               int filter_delay_blocks,
-              const absl::optional<float>& linear_filter_quality,
+              const std::optional<float>& linear_filter_quality,
               bool stationary_block);
 
   // Returns the estimated frequency response for the reverb.
diff --git a/modules/audio_processing/aec3/reverb_model_estimator.cc b/modules/audio_processing/aec3/reverb_model_estimator.cc
index 5cd7a78..8a815e6 100644
--- a/modules/audio_processing/aec3/reverb_model_estimator.cc
+++ b/modules/audio_processing/aec3/reverb_model_estimator.cc
@@ -31,7 +31,7 @@
     rtc::ArrayView<const std::vector<float>> impulse_responses,
     rtc::ArrayView<const std::vector<std::array<float, kFftLengthBy2Plus1>>>
         frequency_responses,
-    rtc::ArrayView<const absl::optional<float>> linear_filter_qualities,
+    rtc::ArrayView<const std::optional<float>> linear_filter_qualities,
     rtc::ArrayView<const int> filter_delays_blocks,
     const std::vector<bool>& usable_linear_estimates,
     bool stationary_block) {
diff --git a/modules/audio_processing/aec3/reverb_model_estimator.h b/modules/audio_processing/aec3/reverb_model_estimator.h
index 63bade9..550239c 100644
--- a/modules/audio_processing/aec3/reverb_model_estimator.h
+++ b/modules/audio_processing/aec3/reverb_model_estimator.h
@@ -13,9 +13,9 @@
 
 #include <array>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"  // kFftLengthBy2Plus1
@@ -38,7 +38,7 @@
       rtc::ArrayView<const std::vector<float>> impulse_responses,
       rtc::ArrayView<const std::vector<std::array<float, kFftLengthBy2Plus1>>>
           frequency_responses,
-      rtc::ArrayView<const absl::optional<float>> linear_filter_qualities,
+      rtc::ArrayView<const std::optional<float>> linear_filter_qualities,
       rtc::ArrayView<const int> filter_delays_blocks,
       const std::vector<bool>& usable_linear_estimates,
       bool stationary_block);
diff --git a/modules/audio_processing/aec3/reverb_model_estimator_unittest.cc b/modules/audio_processing/aec3/reverb_model_estimator_unittest.cc
index fb7dcef..f1c962a 100644
--- a/modules/audio_processing/aec3/reverb_model_estimator_unittest.cc
+++ b/modules/audio_processing/aec3/reverb_model_estimator_unittest.cc
@@ -14,9 +14,9 @@
 #include <array>
 #include <cmath>
 #include <numeric>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
@@ -74,7 +74,7 @@
   float true_power_tail_ = 0.f;
   std::vector<std::vector<float>> h_;
   std::vector<std::vector<std::array<float, kFftLengthBy2Plus1>>> H2_;
-  std::vector<absl::optional<float>> quality_linear_;
+  std::vector<std::optional<float>> quality_linear_;
 };
 
 void ReverbModelEstimatorTest::CreateImpulseResponseWithDecay() {
diff --git a/modules/audio_processing/aec3/subtractor_unittest.cc b/modules/audio_processing/aec3/subtractor_unittest.cc
index 56b9cec..718bee0 100644
--- a/modules/audio_processing/aec3/subtractor_unittest.cc
+++ b/modules/audio_processing/aec3/subtractor_unittest.cc
@@ -44,7 +44,7 @@
 
   Subtractor subtractor(config, num_render_channels, num_capture_channels,
                         &data_dumper, DetectOptimization());
-  absl::optional<DelayEstimate> delay_estimate;
+  std::optional<DelayEstimate> delay_estimate;
   Block x(kNumBands, num_render_channels);
   Block y(/*num_bands=*/1, num_capture_channels);
   std::array<float, kBlockSize> x_old;
diff --git a/modules/audio_processing/aec3/suppression_gain.cc b/modules/audio_processing/aec3/suppression_gain.cc
index 037daba..26797fc 100644
--- a/modules/audio_processing/aec3/suppression_gain.cc
+++ b/modules/audio_processing/aec3/suppression_gain.cc
@@ -107,7 +107,7 @@
     rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> echo_spectrum,
     rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>>
         comfort_noise_spectrum,
-    const absl::optional<int>& narrow_peak_band,
+    const std::optional<int>& narrow_peak_band,
     bool saturated_echo,
     const Block& render,
     const std::array<float, kFftLengthBy2Plus1>& low_band_gain) const {
@@ -394,7 +394,7 @@
                 low_band_gain);
 
   // Compute the gain for the upper bands.
-  const absl::optional<int> narrow_peak_band =
+  const std::optional<int> narrow_peak_band =
       render_signal_analyzer.NarrowPeakBand();
 
   *high_bands_gain =
diff --git a/modules/audio_processing/aec3/suppression_gain.h b/modules/audio_processing/aec3/suppression_gain.h
index c19ddd7..806334c 100644
--- a/modules/audio_processing/aec3/suppression_gain.h
+++ b/modules/audio_processing/aec3/suppression_gain.h
@@ -14,9 +14,9 @@
 #include <array>
 #include <atomic>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
@@ -70,7 +70,7 @@
       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>> echo_spectrum,
       rtc::ArrayView<const std::array<float, kFftLengthBy2Plus1>>
           comfort_noise_spectrum,
-      const absl::optional<int>& narrow_peak_band,
+      const std::optional<int>& narrow_peak_band,
       bool saturated_echo,
       const Block& render,
       const std::array<float, kFftLengthBy2Plus1>& low_band_gain) const;
diff --git a/modules/audio_processing/aec3/suppression_gain_unittest.cc b/modules/audio_processing/aec3/suppression_gain_unittest.cc
index 02de706..bb50200 100644
--- a/modules/audio_processing/aec3/suppression_gain_unittest.cc
+++ b/modules/audio_processing/aec3/suppression_gain_unittest.cc
@@ -81,7 +81,7 @@
                         &data_dumper, DetectOptimization());
   std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
       RenderDelayBuffer::Create(config, kSampleRateHz, kNumRenderChannels));
-  absl::optional<DelayEstimate> delay_estimate;
+  std::optional<DelayEstimate> delay_estimate;
 
   // Ensure that a strong noise is detected to mask any echoes.
   for (size_t ch = 0; ch < kNumCaptureChannels; ++ch) {
diff --git a/modules/audio_processing/agc/BUILD.gn b/modules/audio_processing/agc/BUILD.gn
index 1616f54..f5bb272 100644
--- a/modules/audio_processing/agc/BUILD.gn
+++ b/modules/audio_processing/agc/BUILD.gn
@@ -38,7 +38,6 @@
     "../agc2:gain_map",
     "../agc2:input_volume_stats_reporter",
     "../vad",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/modules/audio_processing/agc/agc_manager_direct.cc b/modules/audio_processing/agc/agc_manager_direct.cc
index b8ad4a8..18d84d8 100644
--- a/modules/audio_processing/agc/agc_manager_direct.cc
+++ b/modules/audio_processing/agc/agc_manager_direct.cc
@@ -69,11 +69,11 @@
 // string. Returns an unspecified value if the field trial is not specified, if
 // disabled or if it cannot be parsed. Example:
 // 'WebRTC-Audio-2ndAgcMinMicLevelExperiment/Enabled-80' => returns 80.
-absl::optional<int> GetMinMicLevelOverride() {
+std::optional<int> GetMinMicLevelOverride() {
   constexpr char kMinMicLevelFieldTrial[] =
       "WebRTC-Audio-2ndAgcMinMicLevelExperiment";
   if (!webrtc::field_trial::IsEnabled(kMinMicLevelFieldTrial)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   const auto field_trial_string =
       webrtc::field_trial::FindFullName(kMinMicLevelFieldTrial);
@@ -84,7 +84,7 @@
   } else {
     RTC_LOG(LS_WARNING) << "[agc] Invalid parameter for "
                         << kMinMicLevelFieldTrial << ", ignored.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 }
 
@@ -189,8 +189,8 @@
 }
 
 void MonoAgc::Process(rtc::ArrayView<const int16_t> audio,
-                      absl::optional<int> rms_error_override) {
-  new_compression_to_set_ = absl::nullopt;
+                      std::optional<int> rms_error_override) {
+  new_compression_to_set_ = std::nullopt;
 
   if (check_volume_on_next_process_) {
     check_volume_on_next_process_ = false;
@@ -617,13 +617,13 @@
 }
 
 void AgcManagerDirect::Process(const AudioBuffer& audio_buffer) {
-  Process(audio_buffer, /*speech_probability=*/absl::nullopt,
-          /*speech_level_dbfs=*/absl::nullopt);
+  Process(audio_buffer, /*speech_probability=*/std::nullopt,
+          /*speech_level_dbfs=*/std::nullopt);
 }
 
 void AgcManagerDirect::Process(const AudioBuffer& audio_buffer,
-                               absl::optional<float> speech_probability,
-                               absl::optional<float> speech_level_dbfs) {
+                               std::optional<float> speech_probability,
+                               std::optional<float> speech_level_dbfs) {
   AggregateChannelLevels();
   const int volume_after_clipping_handling = recommended_input_volume_;
 
@@ -632,7 +632,7 @@
   }
 
   const size_t num_frames_per_band = audio_buffer.num_frames_per_band();
-  absl::optional<int> rms_error_override = absl::nullopt;
+  std::optional<int> rms_error_override = std::nullopt;
   if (speech_probability.has_value() && speech_level_dbfs.has_value()) {
     rms_error_override =
         GetSpeechLevelErrorDb(*speech_level_dbfs, *speech_probability);
@@ -656,7 +656,7 @@
   }
 }
 
-absl::optional<int> AgcManagerDirect::GetDigitalComressionGain() {
+std::optional<int> AgcManagerDirect::GetDigitalComressionGain() {
   return new_compressions_to_set_[channel_controlling_gain_];
 }
 
diff --git a/modules/audio_processing/agc/agc_manager_direct.h b/modules/audio_processing/agc/agc_manager_direct.h
index 62b0e0e..db2d27b 100644
--- a/modules/audio_processing/agc/agc_manager_direct.h
+++ b/modules/audio_processing/agc/agc_manager_direct.h
@@ -13,8 +13,8 @@
 
 #include <atomic>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/audio_processing.h"
 #include "modules/audio_processing/agc/agc.h"
@@ -75,8 +75,8 @@
   // TODO(webrtc:7494): This signature is needed for testing purposes, unify
   // the signatures when the clean-up is done.
   void Process(const AudioBuffer& audio_buffer,
-               absl::optional<float> speech_probability,
-               absl::optional<float> speech_level_dbfs);
+               std::optional<float> speech_probability,
+               std::optional<float> speech_level_dbfs);
 
   // Processes `audio_buffer`. Chooses a digital compression gain and the new
   // input volume to recommend. Must be called after `AnalyzePreProcess()`.
@@ -100,7 +100,7 @@
 
   // If available, returns the latest digital compression gain that has been
   // chosen.
-  absl::optional<int> GetDigitalComressionGain();
+  std::optional<int> GetDigitalComressionGain();
 
   // Returns true if clipping prediction is enabled.
   bool clipping_predictor_enabled() const { return !!clipping_predictor_; }
@@ -150,7 +150,7 @@
 
   const bool analog_controller_enabled_;
 
-  const absl::optional<int> min_mic_level_override_;
+  const std::optional<int> min_mic_level_override_;
   std::unique_ptr<ApmDataDumper> data_dumper_;
   static std::atomic<int> instance_counter_;
   const int num_capture_channels_;
@@ -176,7 +176,7 @@
   const int clipped_wait_frames_;
 
   std::vector<std::unique_ptr<MonoAgc>> channel_agcs_;
-  std::vector<absl::optional<int>> new_compressions_to_set_;
+  std::vector<std::optional<int>> new_compressions_to_set_;
 
   const std::unique_ptr<ClippingPredictor> clipping_predictor_;
   const bool use_clipping_predictor_step_;
@@ -213,16 +213,14 @@
   // after `HandleClipping()`. If `rms_error_override` has a value, RMS error
   // from AGC is overridden by it.
   void Process(rtc::ArrayView<const int16_t> audio,
-               absl::optional<int> rms_error_override);
+               std::optional<int> rms_error_override);
 
   // Returns the recommended input volume. Must be called after `Process()`.
   int recommended_analog_level() const { return recommended_input_volume_; }
 
   float voice_probability() const { return agc_->voice_probability(); }
   void ActivateLogging() { log_to_histograms_ = true; }
-  absl::optional<int> new_compression() const {
-    return new_compression_to_set_;
-  }
+  std::optional<int> new_compression() const { return new_compression_to_set_; }
 
   // Only used for testing.
   void set_agc(Agc* agc) { agc_.reset(agc); }
@@ -263,7 +261,7 @@
   // recommended input volume.
   int recommended_input_volume_ = 0;
 
-  absl::optional<int> new_compression_to_set_;
+  std::optional<int> new_compression_to_set_;
   bool log_to_histograms_ = false;
   const int clipped_level_min_;
 
diff --git a/modules/audio_processing/agc/agc_manager_direct_unittest.cc b/modules/audio_processing/agc/agc_manager_direct_unittest.cc
index 70ac0b5..3b6ae72 100644
--- a/modules/audio_processing/agc/agc_manager_direct_unittest.cc
+++ b/modules/audio_processing/agc/agc_manager_direct_unittest.cc
@@ -160,7 +160,7 @@
 }
 
 std::string GetAgcMinMicLevelExperimentFieldTrial(
-    absl::optional<int> min_mic_level) {
+    std::optional<int> min_mic_level) {
   if (min_mic_level.has_value()) {
     return GetAgcMinMicLevelExperimentFieldTrialEnabled(*min_mic_level);
   }
@@ -196,8 +196,8 @@
 // `AgcManagerDirectTestHelper::CallAgcSequence()` instead.
 void CallPreProcessAndProcess(int num_calls,
                               const AudioBuffer& audio_buffer,
-                              absl::optional<float> speech_probability_override,
-                              absl::optional<float> speech_level_override,
+                              std::optional<float> speech_probability_override,
+                              std::optional<float> speech_level_override,
                               AgcManagerDirect& manager) {
   for (int n = 0; n < num_calls; ++n) {
     manager.AnalyzePreProcess(audio_buffer);
@@ -266,8 +266,8 @@
   // have a value.
   void Feed(int num_frames,
             int gain_db,
-            absl::optional<float> speech_probability_override,
-            absl::optional<float> speech_level_override,
+            std::optional<float> speech_probability_override,
+            std::optional<float> speech_level_override,
             AgcManagerDirect& agc) {
     float gain = std::pow(10.0f, gain_db / 20.0f);  // From dB to linear gain.
     is_.seekg(0, is_.beg);  // Start from the beginning of the PCM file.
@@ -353,13 +353,13 @@
   // AGC is replaced by an override value if `speech_probability_override`
   // and `speech_level_override` have a value.
   int CallAgcSequence(int applied_input_volume,
-                      absl::optional<float> speech_probability_override,
-                      absl::optional<float> speech_level_override) {
+                      std::optional<float> speech_probability_override,
+                      std::optional<float> speech_level_override) {
     manager.set_stream_analog_level(applied_input_volume);
     manager.AnalyzePreProcess(audio_buffer);
     manager.Process(audio_buffer, speech_probability_override,
                     speech_level_override);
-    absl::optional<int> digital_gain = manager.GetDigitalComressionGain();
+    std::optional<int> digital_gain = manager.GetDigitalComressionGain();
     if (digital_gain) {
       mock_gain_control.set_compression_gain_db(*digital_gain);
     }
@@ -372,13 +372,13 @@
   // value if `speech_probability_override` and `speech_level_override` have
   // a value.
   void CallProcess(int num_calls,
-                   absl::optional<float> speech_probability_override,
-                   absl::optional<float> speech_level_override) {
+                   std::optional<float> speech_probability_override,
+                   std::optional<float> speech_level_override) {
     for (int i = 0; i < num_calls; ++i) {
       EXPECT_CALL(*mock_agc, Process(_)).WillOnce(Return());
       manager.Process(audio_buffer, speech_probability_override,
                       speech_level_override);
-      absl::optional<int> new_digital_gain = manager.GetDigitalComressionGain();
+      std::optional<int> new_digital_gain = manager.GetDigitalComressionGain();
       if (new_digital_gain) {
         mock_gain_control.set_compression_gain_db(*new_digital_gain);
       }
@@ -435,7 +435,7 @@
 };
 
 class AgcManagerDirectParametrizedTest
-    : public ::testing::TestWithParam<std::tuple<absl::optional<int>, bool>> {
+    : public ::testing::TestWithParam<std::tuple<std::optional<int>, bool>> {
  protected:
   AgcManagerDirectParametrizedTest()
       : field_trials_(
@@ -449,9 +449,8 @@
   }
 
   bool IsRmsErrorOverridden() const { return std::get<1>(GetParam()); }
-  absl::optional<float> GetOverrideOrEmpty(float value) const {
-    return IsRmsErrorOverridden() ? absl::optional<float>(value)
-                                  : absl::nullopt;
+  std::optional<float> GetOverrideOrEmpty(float value) const {
+    return IsRmsErrorOverridden() ? std::optional<float>(value) : std::nullopt;
   }
 
  private:
@@ -461,8 +460,7 @@
 INSTANTIATE_TEST_SUITE_P(
     ,
     AgcManagerDirectParametrizedTest,
-    ::testing::Combine(testing::Values(absl::nullopt, 12, 20),
-                       testing::Bool()));
+    ::testing::Combine(testing::Values(std::nullopt, 12, 20), testing::Bool()));
 
 // Checks that when the analog controller is disabled, no downward adaptation
 // takes place.
@@ -706,7 +704,7 @@
 }
 
 TEST_P(AgcManagerDirectParametrizedTest, CompressorStepsTowardsTarget) {
-  constexpr absl::optional<float> kNoOverride = absl::nullopt;
+  constexpr std::optional<float> kNoOverride = std::nullopt;
   const auto speech_probability_override =
       GetOverrideOrEmpty(kHighSpeechProbability);
 
@@ -723,7 +721,7 @@
                      GetOverrideOrEmpty(-23.0f));
   EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(_)).Times(0);
   // The mock `GetRmsErrorDb()` returns false; mimic this by passing
-  // absl::nullopt as an override.
+  // std::nullopt as an override.
   helper.CallProcess(/*num_calls=*/19, kNoOverride, kNoOverride);
 
   // Moves slowly upwards.
@@ -778,7 +776,7 @@
 }
 
 TEST_P(AgcManagerDirectParametrizedTest, CompressorErrorIsDeemphasized) {
-  constexpr absl::optional<float> kNoOverride = absl::nullopt;
+  constexpr std::optional<float> kNoOverride = std::nullopt;
   const auto speech_probability_override =
       GetOverrideOrEmpty(kHighSpeechProbability);
 
@@ -792,7 +790,7 @@
   helper.CallProcess(/*num_calls=*/1, speech_probability_override,
                      GetOverrideOrEmpty(-28.0f));
   // The mock `GetRmsErrorDb()` returns false; mimic this by passing
-  // absl::nullopt as an override.
+  // std::nullopt as an override.
   helper.CallProcess(/*num_calls=*/18, kNoOverride, kNoOverride);
   EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(8))
       .WillOnce(Return(0));
@@ -823,7 +821,7 @@
 }
 
 TEST_P(AgcManagerDirectParametrizedTest, CompressorReachesMaximum) {
-  constexpr absl::optional<float> kNoOverride = absl::nullopt;
+  constexpr std::optional<float> kNoOverride = std::nullopt;
   const auto speech_probability_override =
       GetOverrideOrEmpty(kHighSpeechProbability);
 
@@ -840,7 +838,7 @@
   helper.CallProcess(/*num_calls=*/4, speech_probability_override,
                      GetOverrideOrEmpty(-28.0f));
   // The mock `GetRmsErrorDb()` returns false; mimic this by passing
-  // absl::nullopt as an override.
+  // std::nullopt as an override.
   helper.CallProcess(/*num_calls=*/15, kNoOverride, kNoOverride);
   EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(8))
       .WillOnce(Return(0));
@@ -860,7 +858,7 @@
 }
 
 TEST_P(AgcManagerDirectParametrizedTest, CompressorReachesMinimum) {
-  constexpr absl::optional<float> kNoOverride = absl::nullopt;
+  constexpr std::optional<float> kNoOverride = std::nullopt;
   const auto speech_probability_override =
       GetOverrideOrEmpty(kHighSpeechProbability);
 
@@ -877,7 +875,7 @@
   helper.CallProcess(/*num_calls=*/4, speech_probability_override,
                      GetOverrideOrEmpty(-18.0f));
   // The mock `GetRmsErrorDb()` returns false; mimic this by passing
-  // absl::nullopt as an override.
+  // std::nullopt as an override.
   helper.CallProcess(/*num_calls=*/15, kNoOverride, kNoOverride);
   EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(6))
       .WillOnce(Return(0));
@@ -907,7 +905,7 @@
                          GetOverrideOrEmpty(kHighSpeechProbability),
                          GetOverrideOrEmpty(kSpeechLevelDbfs));
 
-  absl::optional<int> new_digital_gain =
+  std::optional<int> new_digital_gain =
       helper.manager.GetDigitalComressionGain();
   if (new_digital_gain) {
     helper.mock_gain_control.set_compression_gain_db(*new_digital_gain);
@@ -1225,7 +1223,7 @@
 
 TEST_P(AgcManagerDirectParametrizedTest,
        MaxCompressionIsIncreasedAfterClipping) {
-  constexpr absl::optional<float> kNoOverride = absl::nullopt;
+  constexpr std::optional<float> kNoOverride = std::nullopt;
   const auto speech_probability_override =
       GetOverrideOrEmpty(kHighSpeechProbability);
 
@@ -1248,7 +1246,7 @@
   helper.CallProcess(/*num_calls=*/5, speech_probability_override,
                      GetOverrideOrEmpty(-29.0f));
   // The mock `GetRmsErrorDb()` returns false; mimic this by passing
-  // absl::nullopt as an override.
+  // std::nullopt as an override.
   helper.CallProcess(/*num_calls=*/14, kNoOverride, kNoOverride);
   EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(8))
       .WillOnce(Return(0));
@@ -1529,11 +1527,11 @@
   // Simulate 4 seconds of clipping; it is expected to trigger a downward
   // adjustment of the analog gain.
   CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
-                           /*speech_probability_override=*/absl::nullopt,
-                           /*speech_level_override=*/absl::nullopt, *manager);
+                           /*speech_probability_override=*/std::nullopt,
+                           /*speech_level_override=*/std::nullopt, *manager);
   CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
-                           /*speech_probability_override=*/absl::nullopt,
-                           /*speech_level_override=*/absl::nullopt,
+                           /*speech_probability_override=*/std::nullopt,
+                           /*speech_level_override=*/std::nullopt,
                            *manager_with_override);
 
   // Make sure that an adaptation occurred.
@@ -1591,8 +1589,8 @@
       /*speech_probability_level=*/-18.0f, *manager);
   CallPreProcessAndProcess(
       /*num_calls=*/400, audio_buffer,
-      /*speech_probability_override=*/absl::optional<float>(0.7f),
-      /*speech_probability_level=*/absl::optional<float>(-18.0f),
+      /*speech_probability_override=*/std::optional<float>(0.7f),
+      /*speech_probability_level=*/std::optional<float>(-18.0f),
       *manager_with_override);
 
   // Make sure that an adaptation occurred.
@@ -1652,11 +1650,11 @@
   // Simulate 4 seconds of clipping; it is expected to trigger a downward
   // adjustment of the analog gain.
   CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
-                           /*speech_probability_override=*/absl::nullopt,
-                           /*speech_level_override=*/absl::nullopt, *manager);
+                           /*speech_probability_override=*/std::nullopt,
+                           /*speech_level_override=*/std::nullopt, *manager);
   CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
-                           /*speech_probability_override=*/absl::nullopt,
-                           /*speech_level_override=*/absl::nullopt,
+                           /*speech_probability_override=*/std::nullopt,
+                           /*speech_level_override=*/std::nullopt,
                            *manager_with_override);
 
   // Make sure that an adaptation occurred.
@@ -1718,12 +1716,12 @@
 
   CallPreProcessAndProcess(
       /*num_calls=*/400, audio_buffer,
-      /*speech_probability_override=*/absl::optional<float>(0.7f),
-      /*speech_level_override=*/absl::optional<float>(-18.0f), *manager);
+      /*speech_probability_override=*/std::optional<float>(0.7f),
+      /*speech_level_override=*/std::optional<float>(-18.0f), *manager);
   CallPreProcessAndProcess(
       /*num_calls=*/400, audio_buffer,
-      /*speech_probability_override=*/absl::optional<float>(0.7f),
-      /*speech_level_override=*/absl::optional<float>(-18.0f),
+      /*speech_probability_override=*/std::optional<float>(0.7f),
+      /*speech_level_override=*/std::optional<float>(-18.0f),
       *manager_with_override);
 
   // Make sure that an adaptation occurred.
@@ -2059,7 +2057,7 @@
   ASSERT_EQ(manager_1.recommended_analog_level(), kAnalogLevel);
   ASSERT_EQ(manager_2.recommended_analog_level(), kAnalogLevel);
 
-  reader.Feed(kNumFrames, kGainDb, absl::nullopt, absl::nullopt, manager_1);
+  reader.Feed(kNumFrames, kGainDb, std::nullopt, std::nullopt, manager_1);
   reader.Feed(kNumFrames, kGainDb, manager_2);
 
   // Check that the states are the same and adaptation occurs.
diff --git a/modules/audio_processing/agc2/BUILD.gn b/modules/audio_processing/agc2/BUILD.gn
index 73b2beb..5da168a 100644
--- a/modules/audio_processing/agc2/BUILD.gn
+++ b/modules/audio_processing/agc2/BUILD.gn
@@ -80,7 +80,6 @@
     "../../../rtc_base:checks",
     "../../../rtc_base:safe_compare",
     "../../../rtc_base:safe_minmax",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -117,7 +116,6 @@
     "../../../rtc_base:checks",
     "../../../rtc_base:logging",
     "../../../rtc_base:safe_minmax",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -220,7 +218,6 @@
     "../../../rtc_base:safe_minmax",
     "../../../system_wrappers:field_trial",
     "../../../system_wrappers:metrics",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -486,7 +483,6 @@
     "../../../rtc_base:stringutils",
     "../../../system_wrappers:metrics",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/modules/audio_processing/agc2/clipping_predictor.cc b/modules/audio_processing/agc2/clipping_predictor.cc
index fd759c6..06115a30 100644
--- a/modules/audio_processing/agc2/clipping_predictor.cc
+++ b/modules/audio_processing/agc2/clipping_predictor.cc
@@ -131,11 +131,11 @@
   // if at least `GetMinFramesProcessed()` frames have been processed since the
   // last reset and a clipping event is predicted. `level`, `min_mic_level`, and
   // `max_mic_level` are limited to [0, 255] and `default_step` to [1, 255].
-  absl::optional<int> EstimateClippedLevelStep(int channel,
-                                               int level,
-                                               int default_step,
-                                               int min_mic_level,
-                                               int max_mic_level) const {
+  std::optional<int> EstimateClippedLevelStep(int channel,
+                                              int level,
+                                              int default_step,
+                                              int min_mic_level,
+                                              int max_mic_level) const {
     RTC_CHECK_GE(channel, 0);
     RTC_CHECK_LT(channel, ch_buffers_.size());
     RTC_DCHECK_GE(level, 0);
@@ -147,7 +147,7 @@
     RTC_DCHECK_GE(max_mic_level, 0);
     RTC_DCHECK_LE(max_mic_level, 255);
     if (level <= min_mic_level) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (PredictClippingEvent(channel)) {
       const int new_level =
@@ -157,7 +157,7 @@
         return step;
       }
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
  private:
@@ -271,11 +271,11 @@
   // least `GetMinFramesProcessed()` frames have been processed since the last
   // reset and a clipping event is predicted. `level`, `min_mic_level`, and
   // `max_mic_level` are limited to [0, 255] and `default_step` to [1, 255].
-  absl::optional<int> EstimateClippedLevelStep(int channel,
-                                               int level,
-                                               int default_step,
-                                               int min_mic_level,
-                                               int max_mic_level) const {
+  std::optional<int> EstimateClippedLevelStep(int channel,
+                                              int level,
+                                              int default_step,
+                                              int min_mic_level,
+                                              int max_mic_level) const {
     RTC_DCHECK_GE(channel, 0);
     RTC_DCHECK_LT(channel, ch_buffers_.size());
     RTC_DCHECK_GE(level, 0);
@@ -287,9 +287,9 @@
     RTC_DCHECK_GE(max_mic_level, 0);
     RTC_DCHECK_LE(max_mic_level, 255);
     if (level <= min_mic_level) {
-      return absl::nullopt;
+      return std::nullopt;
     }
-    absl::optional<float> estimate_db = EstimatePeakValue(channel);
+    std::optional<float> estimate_db = EstimatePeakValue(channel);
     if (estimate_db.has_value() && estimate_db.value() > clipping_threshold_) {
       int step = 0;
       if (!adaptive_step_estimation_) {
@@ -309,7 +309,7 @@
         return level - new_level;
       }
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
  private:
@@ -319,18 +319,18 @@
 
   // Predicts clipping sample peaks based on the processed audio frames.
   // Returns the estimated peak value if clipping is predicted. Otherwise
-  // returns absl::nullopt.
-  absl::optional<float> EstimatePeakValue(int channel) const {
+  // returns std::nullopt.
+  std::optional<float> EstimatePeakValue(int channel) const {
     const auto reference_metrics = ch_buffers_[channel]->ComputePartialMetrics(
         reference_window_delay_, reference_window_length_);
     if (!reference_metrics.has_value()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     const auto metrics =
         ch_buffers_[channel]->ComputePartialMetrics(0, window_length_);
     if (!metrics.has_value() ||
         !(FloatS16ToDbfs(metrics.value().max) > clipping_threshold_)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     const float reference_crest_factor =
         ComputeCrestFactor(reference_metrics.value());
diff --git a/modules/audio_processing/agc2/clipping_predictor.h b/modules/audio_processing/agc2/clipping_predictor.h
index 5332719..3fd1086 100644
--- a/modules/audio_processing/agc2/clipping_predictor.h
+++ b/modules/audio_processing/agc2/clipping_predictor.h
@@ -12,9 +12,9 @@
 #define MODULES_AUDIO_PROCESSING_AGC2_CLIPPING_PREDICTOR_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_processing.h"
 #include "modules/audio_processing/include/audio_frame_view.h"
 
@@ -35,12 +35,12 @@
 
   // Predicts if clipping is going to occur for the specified `channel` in the
   // near-future and, if so, it returns a recommended analog mic level decrease
-  // step. Returns absl::nullopt if clipping is not predicted.
+  // step. Returns std::nullopt if clipping is not predicted.
   // `level` is the current analog mic level, `default_step` is the amount the
   // mic level is lowered by the analog controller with every clipping event and
   // `min_mic_level` and `max_mic_level` is the range of allowed analog mic
   // levels.
-  virtual absl::optional<int> EstimateClippedLevelStep(
+  virtual std::optional<int> EstimateClippedLevelStep(
       int channel,
       int level,
       int default_step,
diff --git a/modules/audio_processing/agc2/clipping_predictor_level_buffer.cc b/modules/audio_processing/agc2/clipping_predictor_level_buffer.cc
index fe4cf2a..acc114c 100644
--- a/modules/audio_processing/agc2/clipping_predictor_level_buffer.cc
+++ b/modules/audio_processing/agc2/clipping_predictor_level_buffer.cc
@@ -50,7 +50,7 @@
 }
 
 // TODO(bugs.webrtc.org/12774): Optimize partial computation for long buffers.
-absl::optional<ClippingPredictorLevelBuffer::Level>
+std::optional<ClippingPredictorLevelBuffer::Level>
 ClippingPredictorLevelBuffer::ComputePartialMetrics(int delay,
                                                     int num_items) const {
   RTC_DCHECK_GE(delay, 0);
@@ -59,7 +59,7 @@
   RTC_DCHECK_LE(num_items, Capacity());
   RTC_DCHECK_LE(delay + num_items, Capacity());
   if (delay + num_items > Size()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   float sum = 0.0f;
   float max = 0.0f;
@@ -71,7 +71,7 @@
     sum += data_[idx].average;
     max = std::fmax(data_[idx].max, max);
   }
-  return absl::optional<Level>({sum / static_cast<float>(num_items), max});
+  return std::optional<Level>({sum / static_cast<float>(num_items), max});
 }
 
 }  // namespace webrtc
diff --git a/modules/audio_processing/agc2/clipping_predictor_level_buffer.h b/modules/audio_processing/agc2/clipping_predictor_level_buffer.h
index c903277..21e9b46 100644
--- a/modules/audio_processing/agc2/clipping_predictor_level_buffer.h
+++ b/modules/audio_processing/agc2/clipping_predictor_level_buffer.h
@@ -12,10 +12,9 @@
 #define MODULES_AUDIO_PROCESSING_AGC2_CLIPPING_PREDICTOR_LEVEL_BUFFER_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
-
 namespace webrtc {
 
 // A circular buffer to store frame-wise `Level` items for clipping prediction.
@@ -58,7 +57,7 @@
   // from `delay` to `delay` - `num_items` (a delay equal to zero corresponds
   // to the most recently pushed item). The value of `delay` is limited to
   // [0, N] and `num_items` to [1, M] where N + M is the capacity of the buffer.
-  absl::optional<Level> ComputePartialMetrics(int delay, int num_items) const;
+  std::optional<Level> ComputePartialMetrics(int delay, int num_items) const;
 
  private:
   int tail_;
diff --git a/modules/audio_processing/agc2/clipping_predictor_level_buffer_unittest.cc b/modules/audio_processing/agc2/clipping_predictor_level_buffer_unittest.cc
index 7af9a43..4f20ddb 100644
--- a/modules/audio_processing/agc2/clipping_predictor_level_buffer_unittest.cc
+++ b/modules/audio_processing/agc2/clipping_predictor_level_buffer_unittest.cc
@@ -108,9 +108,9 @@
   buffer.Push({1, 2});
   buffer.Push({3, 6});
   EXPECT_EQ(buffer.ComputePartialMetrics(/*delay=*/0, /*num_items=*/3),
-            absl::nullopt);
+            std::nullopt);
   EXPECT_EQ(buffer.ComputePartialMetrics(/*delay=*/2, /*num_items=*/1),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(ClippingPredictorLevelBufferTest, CheckMetricsAfterReset) {
diff --git a/modules/audio_processing/agc2/clipping_predictor_unittest.cc b/modules/audio_processing/agc2/clipping_predictor_unittest.cc
index af73107..dbb6c23 100644
--- a/modules/audio_processing/agc2/clipping_predictor_unittest.cc
+++ b/modules/audio_processing/agc2/clipping_predictor_unittest.cc
@@ -105,7 +105,7 @@
     SCOPED_TRACE(i);
     EXPECT_EQ(predictor.EstimateClippedLevelStep(i, level, default_step,
                                                  min_mic_level, max_mic_level),
-              absl::nullopt);
+              std::nullopt);
   }
 }
 
diff --git a/modules/audio_processing/agc2/input_volume_controller.cc b/modules/audio_processing/agc2/input_volume_controller.cc
index bcc650f..fcb8f1d 100644
--- a/modules/audio_processing/agc2/input_volume_controller.cc
+++ b/modules/audio_processing/agc2/input_volume_controller.cc
@@ -173,7 +173,7 @@
 // previous update and the ratio of non-silence frames (i.e., frames with a
 // `speech_probability` higher than `speech_probability_threshold_`) is at least
 // `speech_ratio_threshold_`.
-void MonoInputVolumeController::Process(absl::optional<int> rms_error_db,
+void MonoInputVolumeController::Process(std::optional<int> rms_error_db,
                                         float speech_probability) {
   if (check_volume_on_next_process_) {
     check_volume_on_next_process_ = false;
@@ -404,7 +404,7 @@
   clipping_rate_log_ = 0.0f;
   clipping_rate_log_counter_ = 0;
 
-  applied_input_volume_ = absl::nullopt;
+  applied_input_volume_ = std::nullopt;
 }
 
 void InputVolumeController::AnalyzeInputAudio(int applied_input_volume,
@@ -498,13 +498,13 @@
   AggregateChannelLevels();
 }
 
-absl::optional<int> InputVolumeController::RecommendInputVolume(
+std::optional<int> InputVolumeController::RecommendInputVolume(
     float speech_probability,
-    absl::optional<float> speech_level_dbfs) {
+    std::optional<float> speech_level_dbfs) {
   // Only process if applied input volume is set.
   if (!applied_input_volume_.has_value()) {
     RTC_LOG(LS_ERROR) << "[AGC2] Applied input volume not set.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   AggregateChannelLevels();
@@ -514,7 +514,7 @@
     return applied_input_volume_;
   }
 
-  absl::optional<int> rms_error_db;
+  std::optional<int> rms_error_db;
   if (speech_level_dbfs.has_value()) {
     // Compute the error for all frames (both speech and non-speech frames).
     rms_error_db = GetSpeechLevelRmsErrorDb(
@@ -533,7 +533,7 @@
         recommended_input_volume_);
   }
 
-  applied_input_volume_ = absl::nullopt;
+  applied_input_volume_ = std::nullopt;
   return recommended_input_volume();
 }
 
diff --git a/modules/audio_processing/agc2/input_volume_controller.h b/modules/audio_processing/agc2/input_volume_controller.h
index b61f68f..60e76d8 100644
--- a/modules/audio_processing/agc2/input_volume_controller.h
+++ b/modules/audio_processing/agc2/input_volume_controller.h
@@ -12,9 +12,9 @@
 #define MODULES_AUDIO_PROCESSING_AGC2_INPUT_VOLUME_CONTROLLER_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/audio_processing.h"
 #include "modules/audio_processing/agc2/clipping_predictor.h"
@@ -95,9 +95,9 @@
   // suppression are applied. Returns a non-empty input volume recommendation if
   // available. If `capture_output_used_` is true, returns the applied input
   // volume.
-  absl::optional<int> RecommendInputVolume(
+  std::optional<int> RecommendInputVolume(
       float speech_probability,
-      absl::optional<float> speech_level_dbfs);
+      std::optional<float> speech_level_dbfs);
 
   // Stores whether the capture output will be used or not. Call when the
   // capture stream output has been flagged to be used/not-used. If unused, the
@@ -155,7 +155,7 @@
   int recommended_input_volume_ = 0;
   // Applied input volume. After `SetAppliedInputVolume()` is called it holds
   // the current applied volume.
-  absl::optional<int> applied_input_volume_;
+  std::optional<int> applied_input_volume_;
 
   bool capture_output_used_;
 
@@ -213,7 +213,7 @@
   // result of `HandleClipping()` and on `rms_error_dbfs`. Updates are only
   // allowed for active speech segments and when `rms_error_dbfs` is not empty.
   // Must be called after `HandleClipping()`.
-  void Process(absl::optional<int> rms_error_dbfs, float speech_probability);
+  void Process(std::optional<int> rms_error_dbfs, float speech_probability);
 
   // Returns the recommended input volume. Must be called after `Process()`.
   int recommended_analog_level() const { return recommended_input_volume_; }
diff --git a/modules/audio_processing/agc2/input_volume_controller_unittest.cc b/modules/audio_processing/agc2/input_volume_controller_unittest.cc
index d1bdcf2..eaa8471 100644
--- a/modules/audio_processing/agc2/input_volume_controller_unittest.cc
+++ b/modules/audio_processing/agc2/input_volume_controller_unittest.cc
@@ -156,7 +156,7 @@
            int applied_input_volume,
            int gain_db,
            float speech_probability,
-           absl::optional<float> speech_level_dbfs,
+           std::optional<float> speech_level_dbfs,
            InputVolumeController& controller) {
     RTC_DCHECK(controller.capture_output_used());
 
@@ -201,7 +201,7 @@
 float UpdateRecommendedInputVolume(MonoInputVolumeController& mono_controller,
                                    int applied_input_volume,
                                    float speech_probability,
-                                   absl::optional<float> rms_error_dbfs) {
+                                   std::optional<float> rms_error_dbfs) {
   mono_controller.set_stream_analog_level(applied_input_volume);
   EXPECT_EQ(mono_controller.recommended_analog_level(), applied_input_volume);
   mono_controller.Process(rms_error_dbfs, speech_probability);
@@ -256,12 +256,12 @@
   // - Uses `audio_buffer` to call `AnalyzeInputAudio()` and
   // `RecommendInputVolume()`;
   //  Returns the recommended input volume.
-  absl::optional<int> CallAgcSequence(int applied_input_volume,
-                                      float speech_probability,
-                                      absl::optional<float> speech_level_dbfs,
-                                      int num_calls = 1) {
+  std::optional<int> CallAgcSequence(int applied_input_volume,
+                                     float speech_probability,
+                                     std::optional<float> speech_level_dbfs,
+                                     int num_calls = 1) {
     RTC_DCHECK_GE(num_calls, 1);
-    absl::optional<int> volume = applied_input_volume;
+    std::optional<int> volume = applied_input_volume;
     for (int i = 0; i < num_calls; ++i) {
       // Repeat the initial volume if `RecommendInputVolume()` doesn't return a
       // value.
@@ -285,7 +285,7 @@
   int CallRecommendInputVolume(int num_calls,
                                int initial_volume,
                                float speech_probability,
-                               absl::optional<float> speech_level_dbfs) {
+                               std::optional<float> speech_level_dbfs) {
     RTC_DCHECK(controller.capture_output_used());
 
     // Create non-clipping audio for `AnalyzeInputAudio()`.
@@ -1189,7 +1189,7 @@
   constexpr int kGainDb = -20;
   SpeechSamplesReader reader;
   int volume = reader.Feed(kNumFrames, kInitialInputVolume, kGainDb,
-                           kLowSpeechProbability, absl::nullopt, controller);
+                           kLowSpeechProbability, std::nullopt, controller);
 
   // Check that no adaptation occurs.
   ASSERT_EQ(volume, kInitialInputVolume);
@@ -1845,8 +1845,8 @@
   EXPECT_EQ(volume_1, kInitialInputVolume);
   EXPECT_EQ(volume_2, kInitialInputVolume);
 
-  volume_1 = UpdateRecommendedInputVolume(
-      mono_controller_1, volume_1, kHighSpeechProbability, absl::nullopt);
+  volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
+                                          kHighSpeechProbability, std::nullopt);
   volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
                                           kHighSpeechProbability, -10.0f);
 
diff --git a/modules/audio_processing/agc2/input_volume_stats_reporter.h b/modules/audio_processing/agc2/input_volume_stats_reporter.h
index 31b1100..2f31aa0 100644
--- a/modules/audio_processing/agc2/input_volume_stats_reporter.h
+++ b/modules/audio_processing/agc2/input_volume_stats_reporter.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC2_INPUT_VOLUME_STATS_REPORTER_H_
 #define MODULES_AUDIO_PROCESSING_AGC2_INPUT_VOLUME_STATS_REPORTER_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "rtc_base/gtest_prod_util.h"
 #include "system_wrappers/include/metrics.h"
 
@@ -83,7 +84,7 @@
   const bool cannot_log_stats_;
 
   int log_volume_update_stats_counter_ = 0;
-  absl::optional<int> previous_input_volume_ = absl::nullopt;
+  std::optional<int> previous_input_volume_ = std::nullopt;
 };
 
 // Updates the histogram that keeps track of recommended input volume changes
diff --git a/modules/audio_processing/agc2/saturation_protector_buffer.cc b/modules/audio_processing/agc2/saturation_protector_buffer.cc
index 41efdad..1f9083f 100644
--- a/modules/audio_processing/agc2/saturation_protector_buffer.cc
+++ b/modules/audio_processing/agc2/saturation_protector_buffer.cc
@@ -62,9 +62,9 @@
   }
 }
 
-absl::optional<float> SaturationProtectorBuffer::Front() const {
+std::optional<float> SaturationProtectorBuffer::Front() const {
   if (size_ == 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   RTC_DCHECK_LT(FrontIndex(), buffer_.size());
   return buffer_[FrontIndex()];
diff --git a/modules/audio_processing/agc2/saturation_protector_buffer.h b/modules/audio_processing/agc2/saturation_protector_buffer.h
index e17d099..3965e93 100644
--- a/modules/audio_processing/agc2/saturation_protector_buffer.h
+++ b/modules/audio_processing/agc2/saturation_protector_buffer.h
@@ -12,8 +12,8 @@
 #define MODULES_AUDIO_PROCESSING_AGC2_SATURATION_PROTECTOR_BUFFER_H_
 
 #include <array>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "modules/audio_processing/agc2/agc2_common.h"
 
 namespace webrtc {
@@ -43,7 +43,7 @@
 
   // Returns the oldest item in the buffer. Returns an empty value if the
   // buffer is empty.
-  absl::optional<float> Front() const;
+  std::optional<float> Front() const;
 
  private:
   int FrontIndex() const;
diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc
index 9a831d9..a1cba51 100644
--- a/modules/audio_processing/audio_processing_impl.cc
+++ b/modules/audio_processing/audio_processing_impl.cc
@@ -14,6 +14,7 @@
 #include <cstdint>
 #include <cstring>
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <utility>
@@ -21,7 +22,6 @@
 #include "absl/base/nullability.h"
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/audio_frame.h"
 #include "api/task_queue/task_queue_base.h"
@@ -1400,7 +1400,7 @@
   if (submodules_.agc_manager) {
     submodules_.agc_manager->Process(*capture_buffer);
 
-    absl::optional<int> new_digital_gain =
+    std::optional<int> new_digital_gain =
         submodules_.agc_manager->GetDigitalComressionGain();
     if (new_digital_gain && submodules_.gain_control) {
       submodules_.gain_control->set_compression_gain_db(*new_digital_gain);
@@ -1725,7 +1725,7 @@
 
   // Invalidate any previously recommended input volume which will be updated by
   // `ProcessStream()`.
-  capture_.recommended_input_volume = absl::nullopt;
+  capture_.recommended_input_volume = std::nullopt;
 
   if (submodules_.agc_manager) {
     submodules_.agc_manager->set_stream_analog_level(level);
@@ -1758,7 +1758,7 @@
   if (!capture_.applied_input_volume.has_value()) {
     // When `set_stream_analog_level()` is not called, no input level can be
     // recommended.
-    capture_.recommended_input_volume = absl::nullopt;
+    capture_.recommended_input_volume = std::nullopt;
     return;
   }
 
@@ -1890,7 +1890,7 @@
       RTC_DCHECK(submodules_.echo_controller);
     } else {
       EchoCanceller3Config config;
-      absl::optional<EchoCanceller3Config> multichannel_config;
+      std::optional<EchoCanceller3Config> multichannel_config;
       if (use_setup_specific_default_aec3_config_) {
         multichannel_config = EchoCanceller3::CreateDefaultMultichannelConfig();
       }
diff --git a/modules/audio_processing/audio_processing_impl.h b/modules/audio_processing/audio_processing_impl.h
index 5388c84..ecdc055 100644
--- a/modules/audio_processing/audio_processing_impl.h
+++ b/modules/audio_processing/audio_processing_impl.h
@@ -16,12 +16,12 @@
 #include <atomic>
 #include <list>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/base/nullability.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/audio_processing.h"
 #include "api/audio/audio_processing_statistics.h"
@@ -440,12 +440,12 @@
     AudioProcessingStats stats;
     // Input volume applied on the audio input device when the audio is
     // acquired. Unspecified when unknown.
-    absl::optional<int> applied_input_volume;
+    std::optional<int> applied_input_volume;
     bool applied_input_volume_changed;
     // Recommended input volume to apply on the audio input device the next time
     // that audio is acquired. Unspecified when no input volume can be
     // recommended.
-    absl::optional<int> recommended_input_volume;
+    std::optional<int> recommended_input_volume;
   } capture_ RTC_GUARDED_BY(mutex_capture_);
 
   struct ApmCaptureNonLockedState {
diff --git a/modules/audio_processing/audio_processing_impl_unittest.cc b/modules/audio_processing/audio_processing_impl_unittest.cc
index 82e6550..5b00410 100644
--- a/modules/audio_processing/audio_processing_impl_unittest.cc
+++ b/modules/audio_processing/audio_processing_impl_unittest.cc
@@ -13,9 +13,9 @@
 #include <algorithm>
 #include <array>
 #include <memory>
+#include <optional>
 #include <tuple>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_processing.h"
 #include "api/make_ref_counted.h"
 #include "api/scoped_refptr.h"
diff --git a/modules/audio_processing/echo_detector/circular_buffer.cc b/modules/audio_processing/echo_detector/circular_buffer.cc
index a6d10ed..c24f920 100644
--- a/modules/audio_processing/echo_detector/circular_buffer.cc
+++ b/modules/audio_processing/echo_detector/circular_buffer.cc
@@ -28,9 +28,9 @@
   RTC_DCHECK_LE(nr_elements_in_buffer_, buffer_.size());
 }
 
-absl::optional<float> CircularBuffer::Pop() {
+std::optional<float> CircularBuffer::Pop() {
   if (nr_elements_in_buffer_ == 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   const size_t index =
       (buffer_.size() + next_insertion_index_ - nr_elements_in_buffer_) %
diff --git a/modules/audio_processing/echo_detector/circular_buffer.h b/modules/audio_processing/echo_detector/circular_buffer.h
index db1aeae..5cce0d7 100644
--- a/modules/audio_processing/echo_detector/circular_buffer.h
+++ b/modules/audio_processing/echo_detector/circular_buffer.h
@@ -13,10 +13,9 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
-
 namespace webrtc {
 
 // Ring buffer containing floating point values.
@@ -26,7 +25,7 @@
   ~CircularBuffer();
 
   void Push(float value);
-  absl::optional<float> Pop();
+  std::optional<float> Pop();
   size_t Size() const { return nr_elements_in_buffer_; }
   // This function fills the buffer with zeros, but does not change its size.
   void Clear();
diff --git a/modules/audio_processing/echo_detector/circular_buffer_unittest.cc b/modules/audio_processing/echo_detector/circular_buffer_unittest.cc
index 7a234d4..95bea5e 100644
--- a/modules/audio_processing/echo_detector/circular_buffer_unittest.cc
+++ b/modules/audio_processing/echo_detector/circular_buffer_unittest.cc
@@ -47,7 +47,7 @@
 
 TEST(CircularBufferTests, ReadFromEmpty) {
   CircularBuffer test_buffer(3);
-  EXPECT_EQ(absl::nullopt, test_buffer.Pop());
+  EXPECT_EQ(std::nullopt, test_buffer.Pop());
 }
 
 }  // namespace webrtc
diff --git a/modules/audio_processing/gain_control_impl.cc b/modules/audio_processing/gain_control_impl.cc
index 2a7f527..56f56b5 100644
--- a/modules/audio_processing/gain_control_impl.cc
+++ b/modules/audio_processing/gain_control_impl.cc
@@ -11,8 +11,8 @@
 #include "modules/audio_processing/gain_control_impl.h"
 
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_processing.h"
 #include "modules/audio_processing/agc/legacy/gain_control.h"
 #include "modules/audio_processing/audio_buffer.h"
diff --git a/modules/audio_processing/gain_control_impl.h b/modules/audio_processing/gain_control_impl.h
index 8aea8f2..1a2cafe 100644
--- a/modules/audio_processing/gain_control_impl.h
+++ b/modules/audio_processing/gain_control_impl.h
@@ -15,9 +15,9 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/audio_processing/agc/gain_control.h"
 
@@ -81,8 +81,8 @@
   std::vector<std::unique_ptr<MonoAgcState>> mono_agcs_;
   std::vector<int> capture_levels_;
 
-  absl::optional<size_t> num_proc_channels_;
-  absl::optional<int> sample_rate_hz_;
+  std::optional<size_t> num_proc_channels_;
+  std::optional<int> sample_rate_hz_;
 
   static int instance_counter_;
 };
diff --git a/modules/audio_processing/gain_controller2.cc b/modules/audio_processing/gain_controller2.cc
index 9bfae52..b8f72ce 100644
--- a/modules/audio_processing/gain_controller2.cc
+++ b/modules/audio_processing/gain_controller2.cc
@@ -156,7 +156,7 @@
 
 void GainController2::Analyze(int applied_input_volume,
                               const AudioBuffer& audio_buffer) {
-  recommended_input_volume_ = absl::nullopt;
+  recommended_input_volume_ = std::nullopt;
 
   RTC_DCHECK_GE(applied_input_volume, 0);
   RTC_DCHECK_LE(applied_input_volume, 255);
@@ -167,10 +167,10 @@
   }
 }
 
-void GainController2::Process(absl::optional<float> speech_probability,
+void GainController2::Process(std::optional<float> speech_probability,
                               bool input_volume_changed,
                               AudioBuffer* audio) {
-  recommended_input_volume_ = absl::nullopt;
+  recommended_input_volume_ = std::nullopt;
 
   data_dumper_.DumpRaw("agc2_applied_input_volume_changed",
                        input_volume_changed);
@@ -203,13 +203,13 @@
 
   // Compute audio, noise and speech levels.
   AudioLevels audio_levels = ComputeAudioLevels(float_frame, data_dumper_);
-  absl::optional<float> noise_rms_dbfs;
+  std::optional<float> noise_rms_dbfs;
   if (noise_level_estimator_) {
     // TODO(bugs.webrtc.org/7494): Pass `audio_levels` to remove duplicated
     // computation in `noise_level_estimator_`.
     noise_rms_dbfs = noise_level_estimator_->Analyze(float_frame);
   }
-  absl::optional<SpeechLevel> speech_level;
+  std::optional<SpeechLevel> speech_level;
   if (speech_level_estimator_) {
     RTC_DCHECK(speech_probability.has_value());
     speech_level_estimator_->Update(
@@ -228,8 +228,8 @@
           input_volume_controller_->RecommendInputVolume(
               *speech_probability,
               speech_level->is_confident
-                  ? absl::optional<float>(speech_level->rms_dbfs)
-                  : absl::nullopt);
+                  ? std::optional<float>(speech_level->rms_dbfs)
+                  : std::nullopt);
     }
   }
 
diff --git a/modules/audio_processing/gain_controller2.h b/modules/audio_processing/gain_controller2.h
index dbf192b..d192a20 100644
--- a/modules/audio_processing/gain_controller2.h
+++ b/modules/audio_processing/gain_controller2.h
@@ -69,7 +69,7 @@
   // Handles input volume changes; if the caller cannot determine whether an
   // input volume change occurred, set `input_volume_changed` to false.
   // TODO(bugs.webrtc.org/7494): Remove `speech_probability`.
-  void Process(absl::optional<float> speech_probability,
+  void Process(std::optional<float> speech_probability,
                bool input_volume_changed,
                AudioBuffer* audio);
 
@@ -77,7 +77,7 @@
 
   AvailableCpuFeatures GetCpuFeatures() const { return cpu_features_; }
 
-  absl::optional<int> recommended_input_volume() const {
+  std::optional<int> recommended_input_volume() const {
     return recommended_input_volume_;
   }
 
@@ -103,7 +103,7 @@
   // Recommended input volume from `InputVolumecontroller`. Non-empty after
   // `Process()` if input volume controller is enabled and
   // `InputVolumeController::Process()` has returned a non-empty value.
-  absl::optional<int> recommended_input_volume_;
+  std::optional<int> recommended_input_volume_;
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_processing/gain_controller2_unittest.cc b/modules/audio_processing/gain_controller2_unittest.cc
index bccab8d..0af8365 100644
--- a/modules/audio_processing/gain_controller2_unittest.cc
+++ b/modules/audio_processing/gain_controller2_unittest.cc
@@ -57,7 +57,7 @@
     const auto applied_volume = agc2.recommended_input_volume();
     agc2.Analyze(applied_volume.value_or(applied_initial_volume), ab);
 
-    agc2.Process(/*speech_probability=*/absl::nullopt,
+    agc2.Process(/*speech_probability=*/std::nullopt,
                  /*input_volume_changed=*/false, &ab);
   }
 
@@ -438,13 +438,13 @@
       x *= gain;
     }
     test::CopyVectorToAudioBuffer(stream_config, frame, &audio_buffer);
-    agc2.Process(/*speech_probability=*/absl::nullopt,
+    agc2.Process(/*speech_probability=*/std::nullopt,
                  /*input_volume_changed=*/false, &audio_buffer);
   }
 
   // Estimate the applied gain by processing a probing frame.
   SetAudioBufferSamples(/*value=*/1.0f, audio_buffer);
-  agc2.Process(/*speech_probability=*/absl::nullopt,
+  agc2.Process(/*speech_probability=*/std::nullopt,
                /*input_volume_changed=*/false, &audio_buffer);
   const float applied_gain_db =
       20.0f * std::log10(audio_buffer.channels_const()[0][0]);
@@ -527,7 +527,7 @@
                  &audio_buffer);
     test::CopyVectorToAudioBuffer(stream_config, frame,
                                   &audio_buffer_reference);
-    agc2_reference.Process(/*speech_probability=*/absl::nullopt,
+    agc2_reference.Process(/*speech_probability=*/std::nullopt,
                            /*input_volume_changed=*/false,
                            &audio_buffer_reference);
     // Check the output buffers.
@@ -592,7 +592,7 @@
     }
     test::CopyVectorToAudioBuffer(stream_config, frame,
                                   &audio_buffer_reference);
-    agc2_reference.Process(absl::nullopt, /*input_volume_changed=*/false,
+    agc2_reference.Process(std::nullopt, /*input_volume_changed=*/false,
                            &audio_buffer_reference);
     test::CopyVectorToAudioBuffer(stream_config, frame, &audio_buffer);
     float speech_probability = vad.Analyze(audio_buffer.view());
diff --git a/modules/audio_processing/include/aec_dump.h b/modules/audio_processing/include/aec_dump.h
index f07b911..532fa21 100644
--- a/modules/audio_processing/include/aec_dump.h
+++ b/modules/audio_processing/include/aec_dump.h
@@ -13,10 +13,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 
 #include "absl/base/attributes.h"
-#include "absl/types/optional.h"
 #include "api/audio/audio_processing.h"
 #include "modules/audio_processing/include/audio_frame_view.h"
 
@@ -68,7 +68,7 @@
   struct AudioProcessingState {
     int delay;
     int drift;
-    absl::optional<int> applied_input_volume;
+    std::optional<int> applied_input_volume;
     bool keypress;
   };
 
diff --git a/modules/audio_processing/logging/apm_data_dumper.cc b/modules/audio_processing/logging/apm_data_dumper.cc
index 65d2167..283f739 100644
--- a/modules/audio_processing/logging/apm_data_dumper.cc
+++ b/modules/audio_processing/logging/apm_data_dumper.cc
@@ -61,7 +61,7 @@
 
 #if WEBRTC_APM_DEBUG_DUMP == 1
 bool ApmDataDumper::recording_activated_ = false;
-absl::optional<int> ApmDataDumper::dump_set_to_use_;
+std::optional<int> ApmDataDumper::dump_set_to_use_;
 char ApmDataDumper::output_dir_[] = "";
 
 FILE* ApmDataDumper::GetRawFile(absl::string_view name) {
diff --git a/modules/audio_processing/logging/apm_data_dumper.h b/modules/audio_processing/logging/apm_data_dumper.h
index 76f8b34..5186854 100644
--- a/modules/audio_processing/logging/apm_data_dumper.h
+++ b/modules/audio_processing/logging/apm_data_dumper.h
@@ -20,8 +20,9 @@
 #include <unordered_map>
 #endif
 
+#include <optional>
+
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #if WEBRTC_APM_DEBUG_DUMP == 1
 #include "common_audio/wav_file.h"
@@ -391,7 +392,7 @@
  private:
 #if WEBRTC_APM_DEBUG_DUMP == 1
   static bool recording_activated_;
-  static absl::optional<int> dump_set_to_use_;
+  static std::optional<int> dump_set_to_use_;
   static constexpr size_t kOutputDirMaxLength = 1024;
   static char output_dir_[kOutputDirMaxLength];
   const int instance_index_;
diff --git a/modules/audio_processing/residual_echo_detector.cc b/modules/audio_processing/residual_echo_detector.cc
index 2a564fc..06ac149 100644
--- a/modules/audio_processing/residual_echo_detector.cc
+++ b/modules/audio_processing/residual_echo_detector.cc
@@ -12,8 +12,8 @@
 
 #include <algorithm>
 #include <numeric>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
@@ -89,7 +89,7 @@
   }
 
   // Get the next render value.
-  const absl::optional<float> buffered_render_power = render_buffer_.Pop();
+  const std::optional<float> buffered_render_power = render_buffer_.Pop();
   if (!buffered_render_power) {
     // This can happen in a few cases: at the start of a call, due to a glitch
     // or due to clock drift. The excess capture value will be ignored.
diff --git a/modules/audio_processing/rms_level.cc b/modules/audio_processing/rms_level.cc
index b0a45cb..1c00e83 100644
--- a/modules/audio_processing/rms_level.cc
+++ b/modules/audio_processing/rms_level.cc
@@ -54,7 +54,7 @@
   sum_square_ = 0.f;
   sample_count_ = 0;
   max_sum_square_ = 0.f;
-  block_size_ = absl::nullopt;
+  block_size_ = std::nullopt;
 }
 
 void RmsLevel::Analyze(rtc::ArrayView<const int16_t> data) {
@@ -119,7 +119,7 @@
 
 RmsLevel::Levels RmsLevel::AverageAndPeak() {
   // Note that block_size_ should by design always be non-empty when
-  // sample_count_ != 0. Also, the * operator of absl::optional enforces this
+  // sample_count_ != 0. Also, the * operator of std::optional enforces this
   // with a DCHECK.
   Levels levels = (sample_count_ == 0)
                       ? Levels{RmsLevel::kMinLevelDb, RmsLevel::kMinLevelDb}
diff --git a/modules/audio_processing/rms_level.h b/modules/audio_processing/rms_level.h
index fbece19..b2a5ba0 100644
--- a/modules/audio_processing/rms_level.h
+++ b/modules/audio_processing/rms_level.h
@@ -14,7 +14,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/array_view.h"
 
 namespace webrtc {
@@ -69,7 +70,7 @@
   float sum_square_;
   size_t sample_count_;
   float max_sum_square_;
-  absl::optional<size_t> block_size_;
+  std::optional<size_t> block_size_;
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_processing/test/aec_dump_based_simulator.cc b/modules/audio_processing/test/aec_dump_based_simulator.cc
index 416e287..84ad7de 100644
--- a/modules/audio_processing/test/aec_dump_based_simulator.cc
+++ b/modules/audio_processing/test/aec_dump_based_simulator.cc
@@ -177,8 +177,8 @@
   // Set the applied input level if available.
   aec_dump_applied_input_level_ =
       msg.has_applied_input_volume()
-          ? absl::optional<int>(msg.applied_input_volume())
-          : absl::nullopt;
+          ? std::optional<int>(msg.applied_input_volume())
+          : std::nullopt;
 }
 
 void AecDumpBasedSimulator::VerifyProcessStreamBitExactness(
diff --git a/modules/audio_processing/test/audio_processing_simulator.h b/modules/audio_processing/test/audio_processing_simulator.h
index 082ccb1..314a70d 100644
--- a/modules/audio_processing/test/audio_processing_simulator.h
+++ b/modules/audio_processing/test/audio_processing_simulator.h
@@ -15,9 +15,9 @@
 #include <fstream>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_processing.h"
 #include "common_audio/channel_buffer.h"
 #include "common_audio/include/audio_util.h"
@@ -80,79 +80,79 @@
   SimulationSettings();
   SimulationSettings(const SimulationSettings&);
   ~SimulationSettings();
-  absl::optional<int> stream_delay;
-  absl::optional<bool> use_stream_delay;
-  absl::optional<int> output_sample_rate_hz;
-  absl::optional<int> output_num_channels;
-  absl::optional<int> reverse_output_sample_rate_hz;
-  absl::optional<int> reverse_output_num_channels;
-  absl::optional<std::string> output_filename;
-  absl::optional<std::string> reverse_output_filename;
-  absl::optional<std::string> input_filename;
-  absl::optional<std::string> reverse_input_filename;
-  absl::optional<std::string> artificial_nearend_filename;
-  absl::optional<std::string> linear_aec_output_filename;
-  absl::optional<bool> use_aec;
-  absl::optional<bool> use_aecm;
-  absl::optional<bool> use_ed;  // Residual Echo Detector.
-  absl::optional<std::string> ed_graph_output_filename;
-  absl::optional<bool> use_agc;
-  absl::optional<bool> use_agc2;
-  absl::optional<bool> use_pre_amplifier;
-  absl::optional<bool> use_capture_level_adjustment;
-  absl::optional<bool> use_analog_mic_gain_emulation;
-  absl::optional<bool> use_hpf;
-  absl::optional<bool> use_ns;
-  absl::optional<int> use_ts;
-  absl::optional<bool> use_analog_agc;
-  absl::optional<bool> use_all;
-  absl::optional<bool> analog_agc_use_digital_adaptive_controller;
-  absl::optional<int> agc_mode;
-  absl::optional<int> agc_target_level;
-  absl::optional<bool> use_agc_limiter;
-  absl::optional<int> agc_compression_gain;
-  absl::optional<bool> agc2_use_adaptive_gain;
-  absl::optional<float> agc2_fixed_gain_db;
-  absl::optional<bool> agc2_use_input_volume_controller;
-  absl::optional<float> pre_amplifier_gain_factor;
-  absl::optional<float> pre_gain_factor;
-  absl::optional<float> post_gain_factor;
-  absl::optional<float> analog_mic_gain_emulation_initial_level;
-  absl::optional<int> ns_level;
-  absl::optional<bool> ns_analysis_on_linear_aec_output;
-  absl::optional<bool> override_key_pressed;
-  absl::optional<int> maximum_internal_processing_rate;
+  std::optional<int> stream_delay;
+  std::optional<bool> use_stream_delay;
+  std::optional<int> output_sample_rate_hz;
+  std::optional<int> output_num_channels;
+  std::optional<int> reverse_output_sample_rate_hz;
+  std::optional<int> reverse_output_num_channels;
+  std::optional<std::string> output_filename;
+  std::optional<std::string> reverse_output_filename;
+  std::optional<std::string> input_filename;
+  std::optional<std::string> reverse_input_filename;
+  std::optional<std::string> artificial_nearend_filename;
+  std::optional<std::string> linear_aec_output_filename;
+  std::optional<bool> use_aec;
+  std::optional<bool> use_aecm;
+  std::optional<bool> use_ed;  // Residual Echo Detector.
+  std::optional<std::string> ed_graph_output_filename;
+  std::optional<bool> use_agc;
+  std::optional<bool> use_agc2;
+  std::optional<bool> use_pre_amplifier;
+  std::optional<bool> use_capture_level_adjustment;
+  std::optional<bool> use_analog_mic_gain_emulation;
+  std::optional<bool> use_hpf;
+  std::optional<bool> use_ns;
+  std::optional<int> use_ts;
+  std::optional<bool> use_analog_agc;
+  std::optional<bool> use_all;
+  std::optional<bool> analog_agc_use_digital_adaptive_controller;
+  std::optional<int> agc_mode;
+  std::optional<int> agc_target_level;
+  std::optional<bool> use_agc_limiter;
+  std::optional<int> agc_compression_gain;
+  std::optional<bool> agc2_use_adaptive_gain;
+  std::optional<float> agc2_fixed_gain_db;
+  std::optional<bool> agc2_use_input_volume_controller;
+  std::optional<float> pre_amplifier_gain_factor;
+  std::optional<float> pre_gain_factor;
+  std::optional<float> post_gain_factor;
+  std::optional<float> analog_mic_gain_emulation_initial_level;
+  std::optional<int> ns_level;
+  std::optional<bool> ns_analysis_on_linear_aec_output;
+  std::optional<bool> override_key_pressed;
+  std::optional<int> maximum_internal_processing_rate;
   int initial_mic_level;
   bool simulate_mic_gain = false;
-  absl::optional<bool> multi_channel_render;
-  absl::optional<bool> multi_channel_capture;
-  absl::optional<int> simulated_mic_kind;
-  absl::optional<int> frame_for_sending_capture_output_used_false;
-  absl::optional<int> frame_for_sending_capture_output_used_true;
+  std::optional<bool> multi_channel_render;
+  std::optional<bool> multi_channel_capture;
+  std::optional<int> simulated_mic_kind;
+  std::optional<int> frame_for_sending_capture_output_used_false;
+  std::optional<int> frame_for_sending_capture_output_used_true;
   bool report_performance = false;
-  absl::optional<std::string> performance_report_output_filename;
+  std::optional<std::string> performance_report_output_filename;
   bool report_bitexactness = false;
   bool use_verbose_logging = false;
   bool use_quiet_output = false;
   bool discard_all_settings_in_aecdump = true;
-  absl::optional<std::string> aec_dump_input_filename;
-  absl::optional<std::string> aec_dump_output_filename;
+  std::optional<std::string> aec_dump_input_filename;
+  std::optional<std::string> aec_dump_output_filename;
   bool fixed_interface = false;
   bool store_intermediate_output = false;
   bool print_aec_parameter_values = false;
   bool dump_internal_data = false;
   WavFile::SampleFormat wav_output_format = WavFile::SampleFormat::kInt16;
-  absl::optional<std::string> dump_internal_data_output_dir;
-  absl::optional<int> dump_set_to_use;
-  absl::optional<std::string> call_order_input_filename;
-  absl::optional<std::string> call_order_output_filename;
-  absl::optional<std::string> aec_settings_filename;
-  absl::optional<absl::string_view> aec_dump_input_string;
+  std::optional<std::string> dump_internal_data_output_dir;
+  std::optional<int> dump_set_to_use;
+  std::optional<std::string> call_order_input_filename;
+  std::optional<std::string> call_order_output_filename;
+  std::optional<std::string> aec_settings_filename;
+  std::optional<absl::string_view> aec_dump_input_string;
   std::vector<float>* processed_capture_samples = nullptr;
   bool analysis_only = false;
-  absl::optional<int> dump_start_frame;
-  absl::optional<int> dump_end_frame;
-  absl::optional<int> init_to_process;
+  std::optional<int> dump_start_frame;
+  std::optional<int> dump_end_frame;
+  std::optional<int> init_to_process;
 };
 
 // Provides common functionality for performing audioprocessing simulations.
@@ -220,7 +220,7 @@
   Int16Frame rev_frame_;
   Int16Frame fwd_frame_;
   bool bitexact_output_ = true;
-  absl::optional<int> aec_dump_applied_input_level_ = 0;
+  std::optional<int> aec_dump_applied_input_level_ = 0;
 
  protected:
   size_t output_reset_counter_ = 0;
diff --git a/modules/audio_processing/test/audioproc_float_impl.cc b/modules/audio_processing/test/audioproc_float_impl.cc
index 5d3c75a..f9b0f4b 100644
--- a/modules/audio_processing/test/audioproc_float_impl.cc
+++ b/modules/audio_processing/test/audioproc_float_impl.cc
@@ -339,19 +339,19 @@
     "protobuf debug dump recordings.\n";
 
 void SetSettingIfSpecified(absl::string_view value,
-                           absl::optional<std::string>* parameter) {
+                           std::optional<std::string>* parameter) {
   if (value.compare("") != 0) {
     *parameter = std::string(value);
   }
 }
 
-void SetSettingIfSpecified(int value, absl::optional<int>* parameter) {
+void SetSettingIfSpecified(int value, std::optional<int>* parameter) {
   if (value != kParameterNotSpecifiedValue) {
     *parameter = value;
   }
 }
 
-void SetSettingIfSpecified(float value, absl::optional<float>* parameter) {
+void SetSettingIfSpecified(float value, std::optional<float>* parameter) {
   constexpr float kFloatParameterNotSpecifiedValue =
       kParameterNotSpecifiedValue;
   if (value != kFloatParameterNotSpecifiedValue) {
@@ -359,7 +359,7 @@
   }
 }
 
-void SetSettingIfFlagSet(int32_t flag, absl::optional<bool>* parameter) {
+void SetSettingIfFlagSet(int32_t flag, std::optional<bool>* parameter) {
   if (flag == 0) {
     *parameter = false;
   } else if (flag == 1) {
@@ -507,14 +507,14 @@
                         &settings.dump_end_frame);
 
   constexpr int kFramesPerSecond = 100;
-  absl::optional<float> start_seconds;
+  std::optional<float> start_seconds;
   SetSettingIfSpecified(absl::GetFlag(FLAGS_dump_start_seconds),
                         &start_seconds);
   if (start_seconds) {
     settings.dump_start_frame = *start_seconds * kFramesPerSecond;
   }
 
-  absl::optional<float> end_seconds;
+  std::optional<float> end_seconds;
   SetSettingIfSpecified(absl::GetFlag(FLAGS_dump_end_seconds), &end_seconds);
   if (end_seconds) {
     settings.dump_end_frame = *end_seconds * kFramesPerSecond;
diff --git a/modules/audio_processing/test/conversational_speech/BUILD.gn b/modules/audio_processing/test/conversational_speech/BUILD.gn
index 9d387d2..543306e 100644
--- a/modules/audio_processing/test/conversational_speech/BUILD.gn
+++ b/modules/audio_processing/test/conversational_speech/BUILD.gn
@@ -74,6 +74,5 @@
     "../../../../test:test_support",
     "//testing/gtest",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
diff --git a/modules/audio_processing/test/conversational_speech/generator_unittest.cc b/modules/audio_processing/test/conversational_speech/generator_unittest.cc
index 1771444..bc7fc26 100644
--- a/modules/audio_processing/test/conversational_speech/generator_unittest.cc
+++ b/modules/audio_processing/test/conversational_speech/generator_unittest.cc
@@ -41,10 +41,10 @@
 #include <cmath>
 #include <map>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "common_audio/wav_file.h"
 #include "modules/audio_processing/test/conversational_speech/config.h"
 #include "modules/audio_processing/test/conversational_speech/mock_wavreader_factory.h"
@@ -152,7 +152,7 @@
   if (!DirExists(dir)) {
     return;
   }
-  absl::optional<std::vector<std::string>> dir_content = ReadDirectory(dir);
+  std::optional<std::vector<std::string>> dir_content = ReadDirectory(dir);
   EXPECT_TRUE(dir_content);
   for (const auto& path : *dir_content) {
     if (DirExists(path)) {
diff --git a/modules/audio_processing/test/debug_dump_replayer.cc b/modules/audio_processing/test/debug_dump_replayer.cc
index 2f483f5..fb45463 100644
--- a/modules/audio_processing/test/debug_dump_replayer.cc
+++ b/modules/audio_processing/test/debug_dump_replayer.cc
@@ -54,9 +54,9 @@
 }
 
 // Get next event that has not run.
-absl::optional<audioproc::Event> DebugDumpReplayer::GetNextEvent() const {
+std::optional<audioproc::Event> DebugDumpReplayer::GetNextEvent() const {
   if (!has_next_event_)
-    return absl::nullopt;
+    return std::nullopt;
   else
     return next_event_;
 }
diff --git a/modules/audio_processing/test/debug_dump_replayer.h b/modules/audio_processing/test/debug_dump_replayer.h
index 2768f18..efde413 100644
--- a/modules/audio_processing/test/debug_dump_replayer.h
+++ b/modules/audio_processing/test/debug_dump_replayer.h
@@ -32,7 +32,7 @@
   bool SetDumpFile(absl::string_view filename);
 
   // Return next event.
-  absl::optional<audioproc::Event> GetNextEvent() const;
+  std::optional<audioproc::Event> GetNextEvent() const;
 
   // Run the next event. Returns true if succeeded.
   bool RunNextEvent();
diff --git a/modules/audio_processing/test/debug_dump_test.cc b/modules/audio_processing/test/debug_dump_test.cc
index 93f892d..1e6ba11 100644
--- a/modules/audio_processing/test/debug_dump_test.cc
+++ b/modules/audio_processing/test/debug_dump_test.cc
@@ -264,7 +264,7 @@
 void DebugDumpTest::VerifyDebugDump(absl::string_view in_filename) {
   ASSERT_TRUE(debug_dump_replayer_.SetDumpFile(in_filename));
 
-  while (const absl::optional<audioproc::Event> event =
+  while (const std::optional<audioproc::Event> event =
              debug_dump_replayer_.GetNextEvent()) {
     debug_dump_replayer_.RunNextEvent();
     if (event->type() == audioproc::Event::STREAM) {
@@ -371,7 +371,7 @@
 
   ASSERT_TRUE(debug_dump_replayer_.SetDumpFile(generator.dump_file_name()));
 
-  while (const absl::optional<audioproc::Event> event =
+  while (const std::optional<audioproc::Event> event =
              debug_dump_replayer_.GetNextEvent()) {
     debug_dump_replayer_.RunNextEvent();
     if (event->type() == audioproc::Event::CONFIG) {
@@ -395,7 +395,7 @@
 
   ASSERT_TRUE(debug_dump_replayer_.SetDumpFile(generator.dump_file_name()));
 
-  while (const absl::optional<audioproc::Event> event =
+  while (const std::optional<audioproc::Event> event =
              debug_dump_replayer_.GetNextEvent()) {
     debug_dump_replayer_.RunNextEvent();
     if (event->type() == audioproc::Event::CONFIG) {
@@ -420,7 +420,7 @@
 
   ASSERT_TRUE(debug_dump_replayer_.SetDumpFile(generator.dump_file_name()));
 
-  while (const absl::optional<audioproc::Event> event =
+  while (const std::optional<audioproc::Event> event =
              debug_dump_replayer_.GetNextEvent()) {
     debug_dump_replayer_.RunNextEvent();
     if (event->type() == audioproc::Event::CONFIG) {
@@ -442,7 +442,7 @@
 
   ASSERT_TRUE(debug_dump_replayer_.SetDumpFile(generator.dump_file_name()));
 
-  while (const absl::optional<audioproc::Event> event =
+  while (const std::optional<audioproc::Event> event =
              debug_dump_replayer_.GetNextEvent()) {
     debug_dump_replayer_.RunNextEvent();
     if (event->type() == audioproc::Event::CONFIG) {
diff --git a/modules/audio_processing/test/fake_recording_device.cc b/modules/audio_processing/test/fake_recording_device.cc
index 3fd80b2..476ab8a 100644
--- a/modules/audio_processing/test/fake_recording_device.cc
+++ b/modules/audio_processing/test/fake_recording_device.cc
@@ -12,8 +12,8 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "modules/audio_processing/agc2/gain_map_internal.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_conversions.h"
@@ -45,7 +45,7 @@
   // Mic level to simulate.
   int mic_level_;
   // Optional mic level to undo.
-  absl::optional<int> undo_mic_level_;
+  std::optional<int> undo_mic_level_;
 };
 
 namespace {
@@ -94,7 +94,7 @@
   }
 };
 
-float ComputeAgcLinearFactor(const absl::optional<int>& undo_mic_level,
+float ComputeAgcLinearFactor(const std::optional<int>& undo_mic_level,
                              int mic_level) {
   // If an undo level is specified, virtually restore the unmodified
   // microphone level; otherwise simulate the mic gain only.
diff --git a/modules/audio_processing/test/performance_timer.h b/modules/audio_processing/test/performance_timer.h
index 5375ba7..b97a67d 100644
--- a/modules/audio_processing/test/performance_timer.h
+++ b/modules/audio_processing/test/performance_timer.h
@@ -11,9 +11,9 @@
 #ifndef MODULES_AUDIO_PROCESSING_TEST_PERFORMANCE_TIMER_H_
 #define MODULES_AUDIO_PROCESSING_TEST_PERFORMANCE_TIMER_H_
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "system_wrappers/include/clock.h"
 
 namespace webrtc {
@@ -37,7 +37,7 @@
 
  private:
   webrtc::Clock* clock_;
-  absl::optional<int64_t> start_timestamp_us_;
+  std::optional<int64_t> start_timestamp_us_;
   std::vector<int64_t> timestamps_us_;
 };
 
diff --git a/modules/audio_processing/transient/BUILD.gn b/modules/audio_processing/transient/BUILD.gn
index ac1b13d..75e2761 100644
--- a/modules/audio_processing/transient/BUILD.gn
+++ b/modules/audio_processing/transient/BUILD.gn
@@ -96,7 +96,6 @@
         "//testing/gtest",
         "//third_party/abseil-cpp/absl/flags:flag",
         "//third_party/abseil-cpp/absl/flags:parse",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
   }
@@ -125,7 +124,6 @@
       "../../../test:test_support",
       "//testing/gtest",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
diff --git a/modules/audio_processing/transient/transient_suppressor_unittest.cc b/modules/audio_processing/transient/transient_suppressor_unittest.cc
index ab48504..1a368d9 100644
--- a/modules/audio_processing/transient/transient_suppressor_unittest.cc
+++ b/modules/audio_processing/transient/transient_suppressor_unittest.cc
@@ -10,9 +10,9 @@
 
 #include "modules/audio_processing/transient/transient_suppressor.h"
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "modules/audio_processing/transient/common.h"
 #include "modules/audio_processing/transient/transient_suppressor_impl.h"
 #include "test/gtest.h"
@@ -23,13 +23,13 @@
 
 // Returns the index of the first non-zero sample in `samples` or an unspecified
 // value if no value is zero.
-absl::optional<int> FindFirstNonZeroSample(const std::vector<float>& samples) {
+std::optional<int> FindFirstNonZeroSample(const std::vector<float>& samples) {
   for (size_t i = 0; i < samples.size(); ++i) {
     if (samples[i] != 0.0f) {
       return i;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace
@@ -138,7 +138,7 @@
         /*key_pressed=*/false);
 
     // Detect the algorithmic delay of `TransientSuppressorImpl`.
-    absl::optional<int> frame_delay = FindFirstNonZeroSample(frame);
+    std::optional<int> frame_delay = FindFirstNonZeroSample(frame);
 
     // Check that the delayed voice probability is delayed according to the
     // measured delay.
diff --git a/modules/congestion_controller/goog_cc/BUILD.gn b/modules/congestion_controller/goog_cc/BUILD.gn
index a152729..f82a54a 100644
--- a/modules/congestion_controller/goog_cc/BUILD.gn
+++ b/modules/congestion_controller/goog_cc/BUILD.gn
@@ -43,7 +43,6 @@
     "../../remote_bitrate_estimator",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -55,7 +54,6 @@
   deps = [
     "../../../api/units:data_rate",
     "../../../rtc_base:safe_minmax",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -70,7 +68,6 @@
     "../../../api/units:data_size",
     "../../../rtc_base:checks",
     "../../../rtc_base/experiments:rate_control_settings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -90,7 +87,6 @@
     "../../../rtc_base/experiments:alr_experiment",
     "../../../rtc_base/experiments:field_trial_parser",
     "../../pacing:interval_budget",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 rtc_library("estimators") {
@@ -130,7 +126,6 @@
     "../../../rtc_base/experiments:field_trial_parser",
     "../../remote_bitrate_estimator",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -151,7 +146,6 @@
     "../../../rtc_base/experiments:field_trial_parser",
     "../../remote_bitrate_estimator",
     "//third_party/abseil-cpp/absl/algorithm:container",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -195,7 +189,6 @@
     "../../../system_wrappers:metrics",
     "../../remote_bitrate_estimator",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -227,7 +220,6 @@
     "../../../system_wrappers:metrics",
     "../../pacing",
     "../../remote_bitrate_estimator",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -255,7 +247,6 @@
     "../../../system_wrappers:metrics",
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -283,7 +274,6 @@
       "../../../test/logging:log_writer",
       "../../remote_bitrate_estimator",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
   if (!build_with_chromium) {
@@ -347,7 +337,6 @@
         "../../pacing",
         "//testing/gmock",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
   }
diff --git a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.cc b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.cc
index 11bae88..4310970 100644
--- a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.cc
+++ b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.cc
@@ -12,10 +12,10 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
@@ -56,11 +56,11 @@
   }
 }
 
-absl::optional<DataRate> AcknowledgedBitrateEstimator::bitrate() const {
+std::optional<DataRate> AcknowledgedBitrateEstimator::bitrate() const {
   return bitrate_estimator_->bitrate();
 }
 
-absl::optional<DataRate> AcknowledgedBitrateEstimator::PeekRate() const {
+std::optional<DataRate> AcknowledgedBitrateEstimator::PeekRate() const {
   return bitrate_estimator_->PeekRate();
 }
 
diff --git a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h
index a31c4df..68766f3 100644
--- a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h
+++ b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h
@@ -12,9 +12,9 @@
 #define MODULES_CONGESTION_CONTROLLER_GOOG_CC_ACKNOWLEDGED_BITRATE_ESTIMATOR_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
@@ -37,13 +37,13 @@
 
   void IncomingPacketFeedbackVector(
       const std::vector<PacketResult>& packet_feedback_vector) override;
-  absl::optional<DataRate> bitrate() const override;
-  absl::optional<DataRate> PeekRate() const override;
+  std::optional<DataRate> bitrate() const override;
+  std::optional<DataRate> PeekRate() const override;
   void SetAlr(bool in_alr) override;
   void SetAlrEndedTime(Timestamp alr_ended_time) override;
 
  private:
-  absl::optional<Timestamp> alr_ended_time_;
+  std::optional<Timestamp> alr_ended_time_;
   bool in_alr_;
   std::unique_ptr<BitrateEstimator> bitrate_estimator_;
 };
diff --git a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_interface.h b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_interface.h
index 44e455d..4ff8dc1 100644
--- a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_interface.h
+++ b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_interface.h
@@ -11,11 +11,10 @@
 #ifndef MODULES_CONGESTION_CONTROLLER_GOOG_CC_ACKNOWLEDGED_BITRATE_ESTIMATOR_INTERFACE_H_
 #define MODULES_CONGESTION_CONTROLLER_GOOG_CC_ACKNOWLEDGED_BITRATE_ESTIMATOR_INTERFACE_H_
 
-
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
@@ -75,8 +74,8 @@
 
   virtual void IncomingPacketFeedbackVector(
       const std::vector<PacketResult>& packet_feedback_vector) = 0;
-  virtual absl::optional<DataRate> bitrate() const = 0;
-  virtual absl::optional<DataRate> PeekRate() const = 0;
+  virtual std::optional<DataRate> bitrate() const = 0;
+  virtual std::optional<DataRate> PeekRate() const = 0;
   virtual void SetAlr(bool in_alr) = 0;
   virtual void SetAlrEndedTime(Timestamp alr_ended_time) = 0;
 };
diff --git a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_unittest.cc b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_unittest.cc
index 6e28f8e..81fb4fb 100644
--- a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_unittest.cc
+++ b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_unittest.cc
@@ -13,10 +13,10 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/transport/field_trial_based_config.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
@@ -47,7 +47,7 @@
               Update,
               (Timestamp at_time, DataSize data_size, bool in_alr),
               (override));
-  MOCK_METHOD(absl::optional<DataRate>, bitrate, (), (const, override));
+  MOCK_METHOD(std::optional<DataRate>, bitrate, (), (const, override));
   MOCK_METHOD(void, ExpectFastRateChange, (), (override));
 };
 
@@ -134,7 +134,7 @@
 
 TEST(TestAcknowledgedBitrateEstimator, ReturnBitrate) {
   auto states = CreateTestStates();
-  absl::optional<DataRate> return_value = DataRate::KilobitsPerSec(42);
+  std::optional<DataRate> return_value = DataRate::KilobitsPerSec(42);
   EXPECT_CALL(*states.mock_bitrate_estimator, bitrate())
       .Times(1)
       .WillOnce(Return(return_value));
diff --git a/modules/congestion_controller/goog_cc/alr_detector.cc b/modules/congestion_controller/goog_cc/alr_detector.cc
index 33dbdef..6cc7429 100644
--- a/modules/congestion_controller/goog_cc/alr_detector.cc
+++ b/modules/congestion_controller/goog_cc/alr_detector.cc
@@ -13,8 +13,8 @@
 #include <cstdint>
 #include <cstdio>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/rtc_event_log/rtc_event_log.h"
 #include "logging/rtc_event_log/events/rtc_event_alr_state.h"
@@ -28,7 +28,7 @@
 namespace {
 AlrDetectorConfig GetConfigFromTrials(const FieldTrialsView* key_value_config) {
   RTC_CHECK(AlrExperimentSettings::MaxOneFieldTrialEnabled(*key_value_config));
-  absl::optional<AlrExperimentSettings> experiment_settings =
+  std::optional<AlrExperimentSettings> experiment_settings =
       AlrExperimentSettings::CreateFromFieldTrial(
           *key_value_config,
           AlrExperimentSettings::kScreenshareProbingBweExperimentName);
@@ -105,7 +105,7 @@
   alr_budget_.set_target_rate_kbps(target_rate_kbps);
 }
 
-absl::optional<int64_t> AlrDetector::GetApplicationLimitedRegionStartTime()
+std::optional<int64_t> AlrDetector::GetApplicationLimitedRegionStartTime()
     const {
   return alr_started_time_ms_;
 }
diff --git a/modules/congestion_controller/goog_cc/alr_detector.h b/modules/congestion_controller/goog_cc/alr_detector.h
index bddcab3..e758b26 100644
--- a/modules/congestion_controller/goog_cc/alr_detector.h
+++ b/modules/congestion_controller/goog_cc/alr_detector.h
@@ -15,8 +15,8 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "modules/pacing/interval_budget.h"
 #include "rtc_base/experiments/struct_parameters_parser.h"
@@ -57,16 +57,16 @@
 
   // Returns time in milliseconds when the current application-limited region
   // started or empty result if the sender is currently not application-limited.
-  absl::optional<int64_t> GetApplicationLimitedRegionStartTime() const;
+  std::optional<int64_t> GetApplicationLimitedRegionStartTime() const;
 
  private:
   friend class GoogCcStatePrinter;
   const AlrDetectorConfig conf_;
 
-  absl::optional<int64_t> last_send_time_ms_;
+  std::optional<int64_t> last_send_time_ms_;
 
   IntervalBudget alr_budget_;
-  absl::optional<int64_t> alr_started_time_ms_;
+  std::optional<int64_t> alr_started_time_ms_;
 
   RtcEventLog* event_log_;
 };
diff --git a/modules/congestion_controller/goog_cc/alr_detector_unittest.cc b/modules/congestion_controller/goog_cc/alr_detector_unittest.cc
index da5852c..57c583d 100644
--- a/modules/congestion_controller/goog_cc/alr_detector_unittest.cc
+++ b/modules/congestion_controller/goog_cc/alr_detector_unittest.cc
@@ -11,8 +11,8 @@
 #include "modules/congestion_controller/goog_cc/alr_detector.h"
 
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/transport/field_trial_based_config.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/experiments/alr_experiment.h"
@@ -68,8 +68,8 @@
   }
   AlrDetector* const alr_detector_;
   int64_t* timestamp_ms_;
-  absl::optional<int> interval_ms_;
-  absl::optional<int> usage_percentage_;
+  std::optional<int> interval_ms_;
+  std::optional<int> usage_percentage_;
 };
 }  // namespace
 
@@ -158,7 +158,7 @@
 TEST(AlrDetectorTest, ParseControlFieldTrial) {
   webrtc::test::ScopedFieldTrials scoped_field_trial(
       "WebRTC-ProbingScreenshareBwe/Control/");
-  absl::optional<AlrExperimentSettings> parsed_params =
+  std::optional<AlrExperimentSettings> parsed_params =
       AlrExperimentSettings::CreateFromFieldTrial(
           FieldTrialBasedConfig(), "WebRTC-ProbingScreenshareBwe");
   EXPECT_FALSE(static_cast<bool>(parsed_params));
@@ -167,7 +167,7 @@
 TEST(AlrDetectorTest, ParseActiveFieldTrial) {
   webrtc::test::ScopedFieldTrials scoped_field_trial(
       "WebRTC-ProbingScreenshareBwe/1.1,2875,85,20,-20,1/");
-  absl::optional<AlrExperimentSettings> parsed_params =
+  std::optional<AlrExperimentSettings> parsed_params =
       AlrExperimentSettings::CreateFromFieldTrial(
           FieldTrialBasedConfig(), "WebRTC-ProbingScreenshareBwe");
   ASSERT_TRUE(static_cast<bool>(parsed_params));
diff --git a/modules/congestion_controller/goog_cc/bitrate_estimator.cc b/modules/congestion_controller/goog_cc/bitrate_estimator.cc
index 3ec9780..9140b8e 100644
--- a/modules/congestion_controller/goog_cc/bitrate_estimator.cc
+++ b/modules/congestion_controller/goog_cc/bitrate_estimator.cc
@@ -13,8 +13,8 @@
 #include <algorithm>
 #include <cmath>
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/units/data_rate.h"
 #include "api/units/data_size.h"
@@ -146,16 +146,16 @@
   return bitrate_sample;
 }
 
-absl::optional<DataRate> BitrateEstimator::bitrate() const {
+std::optional<DataRate> BitrateEstimator::bitrate() const {
   if (bitrate_estimate_kbps_ < 0.f)
-    return absl::nullopt;
+    return std::nullopt;
   return DataRate::KilobitsPerSec(bitrate_estimate_kbps_);
 }
 
-absl::optional<DataRate> BitrateEstimator::PeekRate() const {
+std::optional<DataRate> BitrateEstimator::PeekRate() const {
   if (current_window_ms_ > 0)
     return DataSize::Bytes(sum_) / TimeDelta::Millis(current_window_ms_);
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void BitrateEstimator::ExpectFastRateChange() {
diff --git a/modules/congestion_controller/goog_cc/bitrate_estimator.h b/modules/congestion_controller/goog_cc/bitrate_estimator.h
index 5ca8234..a808a82 100644
--- a/modules/congestion_controller/goog_cc/bitrate_estimator.h
+++ b/modules/congestion_controller/goog_cc/bitrate_estimator.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/field_trials_view.h"
 #include "api/units/data_rate.h"
 #include "api/units/data_size.h"
@@ -33,8 +34,8 @@
   virtual ~BitrateEstimator();
   virtual void Update(Timestamp at_time, DataSize amount, bool in_alr);
 
-  virtual absl::optional<DataRate> bitrate() const;
-  absl::optional<DataRate> PeekRate() const;
+  virtual std::optional<DataRate> bitrate() const;
+  std::optional<DataRate> PeekRate() const;
 
   virtual void ExpectFastRateChange();
 
diff --git a/modules/congestion_controller/goog_cc/congestion_window_pushback_controller.h b/modules/congestion_controller/goog_cc/congestion_window_pushback_controller.h
index a344fa1..208331f 100644
--- a/modules/congestion_controller/goog_cc/congestion_window_pushback_controller.h
+++ b/modules/congestion_controller/goog_cc/congestion_window_pushback_controller.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/field_trials_view.h"
 #include "api/units/data_size.h"
 
@@ -36,7 +37,7 @@
  private:
   const bool add_pacing_;
   const uint32_t min_pushback_target_bitrate_bps_;
-  absl::optional<DataSize> current_data_window_;
+  std::optional<DataSize> current_data_window_;
   int64_t outstanding_bytes_ = 0;
   int64_t pacing_bytes_ = 0;
   double encoding_rate_ratio_ = 1.0;
diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe.cc b/modules/congestion_controller/goog_cc/delay_based_bwe.cc
index 187ef69..e2ab104 100644
--- a/modules/congestion_controller/goog_cc/delay_based_bwe.cc
+++ b/modules/congestion_controller/goog_cc/delay_based_bwe.cc
@@ -13,10 +13,10 @@
 #include <algorithm>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/network_state_predictor.h"
 #include "api/rtc_event_log/rtc_event_log.h"
@@ -98,9 +98,9 @@
 
 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector(
     const TransportPacketsFeedback& msg,
-    absl::optional<DataRate> acked_bitrate,
-    absl::optional<DataRate> probe_bitrate,
-    absl::optional<NetworkStateEstimate> network_estimate,
+    std::optional<DataRate> acked_bitrate,
+    std::optional<DataRate> probe_bitrate,
+    std::optional<NetworkStateEstimate> network_estimate,
     bool in_alr) {
   RTC_DCHECK_RUNS_SERIALIZED(&network_race_);
 
@@ -204,15 +204,15 @@
 }
 
 DataRate DelayBasedBwe::TriggerOveruse(Timestamp at_time,
-                                       absl::optional<DataRate> link_capacity) {
+                                       std::optional<DataRate> link_capacity) {
   RateControlInput input(BandwidthUsage::kBwOverusing, link_capacity);
   return rate_control_.Update(input, at_time);
 }
 
 DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate(
-    absl::optional<DataRate> acked_bitrate,
-    absl::optional<DataRate> probe_bitrate,
-    absl::optional<NetworkStateEstimate> state_estimate,
+    std::optional<DataRate> acked_bitrate,
+    std::optional<DataRate> probe_bitrate,
+    std::optional<NetworkStateEstimate> state_estimate,
     bool recovered_from_overuse,
     bool in_alr,
     Timestamp at_time) {
@@ -266,7 +266,7 @@
 }
 
 bool DelayBasedBwe::UpdateEstimate(Timestamp at_time,
-                                   absl::optional<DataRate> acked_bitrate,
+                                   std::optional<DataRate> acked_bitrate,
                                    DataRate* target_rate) {
   const RateControlInput input(active_delay_detector_->State(), acked_bitrate);
   *target_rate = rate_control_.Update(input, at_time);
diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe.h b/modules/congestion_controller/goog_cc/delay_based_bwe.h
index 3bdab4a..50dcae9 100644
--- a/modules/congestion_controller/goog_cc/delay_based_bwe.h
+++ b/modules/congestion_controller/goog_cc/delay_based_bwe.h
@@ -14,9 +14,9 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/network_state_predictor.h"
 #include "api/transport/bandwidth_usage.h"
@@ -74,9 +74,9 @@
 
   Result IncomingPacketFeedbackVector(
       const TransportPacketsFeedback& msg,
-      absl::optional<DataRate> acked_bitrate,
-      absl::optional<DataRate> probe_bitrate,
-      absl::optional<NetworkStateEstimate> network_estimate,
+      std::optional<DataRate> acked_bitrate,
+      std::optional<DataRate> probe_bitrate,
+      std::optional<NetworkStateEstimate> network_estimate,
       bool in_alr);
   void OnRttUpdate(TimeDelta avg_rtt);
   bool LatestEstimate(std::vector<uint32_t>* ssrcs, DataRate* bitrate) const;
@@ -84,7 +84,7 @@
   void SetMinBitrate(DataRate min_bitrate);
   TimeDelta GetExpectedBwePeriod() const;
   DataRate TriggerOveruse(Timestamp at_time,
-                          absl::optional<DataRate> link_capacity);
+                          std::optional<DataRate> link_capacity);
   DataRate last_estimate() const { return prev_bitrate_; }
   BandwidthUsage last_state() const { return prev_state_; }
 
@@ -92,17 +92,16 @@
   friend class GoogCcStatePrinter;
   void IncomingPacketFeedback(const PacketResult& packet_feedback,
                               Timestamp at_time);
-  Result MaybeUpdateEstimate(
-      absl::optional<DataRate> acked_bitrate,
-      absl::optional<DataRate> probe_bitrate,
-      absl::optional<NetworkStateEstimate> state_estimate,
-      bool recovered_from_overuse,
-      bool in_alr,
-      Timestamp at_time);
+  Result MaybeUpdateEstimate(std::optional<DataRate> acked_bitrate,
+                             std::optional<DataRate> probe_bitrate,
+                             std::optional<NetworkStateEstimate> state_estimate,
+                             bool recovered_from_overuse,
+                             bool in_alr,
+                             Timestamp at_time);
   // Updates the current remote rate estimate and returns true if a valid
   // estimate exists.
   bool UpdateEstimate(Timestamp at_time,
-                      absl::optional<DataRate> acked_bitrate,
+                      std::optional<DataRate> acked_bitrate,
                       DataRate* target_rate);
 
   rtc::RaceChecker network_race_;
diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc b/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc
index e56aa4a..433d3cb 100644
--- a/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc
+++ b/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc
@@ -13,9 +13,9 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
 #include "api/units/data_size.h"
@@ -220,7 +220,7 @@
       bitrate_estimator_->IncomingPacketFeedbackVector(
           msg, acknowledged_bitrate_estimator_->bitrate(),
           probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(),
-          /*network_estimate*/ absl::nullopt, /*in_alr*/ false);
+          /*network_estimate*/ std::nullopt, /*in_alr*/ false);
   if (result.updated) {
     bitrate_observer_.OnReceiveBitrateChanged(result.target_bitrate.bps());
   }
@@ -264,7 +264,7 @@
       bitrate_estimator_->IncomingPacketFeedbackVector(
           msg, acknowledged_bitrate_estimator_->bitrate(),
           probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(),
-          /*network_estimate*/ absl::nullopt, /*in_alr*/ false);
+          /*network_estimate*/ std::nullopt, /*in_alr*/ false);
   if (result.updated) {
     bitrate_observer_.OnReceiveBitrateChanged(result.target_bitrate.bps());
     if (!first_update_ && result.target_bitrate.bps() < bitrate_bps)
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
index ddc4aa2..9b00511 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
@@ -16,11 +16,11 @@
 #include <cstdint>
 #include <memory>
 #include <numeric>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/field_trials_view.h"
 #include "api/transport/bandwidth_usage.h"
@@ -163,7 +163,7 @@
 NetworkControlUpdate GoogCcNetworkController::OnNetworkRouteChange(
     NetworkRouteChange msg) {
   if (safe_reset_on_route_change_) {
-    absl::optional<DataRate> estimated_bitrate;
+    std::optional<DataRate> estimated_bitrate;
     if (safe_reset_acknowledged_rate_) {
       estimated_bitrate = acknowledged_bitrate_estimator_->bitrate();
       if (!estimated_bitrate)
@@ -213,7 +213,7 @@
           *initial_config_->stream_based_config
                .enable_repeated_initial_probing);
     }
-    absl::optional<DataRate> total_bitrate =
+    std::optional<DataRate> total_bitrate =
         initial_config_->stream_based_config.max_total_allocated_bitrate;
     if (total_bitrate) {
       auto probes = probe_controller_->OnMaxTotalAllocatedBitrate(
@@ -228,7 +228,7 @@
         msg.pacer_queue->bytes());
   }
   bandwidth_estimation_->UpdateEstimate(msg.at_time);
-  absl::optional<int64_t> start_time_ms =
+  std::optional<int64_t> start_time_ms =
       alr_detector_->GetApplicationLimitedRegionStartTime();
   probe_controller_->SetAlrStartTimeMs(start_time_ms);
 
@@ -494,7 +494,7 @@
       lost_packets_since_last_loss_update_ = 0;
     }
   }
-  absl::optional<int64_t> alr_start_time =
+  std::optional<int64_t> alr_start_time =
       alr_detector_->GetApplicationLimitedRegionStartTime();
 
   if (previously_in_alr_ && !alr_start_time.has_value()) {
@@ -519,7 +519,7 @@
     network_estimator_->OnTransportPacketsFeedback(report);
     SetNetworkStateEstimate(network_estimator_->GetCurrentEstimate());
   }
-  absl::optional<DataRate> probe_bitrate =
+  std::optional<DataRate> probe_bitrate =
       probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate();
   if (ignore_probes_lower_than_network_estimate_ && probe_bitrate &&
       estimate_ && *probe_bitrate < delay_based_bwe_->last_estimate() &&
@@ -601,7 +601,7 @@
 }
 
 void GoogCcNetworkController::SetNetworkStateEstimate(
-    absl::optional<NetworkStateEstimate> estimate) {
+    std::optional<NetworkStateEstimate> estimate) {
   auto prev_estimate = estimate_;
   estimate_ = estimate;
   if (estimate_ && (!prev_estimate ||
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.h b/modules/congestion_controller/goog_cc/goog_cc_network_control.h
index 46ef23f..7e7fe07 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control.h
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.h
@@ -15,9 +15,9 @@
 
 #include <deque>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/network_state_predictor.h"
 #include "api/transport/network_control.h"
@@ -83,7 +83,7 @@
                                     Timestamp at_time);
   void UpdateCongestionWindowSize();
   PacerConfig GetPacingRates(Timestamp at_time) const;
-  void SetNetworkStateEstimate(absl::optional<NetworkStateEstimate> estimate);
+  void SetNetworkStateEstimate(std::optional<NetworkStateEstimate> estimate);
 
   const Environment env_;
   const bool packet_feedback_only_;
@@ -109,16 +109,16 @@
   std::unique_ptr<AcknowledgedBitrateEstimatorInterface>
       acknowledged_bitrate_estimator_;
 
-  absl::optional<NetworkControllerConfig> initial_config_;
+  std::optional<NetworkControllerConfig> initial_config_;
 
   DataRate min_target_rate_ = DataRate::Zero();
   DataRate min_data_rate_ = DataRate::Zero();
   DataRate max_data_rate_ = DataRate::PlusInfinity();
-  absl::optional<DataRate> starting_rate_;
+  std::optional<DataRate> starting_rate_;
 
   bool first_packet_sent_ = false;
 
-  absl::optional<NetworkStateEstimate> estimate_;
+  std::optional<NetworkStateEstimate> estimate_;
 
   Timestamp next_loss_update_ = Timestamp::MinusInfinity();
   int lost_packets_since_last_loss_update_ = 0;
@@ -131,7 +131,7 @@
   DataRate last_stable_target_rate_;
   LossBasedState last_loss_base_state_;
 
-  absl::optional<uint8_t> last_estimated_fraction_loss_ = 0;
+  std::optional<uint8_t> last_estimated_fraction_loss_ = 0;
   TimeDelta last_estimated_round_trip_time_ = TimeDelta::PlusInfinity();
 
   double pacing_factor_;
@@ -140,7 +140,7 @@
 
   bool previously_in_alr_ = false;
 
-  absl::optional<DataSize> current_data_window_;
+  std::optional<DataSize> current_data_window_;
 };
 
 }  // namespace webrtc
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
index aee5bd1..e34dfee 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
@@ -12,13 +12,13 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <queue>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
 #include "api/test/network_emulation/create_cross_traffic.h"
@@ -94,9 +94,9 @@
 
 NetworkRouteChange CreateRouteChange(
     Timestamp time,
-    absl::optional<DataRate> start_rate = absl::nullopt,
-    absl::optional<DataRate> min_rate = absl::nullopt,
-    absl::optional<DataRate> max_rate = absl::nullopt) {
+    std::optional<DataRate> start_rate = std::nullopt,
+    std::optional<DataRate> min_rate = std::nullopt,
+    std::optional<DataRate> max_rate = std::nullopt) {
   NetworkRouteChange route_change;
   route_change.at_time = time;
   route_change.constraints.at_time = time;
@@ -121,13 +121,13 @@
 
 // Simulate sending packets and receiving transport feedback during
 // `runtime_ms`, then return the final target birate.
-absl::optional<DataRate> PacketTransmissionAndFeedbackBlock(
+std::optional<DataRate> PacketTransmissionAndFeedbackBlock(
     NetworkControllerInterface* controller,
     int64_t runtime_ms,
     int64_t delay,
     Timestamp& current_time) {
   NetworkControlUpdate update;
-  absl::optional<DataRate> target_bitrate;
+  std::optional<DataRate> target_bitrate;
   int64_t delay_buildup = 0;
   int64_t start_time_ms = current_time.ms();
   while (current_time.ms() - start_time_ms < runtime_ms) {
@@ -423,14 +423,14 @@
   // The test must run and insert packets/feedback long enough that the
   // BWE computes a valid estimate. This is first done in an environment which
   // simulates no bandwidth limitation, and therefore not built-up delay.
-  absl::optional<DataRate> target_bitrate_before_delay =
+  std::optional<DataRate> target_bitrate_before_delay =
       PacketTransmissionAndFeedbackBlock(controller.get(), kRunTimeMs, 0,
                                          current_time);
   ASSERT_TRUE(target_bitrate_before_delay.has_value());
 
   // Repeat, but this time with a building delay, and make sure that the
   // estimation is adjusted downwards.
-  absl::optional<DataRate> target_bitrate_after_delay =
+  std::optional<DataRate> target_bitrate_after_delay =
       PacketTransmissionAndFeedbackBlock(controller.get(), kRunTimeMs, 50,
                                          current_time);
   EXPECT_LT(*target_bitrate_after_delay, *target_bitrate_before_delay);
@@ -1098,7 +1098,7 @@
       fixture.CreateController();
   Timestamp current_time = Timestamp::Millis(123);
   TimeDelta one_way_delay = TimeDelta::Millis(10);
-  absl::optional<TimeDelta> rtt = absl::nullopt;
+  std::optional<TimeDelta> rtt = std::nullopt;
 
   TransportPacketsFeedback feedback = CreateTransportPacketsFeedback(
       /*per_packet_network_delay=*/TimeDelta::Millis(50), one_way_delay,
diff --git a/modules/congestion_controller/goog_cc/link_capacity_estimator.h b/modules/congestion_controller/goog_cc/link_capacity_estimator.h
index aa23491..5c4cbd4 100644
--- a/modules/congestion_controller/goog_cc/link_capacity_estimator.h
+++ b/modules/congestion_controller/goog_cc/link_capacity_estimator.h
@@ -10,7 +10,8 @@
 #ifndef MODULES_CONGESTION_CONTROLLER_GOOG_CC_LINK_CAPACITY_ESTIMATOR_H_
 #define MODULES_CONGESTION_CONTROLLER_GOOG_CC_LINK_CAPACITY_ESTIMATOR_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/data_rate.h"
 
 namespace webrtc {
@@ -30,7 +31,7 @@
   void Update(DataRate capacity_sample, double alpha);
 
   double deviation_estimate_kbps() const;
-  absl::optional<double> estimate_kbps_;
+  std::optional<double> estimate_kbps_;
   double deviation_kbps_ = 0.4;
 };
 }  // namespace webrtc
diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc
index 80a1888..559f23a 100644
--- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc
+++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc
@@ -15,10 +15,10 @@
 #include <cstddef>
 #include <cstdlib>
 #include <limits>
+#include <optional>
 #include <vector>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/field_trials_view.h"
 #include "api/transport/network_types.h"
@@ -42,7 +42,7 @@
   return datarate.IsFinite();
 }
 
-bool IsValid(absl::optional<DataRate> datarate) {
+bool IsValid(std::optional<DataRate> datarate) {
   return datarate.has_value() && IsValid(datarate.value());
 }
 
@@ -396,7 +396,7 @@
 
 // Returns a `LossBasedBweV2::Config` iff the `key_value_config` specifies a
 // configuration for the `LossBasedBweV2` which is explicitly enabled.
-absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
+std::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
     const FieldTrialsView* key_value_config) {
   FieldTrialParameter<bool> enabled("Enabled", true);
   FieldTrialParameter<double> bandwidth_rampup_upper_bound_factor(
@@ -514,7 +514,7 @@
   }
 
   if (!enabled.Get()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   Config config;
   config.bandwidth_rampup_upper_bound_factor =
diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h
index c855f58..14e9d3d 100644
--- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h
+++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h
@@ -12,10 +12,10 @@
 #define MODULES_CONGESTION_CONTROLLER_GOOG_CC_LOSS_BASED_BWE_V2_H_
 
 #include <cstdint>
+#include <optional>
 #include <unordered_map>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/field_trials_view.h"
 #include "api/transport/network_types.h"
@@ -164,7 +164,7 @@
     DataRate rate = DataRate::PlusInfinity();
   };
 
-  static absl::optional<Config> CreateConfig(
+  static std::optional<Config> CreateConfig(
       const FieldTrialsView* key_value_config);
   bool IsConfigValid() const;
 
@@ -200,16 +200,16 @@
   bool IsInLossLimitedState() const;
   bool CanKeepIncreasingState(DataRate estimate) const;
 
-  absl::optional<DataRate> acknowledged_bitrate_;
-  absl::optional<Config> config_;
+  std::optional<DataRate> acknowledged_bitrate_;
+  std::optional<Config> config_;
   ChannelParameters current_best_estimate_;
   int num_observations_ = 0;
   std::vector<Observation> observations_;
   PartialObservation partial_observation_;
   Timestamp last_send_time_most_recent_observation_ = Timestamp::PlusInfinity();
   Timestamp last_time_estimate_reduced_ = Timestamp::MinusInfinity();
-  absl::optional<DataRate> cached_instant_upper_bound_;
-  absl::optional<DataRate> cached_instant_lower_bound_;
+  std::optional<DataRate> cached_instant_upper_bound_;
+  std::optional<DataRate> cached_instant_lower_bound_;
   std::vector<double> instant_upper_bound_temporal_weights_;
   std::vector<double> temporal_weights_;
   Timestamp recovering_after_loss_timestamp_ = Timestamp::MinusInfinity();
diff --git a/modules/congestion_controller/goog_cc/probe_bitrate_estimator.cc b/modules/congestion_controller/goog_cc/probe_bitrate_estimator.cc
index 99d7d4c..62b6a6b 100644
--- a/modules/congestion_controller/goog_cc/probe_bitrate_estimator.cc
+++ b/modules/congestion_controller/goog_cc/probe_bitrate_estimator.cc
@@ -12,8 +12,8 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/rtc_event_log/rtc_event_log.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
@@ -64,7 +64,7 @@
 
 ProbeBitrateEstimator::~ProbeBitrateEstimator() = default;
 
-absl::optional<DataRate> ProbeBitrateEstimator::HandleProbeAndEstimateBitrate(
+std::optional<DataRate> ProbeBitrateEstimator::HandleProbeAndEstimateBitrate(
     const PacketResult& packet_feedback) {
   int cluster_id = packet_feedback.sent_packet.pacing_info.probe_cluster_id;
   RTC_DCHECK_NE(cluster_id, PacedPacketInfo::kNotAProbe);
@@ -103,7 +103,7 @@
           packet_feedback.sent_packet.pacing_info.probe_cluster_min_bytes) *
       kMinReceivedBytesRatio;
   if (cluster->num_probes < min_probes || cluster->size_total < min_size)
-    return absl::nullopt;
+    return std::nullopt;
 
   TimeDelta send_interval = cluster->last_send - cluster->first_send;
   TimeDelta receive_interval = cluster->last_receive - cluster->first_receive;
@@ -122,7 +122,7 @@
       event_log_->Log(std::make_unique<RtcEventProbeResultFailure>(
           cluster_id, ProbeFailureReason::kInvalidSendReceiveInterval));
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
   // Since the `send_interval` does not include the time it takes to actually
   // send the last packet the size of the last sent packet should not be
@@ -159,7 +159,7 @@
       event_log_->Log(std::make_unique<RtcEventProbeResultFailure>(
           cluster_id, ProbeFailureReason::kInvalidSendReceiveRatio));
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
   RTC_LOG(LS_INFO) << "Probing successful"
                       " [cluster id: "
@@ -187,9 +187,9 @@
   return estimated_data_rate_;
 }
 
-absl::optional<DataRate>
+std::optional<DataRate>
 ProbeBitrateEstimator::FetchAndResetLastEstimatedBitrate() {
-  absl::optional<DataRate> estimated_data_rate = estimated_data_rate_;
+  std::optional<DataRate> estimated_data_rate = estimated_data_rate_;
   estimated_data_rate_.reset();
   return estimated_data_rate;
 }
diff --git a/modules/congestion_controller/goog_cc/probe_bitrate_estimator.h b/modules/congestion_controller/goog_cc/probe_bitrate_estimator.h
index f11aece..fdb5540 100644
--- a/modules/congestion_controller/goog_cc/probe_bitrate_estimator.h
+++ b/modules/congestion_controller/goog_cc/probe_bitrate_estimator.h
@@ -12,8 +12,8 @@
 #define MODULES_CONGESTION_CONTROLLER_GOOG_CC_PROBE_BITRATE_ESTIMATOR_H_
 
 #include <map>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
 #include "api/units/data_size.h"
@@ -29,10 +29,10 @@
 
   // Should be called for every probe packet we receive feedback about.
   // Returns the estimated bitrate if the probe completes a valid cluster.
-  absl::optional<DataRate> HandleProbeAndEstimateBitrate(
+  std::optional<DataRate> HandleProbeAndEstimateBitrate(
       const PacketResult& packet_feedback);
 
-  absl::optional<DataRate> FetchAndResetLastEstimatedBitrate();
+  std::optional<DataRate> FetchAndResetLastEstimatedBitrate();
 
  private:
   struct AggregatedCluster {
@@ -51,7 +51,7 @@
 
   std::map<int, AggregatedCluster> clusters_;
   RtcEventLog* const event_log_;
-  absl::optional<DataRate> estimated_data_rate_;
+  std::optional<DataRate> estimated_data_rate_;
 };
 
 }  // namespace webrtc
diff --git a/modules/congestion_controller/goog_cc/probe_bitrate_estimator_unittest.cc b/modules/congestion_controller/goog_cc/probe_bitrate_estimator_unittest.cc
index efb9725..a8113c9 100644
--- a/modules/congestion_controller/goog_cc/probe_bitrate_estimator_unittest.cc
+++ b/modules/congestion_controller/goog_cc/probe_bitrate_estimator_unittest.cc
@@ -13,8 +13,8 @@
 #include <stddef.h>
 
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
 #include "api/units/data_size.h"
@@ -55,7 +55,7 @@
   }
 
  protected:
-  absl::optional<DataRate> measured_data_rate_;
+  std::optional<DataRate> measured_data_rate_;
   ProbeBitrateEstimator probe_bitrate_estimator_;
 };
 
diff --git a/modules/congestion_controller/goog_cc/probe_controller.cc b/modules/congestion_controller/goog_cc/probe_controller.cc
index 44cb0a7..bc56ce0 100644
--- a/modules/congestion_controller/goog_cc/probe_controller.cc
+++ b/modules/congestion_controller/goog_cc/probe_controller.cc
@@ -14,10 +14,10 @@
 #include <cstdint>
 #include <initializer_list>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/rtc_event_log/rtc_event_log.h"
 #include "api/transport/network_types.h"
@@ -375,11 +375,11 @@
 }
 
 void ProbeController::SetAlrStartTimeMs(
-    absl::optional<int64_t> alr_start_time_ms) {
+    std::optional<int64_t> alr_start_time_ms) {
   if (alr_start_time_ms) {
     alr_start_time_ = Timestamp::Millis(*alr_start_time_ms);
   } else {
-    alr_start_time_ = absl::nullopt;
+    alr_start_time_ = std::nullopt;
   }
 }
 void ProbeController::SetAlrEndedTimeMs(int64_t alr_end_time_ms) {
@@ -433,7 +433,7 @@
   min_bitrate_to_probe_further_ = DataRate::PlusInfinity();
   time_last_probing_initiated_ = Timestamp::Zero();
   estimated_bitrate_ = DataRate::Zero();
-  network_estimate_ = absl::nullopt;
+  network_estimate_ = std::nullopt;
   start_bitrate_ = DataRate::Zero();
   max_bitrate_ = kDefaultMaxProbingBitrate;
   Timestamp now = at_time;
diff --git a/modules/congestion_controller/goog_cc/probe_controller.h b/modules/congestion_controller/goog_cc/probe_controller.h
index 96c6091..7d769da 100644
--- a/modules/congestion_controller/goog_cc/probe_controller.h
+++ b/modules/congestion_controller/goog_cc/probe_controller.h
@@ -13,10 +13,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
 #include "absl/base/attributes.h"
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/rtc_event_log/rtc_event_log.h"
 #include "api/transport/network_types.h"
@@ -138,7 +138,7 @@
   // SetBitrates.
   void EnableRepeatedInitialProbing(bool enable);
 
-  void SetAlrStartTimeMs(absl::optional<int64_t> alr_start_time);
+  void SetAlrStartTimeMs(std::optional<int64_t> alr_start_time);
   void SetAlrEndedTimeMs(int64_t alr_end_time);
 
   ABSL_MUST_USE_RESULT std::vector<ProbeClusterConfig> RequestProbe(
@@ -187,12 +187,12 @@
   DataRate min_bitrate_to_probe_further_ = DataRate::PlusInfinity();
   Timestamp time_last_probing_initiated_ = Timestamp::MinusInfinity();
   DataRate estimated_bitrate_ = DataRate::Zero();
-  absl::optional<webrtc::NetworkStateEstimate> network_estimate_;
+  std::optional<webrtc::NetworkStateEstimate> network_estimate_;
   DataRate start_bitrate_ = DataRate::Zero();
   DataRate max_bitrate_ = DataRate::PlusInfinity();
   Timestamp last_bwe_drop_probing_time_ = Timestamp::Zero();
-  absl::optional<Timestamp> alr_start_time_;
-  absl::optional<Timestamp> alr_end_time_;
+  std::optional<Timestamp> alr_start_time_;
+  std::optional<Timestamp> alr_end_time_;
   bool enable_periodic_alr_probing_;
   Timestamp time_of_last_large_drop_ = Timestamp::MinusInfinity();
   DataRate bitrate_before_last_large_drop_ = DataRate::Zero();
diff --git a/modules/congestion_controller/goog_cc/probe_controller_unittest.cc b/modules/congestion_controller/goog_cc/probe_controller_unittest.cc
index 5ee7cc7..01d4a6d 100644
--- a/modules/congestion_controller/goog_cc/probe_controller_unittest.cc
+++ b/modules/congestion_controller/goog_cc/probe_controller_unittest.cc
@@ -10,10 +10,10 @@
 #include "modules/congestion_controller/goog_cc/probe_controller.h"
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
 #include "api/units/time_delta.h"
@@ -210,7 +210,7 @@
   EXPECT_EQ(probes.at(0).target_data_rate, kMaxBitrate);
 
   // Do not probe when not in alr.
-  probe_controller->SetAlrStartTimeMs(absl::nullopt);
+  probe_controller->SetAlrStartTimeMs(std::nullopt);
   probes = probe_controller->OnMaxTotalAllocatedBitrate(
       kMaxBitrate + DataRate::BitsPerSec(2), fixture.CurrentTime());
   EXPECT_TRUE(probes.empty());
@@ -520,7 +520,7 @@
       DataRate::BitsPerSec(500), BandwidthLimitedCause::kDelayBasedLimited,
       fixture.CurrentTime());
 
-  probe_controller->SetAlrStartTimeMs(absl::nullopt);
+  probe_controller->SetAlrStartTimeMs(std::nullopt);
   fixture.AdvanceTime(kAlrProbeInterval + TimeDelta::Millis(1));
   probes = probe_controller->Process(fixture.CurrentTime());
   probes = probe_controller->SetEstimatedBitrate(
@@ -548,7 +548,7 @@
       DataRate::BitsPerSec(500), BandwidthLimitedCause::kDelayBasedLimited,
       fixture.CurrentTime());
 
-  probe_controller->SetAlrStartTimeMs(absl::nullopt);
+  probe_controller->SetAlrStartTimeMs(std::nullopt);
   fixture.AdvanceTime(kAlrProbeInterval + TimeDelta::Millis(1));
   probes = probe_controller->Process(fixture.CurrentTime());
   probes = probe_controller->SetEstimatedBitrate(
@@ -1066,7 +1066,7 @@
   probes = probe_controller->Process(fixture.CurrentTime());
   ASSERT_TRUE(probes.empty());
 
-  probe_controller->SetAlrStartTimeMs(absl::nullopt);
+  probe_controller->SetAlrStartTimeMs(std::nullopt);
   fixture.AdvanceTime(kAlrProbeInterval + TimeDelta::Millis(1));
   probes = probe_controller->Process(fixture.CurrentTime());
   EXPECT_TRUE(probes.empty());
diff --git a/modules/congestion_controller/goog_cc/robust_throughput_estimator.cc b/modules/congestion_controller/goog_cc/robust_throughput_estimator.cc
index 5a22910..3aad0c9 100644
--- a/modules/congestion_controller/goog_cc/robust_throughput_estimator.cc
+++ b/modules/congestion_controller/goog_cc/robust_throughput_estimator.cc
@@ -13,10 +13,10 @@
 #include <stddef.h>
 
 #include <algorithm>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
 #include "api/units/data_size.h"
@@ -101,9 +101,9 @@
   }
 }
 
-absl::optional<DataRate> RobustThroughputEstimator::bitrate() const {
+std::optional<DataRate> RobustThroughputEstimator::bitrate() const {
   if (window_.empty() || window_.size() < settings_.required_packets)
-    return absl::nullopt;
+    return std::nullopt;
 
   TimeDelta largest_recv_gap(TimeDelta::Zero());
   TimeDelta second_largest_recv_gap(TimeDelta::Zero());
diff --git a/modules/congestion_controller/goog_cc/robust_throughput_estimator.h b/modules/congestion_controller/goog_cc/robust_throughput_estimator.h
index 9d89856..a1dc139 100644
--- a/modules/congestion_controller/goog_cc/robust_throughput_estimator.h
+++ b/modules/congestion_controller/goog_cc/robust_throughput_estimator.h
@@ -12,9 +12,9 @@
 #define MODULES_CONGESTION_CONTROLLER_GOOG_CC_ROBUST_THROUGHPUT_ESTIMATOR_H_
 
 #include <deque>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
 #include "api/units/timestamp.h"
@@ -31,9 +31,9 @@
   void IncomingPacketFeedbackVector(
       const std::vector<PacketResult>& packet_feedback_vector) override;
 
-  absl::optional<DataRate> bitrate() const override;
+  std::optional<DataRate> bitrate() const override;
 
-  absl::optional<DataRate> PeekRate() const override { return bitrate(); }
+  std::optional<DataRate> PeekRate() const override { return bitrate(); }
   void SetAlr(bool /*in_alr*/) override {}
   void SetAlrEndedTime(Timestamp /*alr_ended_time*/) override {}
 
diff --git a/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc b/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc
index c5e1117..4a32609 100644
--- a/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc
+++ b/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc
@@ -16,10 +16,10 @@
 #include <cstdio>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/rtc_event_log/rtc_event_log.h"
 #include "api/transport/bandwidth_usage.h"
@@ -125,7 +125,7 @@
     capacity_estimate_bps_ = start_rate.bps<double>();
 }
 
-void LinkCapacityTracker::OnRateUpdate(absl::optional<DataRate> acknowledged,
+void LinkCapacityTracker::OnRateUpdate(std::optional<DataRate> acknowledged,
                                        DataRate target,
                                        Timestamp at_time) {
   if (!acknowledged)
@@ -278,7 +278,7 @@
 }
 
 void SendSideBandwidthEstimation::SetBitrates(
-    absl::optional<DataRate> send_bitrate,
+    std::optional<DataRate> send_bitrate,
     DataRate min_bitrate,
     DataRate max_bitrate,
     Timestamp at_time) {
@@ -354,7 +354,7 @@
 }
 
 void SendSideBandwidthEstimation::SetAcknowledgedRate(
-    absl::optional<DataRate> acknowledged_rate,
+    std::optional<DataRate> acknowledged_rate,
     Timestamp at_time) {
   acknowledged_rate_ = acknowledged_rate;
   if (!acknowledged_rate.has_value()) {
@@ -373,7 +373,7 @@
 void SendSideBandwidthEstimation::UpdateLossBasedEstimator(
     const TransportPacketsFeedback& report,
     BandwidthUsage delay_detector_state,
-    absl::optional<DataRate> probe_bitrate,
+    std::optional<DataRate> probe_bitrate,
     bool in_alr) {
   if (LossBasedBandwidthEstimatorV1Enabled()) {
     loss_based_bandwidth_estimator_v1_.UpdateLossStatistics(
diff --git a/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h b/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h
index 3f26fdf..9a56a28 100644
--- a/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h
+++ b/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h
@@ -17,10 +17,10 @@
 
 #include <deque>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/transport/bandwidth_usage.h"
 #include "api/transport/network_types.h"
@@ -43,7 +43,7 @@
   void UpdateDelayBasedEstimate(Timestamp at_time,
                                 DataRate delay_based_bitrate);
   void OnStartingRate(DataRate start_rate);
-  void OnRateUpdate(absl::optional<DataRate> acknowledged,
+  void OnRateUpdate(std::optional<DataRate> acknowledged,
                     DataRate target,
                     Timestamp at_time);
   void OnRttBackoff(DataRate backoff_rate, Timestamp at_time);
@@ -115,18 +115,18 @@
   // Call when we receive a RTCP message with a ReceiveBlock.
   void UpdateRtt(TimeDelta rtt, Timestamp at_time);
 
-  void SetBitrates(absl::optional<DataRate> send_bitrate,
+  void SetBitrates(std::optional<DataRate> send_bitrate,
                    DataRate min_bitrate,
                    DataRate max_bitrate,
                    Timestamp at_time);
   void SetSendBitrate(DataRate bitrate, Timestamp at_time);
   void SetMinMaxBitrate(DataRate min_bitrate, DataRate max_bitrate);
   int GetMinBitrate() const;
-  void SetAcknowledgedRate(absl::optional<DataRate> acknowledged_rate,
+  void SetAcknowledgedRate(std::optional<DataRate> acknowledged_rate,
                            Timestamp at_time);
   void UpdateLossBasedEstimator(const TransportPacketsFeedback& report,
                                 BandwidthUsage delay_detector_state,
-                                absl::optional<DataRate> probe_bitrate,
+                                std::optional<DataRate> probe_bitrate,
                                 bool in_alr);
   bool PaceAtLossBasedEstimate() const;
 
@@ -178,7 +178,7 @@
   int lost_packets_since_last_loss_update_;
   int expected_packets_since_last_loss_update_;
 
-  absl::optional<DataRate> acknowledged_rate_;
+  std::optional<DataRate> acknowledged_rate_;
   DataRate current_target_;
   DataRate last_logged_target_;
   DataRate min_bitrate_configured_;
diff --git a/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc b/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc
index 51a67de..669fa4d 100644
--- a/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc
+++ b/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc
@@ -13,11 +13,11 @@
 
 #include <deque>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/rtc_event_log_output.h"
 #include "api/transport/goog_cc_factory.h"
 #include "api/transport/network_control.h"
@@ -42,16 +42,16 @@
 void WriteTypedValue(RtcEventLogOutput* out, double value) {
   LogWriteFormat(out, "%.6f", value);
 }
-void WriteTypedValue(RtcEventLogOutput* out, absl::optional<DataRate> value) {
+void WriteTypedValue(RtcEventLogOutput* out, std::optional<DataRate> value) {
   LogWriteFormat(out, "%.0f", value ? value->bytes_per_sec<double>() : NAN);
 }
-void WriteTypedValue(RtcEventLogOutput* out, absl::optional<DataSize> value) {
+void WriteTypedValue(RtcEventLogOutput* out, std::optional<DataSize> value) {
   LogWriteFormat(out, "%.0f", value ? value->bytes<double>() : NAN);
 }
-void WriteTypedValue(RtcEventLogOutput* out, absl::optional<TimeDelta> value) {
+void WriteTypedValue(RtcEventLogOutput* out, std::optional<TimeDelta> value) {
   LogWriteFormat(out, "%.3f", value ? value->seconds<double>() : NAN);
 }
-void WriteTypedValue(RtcEventLogOutput* out, absl::optional<Timestamp> value) {
+void WriteTypedValue(RtcEventLogOutput* out, std::optional<Timestamp> value) {
   LogWriteFormat(out, "%.3f", value ? value->seconds<double>() : NAN);
 }
 
diff --git a/modules/congestion_controller/goog_cc/trendline_estimator.cc b/modules/congestion_controller/goog_cc/trendline_estimator.cc
index 309afaa..4fb11b3 100644
--- a/modules/congestion_controller/goog_cc/trendline_estimator.cc
+++ b/modules/congestion_controller/goog_cc/trendline_estimator.cc
@@ -18,11 +18,11 @@
 #include <cstdio>
 #include <deque>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/network_state_predictor.h"
 #include "api/transport/bandwidth_usage.h"
@@ -57,7 +57,7 @@
   return TrendlineEstimatorSettings::kDefaultTrendlineWindowSize;
 }
 
-absl::optional<double> LinearFitSlope(
+std::optional<double> LinearFitSlope(
     const std::deque<TrendlineEstimator::PacketTiming>& packets) {
   RTC_DCHECK(packets.size() >= 2);
   // Compute the "center of mass".
@@ -79,11 +79,11 @@
     denominator += (x - x_avg) * (x - x_avg);
   }
   if (denominator == 0)
-    return absl::nullopt;
+    return std::nullopt;
   return numerator / denominator;
 }
 
-absl::optional<double> ComputeSlopeCap(
+std::optional<double> ComputeSlopeCap(
     const std::deque<TrendlineEstimator::PacketTiming>& packets,
     const TrendlineEstimatorSettings& settings) {
   RTC_DCHECK(1 <= settings.beginning_packets &&
@@ -104,7 +104,7 @@
       late = packets[i];
   }
   if (late.arrival_time_ms - early.arrival_time_ms < 1) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return (late.raw_delay_ms - early.raw_delay_ms) /
              (late.arrival_time_ms - early.arrival_time_ms) +
@@ -238,7 +238,7 @@
     //   trend < 0     ->  the delay decreases, queues are being emptied
     trend = LinearFitSlope(delay_hist_).value_or(trend);
     if (settings_.enable_cap) {
-      absl::optional<double> cap = ComputeSlopeCap(delay_hist_, settings_);
+      std::optional<double> cap = ComputeSlopeCap(delay_hist_, settings_);
       // We only use the cap to filter out overuse detections, not
       // to detect additional underuses.
       if (trend >= 0 && cap.has_value() && trend > cap.value()) {
diff --git a/modules/congestion_controller/pcc/BUILD.gn b/modules/congestion_controller/pcc/BUILD.gn
index 1ae7523..0af1baf 100644
--- a/modules/congestion_controller/pcc/BUILD.gn
+++ b/modules/congestion_controller/pcc/BUILD.gn
@@ -36,7 +36,6 @@
     "../../../api/units:timestamp",
     "../../../rtc_base:checks",
     "../../../rtc_base:random",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -90,7 +89,6 @@
     ":utility_function",
     "../../../api/transport:network_control",
     "../../../api/units:data_rate",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/modules/congestion_controller/pcc/bitrate_controller.cc b/modules/congestion_controller/pcc/bitrate_controller.cc
index 1a9cddb..3c907f7 100644
--- a/modules/congestion_controller/pcc/bitrate_controller.cc
+++ b/modules/congestion_controller/pcc/bitrate_controller.cc
@@ -107,12 +107,11 @@
   return rate_change;
 }
 
-absl::optional<DataRate>
-PccBitrateController::ComputeRateUpdateForSlowStartMode(
+std::optional<DataRate> PccBitrateController::ComputeRateUpdateForSlowStartMode(
     const PccMonitorInterval& monitor_interval) {
   double utility_value = utility_function_->Compute(monitor_interval);
   if (previous_utility_.has_value() && utility_value <= previous_utility_) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   previous_utility_ = utility_value;
   return monitor_interval.GetTargetSendingRate();
diff --git a/modules/congestion_controller/pcc/bitrate_controller.h b/modules/congestion_controller/pcc/bitrate_controller.h
index fadeea1..a34d429 100644
--- a/modules/congestion_controller/pcc/bitrate_controller.h
+++ b/modules/congestion_controller/pcc/bitrate_controller.h
@@ -14,9 +14,9 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/units/data_rate.h"
 #include "modules/congestion_controller/pcc/monitor_interval.h"
 #include "modules/congestion_controller/pcc/utility_function.h"
@@ -42,7 +42,7 @@
       double dynamic_boundary_increment,
       std::unique_ptr<PccUtilityFunctionInterface> utility_function);
 
-  absl::optional<DataRate> ComputeRateUpdateForSlowStartMode(
+  std::optional<DataRate> ComputeRateUpdateForSlowStartMode(
       const PccMonitorInterval& monitor_interval);
 
   DataRate ComputeRateUpdateForOnlineLearningMode(
@@ -65,7 +65,7 @@
   int64_t step_size_adjustments_number_;
   const double initial_conversion_factor_;
 
-  absl::optional<double> previous_utility_;
+  std::optional<double> previous_utility_;
 };
 
 }  // namespace pcc
diff --git a/modules/congestion_controller/pcc/bitrate_controller_unittest.cc b/modules/congestion_controller/pcc/bitrate_controller_unittest.cc
index 957d99b..b6e1ee5 100644
--- a/modules/congestion_controller/pcc/bitrate_controller_unittest.cc
+++ b/modules/congestion_controller/pcc/bitrate_controller_unittest.cc
@@ -253,7 +253,7 @@
       kTargetSendingRate * 2);
   EXPECT_EQ(
       bitrate_controller.ComputeRateUpdateForSlowStartMode(monitor_block[0]),
-      absl::nullopt);
+      std::nullopt);
 }
 
 TEST(PccBitrateControllerTest, StepSizeIncrease) {
diff --git a/modules/congestion_controller/pcc/pcc_network_controller.cc b/modules/congestion_controller/pcc/pcc_network_controller.cc
index 8653470..1705afb 100644
--- a/modules/congestion_controller/pcc/pcc_network_controller.cc
+++ b/modules/congestion_controller/pcc/pcc_network_controller.cc
@@ -11,8 +11,8 @@
 #include "modules/congestion_controller/pcc/pcc_network_controller.h"
 
 #include <algorithm>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/units/data_size.h"
 #include "rtc_base/checks.h"
 
diff --git a/modules/congestion_controller/rtp/BUILD.gn b/modules/congestion_controller/rtp/BUILD.gn
index 8435ddb..531a026 100644
--- a/modules/congestion_controller/rtp/BUILD.gn
+++ b/modules/congestion_controller/rtp/BUILD.gn
@@ -27,7 +27,6 @@
     "../../../rtc_base:safe_minmax",
     "../../../rtc_base/system:no_unique_address",
     "../../pacing",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 rtc_library("transport_feedback") {
diff --git a/modules/congestion_controller/rtp/control_handler.cc b/modules/congestion_controller/rtp/control_handler.cc
index 357a0f0..93e18a8 100644
--- a/modules/congestion_controller/rtp/control_handler.cc
+++ b/modules/congestion_controller/rtp/control_handler.cc
@@ -38,10 +38,10 @@
   pacer_expected_queue_ms_ = expected_queue_time.ms();
 }
 
-absl::optional<TargetTransferRate> CongestionControlHandler::GetUpdate() {
+std::optional<TargetTransferRate> CongestionControlHandler::GetUpdate() {
   RTC_DCHECK_RUN_ON(&sequenced_checker_);
   if (!last_incoming_.has_value())
-    return absl::nullopt;
+    return std::nullopt;
   TargetTransferRate new_outgoing = *last_incoming_;
   DataRate log_target_rate = new_outgoing.target_rate;
   bool pause_encoding = false;
@@ -67,7 +67,7 @@
     last_reported_ = new_outgoing;
     return new_outgoing;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace webrtc
diff --git a/modules/congestion_controller/rtp/control_handler.h b/modules/congestion_controller/rtp/control_handler.h
index 649d2f9..f492199 100644
--- a/modules/congestion_controller/rtp/control_handler.h
+++ b/modules/congestion_controller/rtp/control_handler.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/sequence_checker.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_size.h"
@@ -38,11 +39,11 @@
   void SetTargetRate(TargetTransferRate new_target_rate);
   void SetNetworkAvailability(bool network_available);
   void SetPacerQueue(TimeDelta expected_queue_time);
-  absl::optional<TargetTransferRate> GetUpdate();
+  std::optional<TargetTransferRate> GetUpdate();
 
  private:
-  absl::optional<TargetTransferRate> last_incoming_;
-  absl::optional<TargetTransferRate> last_reported_;
+  std::optional<TargetTransferRate> last_incoming_;
+  std::optional<TargetTransferRate> last_reported_;
   bool network_available_ = true;
   bool encoder_paused_in_last_report_ = false;
 
diff --git a/modules/congestion_controller/rtp/transport_feedback_adapter.cc b/modules/congestion_controller/rtp/transport_feedback_adapter.cc
index 081e016..2f5e6a7 100644
--- a/modules/congestion_controller/rtp/transport_feedback_adapter.cc
+++ b/modules/congestion_controller/rtp/transport_feedback_adapter.cc
@@ -108,7 +108,7 @@
   history_.insert(std::make_pair(packet.sent.sequence_number, packet));
 }
 
-absl::optional<SentPacket> TransportFeedbackAdapter::ProcessSentPacket(
+std::optional<SentPacket> TransportFeedbackAdapter::ProcessSentPacket(
     const rtc::SentPacket& sent_packet) {
   auto send_time = Timestamp::Millis(sent_packet.send_time_ms);
   // TODO(srte): Only use one way to indicate that packet feedback is used.
@@ -144,16 +144,16 @@
         DataSize::Bytes(sent_packet.info.packet_size_bytes);
     last_untracked_send_time_ = std::max(last_untracked_send_time_, send_time);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<TransportPacketsFeedback>
+std::optional<TransportPacketsFeedback>
 TransportFeedbackAdapter::ProcessTransportFeedback(
     const rtcp::TransportFeedback& feedback,
     Timestamp feedback_receive_time) {
   if (feedback.GetPacketStatusCount() == 0) {
     RTC_LOG(LS_INFO) << "Empty transport feedback packet received.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   TransportPacketsFeedback msg;
@@ -161,7 +161,7 @@
   msg.packet_feedbacks =
       ProcessTransportFeedbackInner(feedback, feedback_receive_time);
   if (msg.packet_feedbacks.empty())
-    return absl::nullopt;
+    return std::nullopt;
   msg.data_in_flight = in_flight_.GetOutstandingData(network_route_);
 
   return msg;
diff --git a/modules/congestion_controller/rtp/transport_feedback_adapter.h b/modules/congestion_controller/rtp/transport_feedback_adapter.h
index 7b1243b..fb48b17 100644
--- a/modules/congestion_controller/rtp/transport_feedback_adapter.h
+++ b/modules/congestion_controller/rtp/transport_feedback_adapter.h
@@ -62,10 +62,10 @@
   void AddPacket(const RtpPacketSendInfo& packet_info,
                  size_t overhead_bytes,
                  Timestamp creation_time);
-  absl::optional<SentPacket> ProcessSentPacket(
+  std::optional<SentPacket> ProcessSentPacket(
       const rtc::SentPacket& sent_packet);
 
-  absl::optional<TransportPacketsFeedback> ProcessTransportFeedback(
+  std::optional<TransportPacketsFeedback> ProcessTransportFeedback(
       const rtcp::TransportFeedback& feedback,
       Timestamp feedback_receive_time);
 
diff --git a/modules/congestion_controller/rtp/transport_feedback_adapter_unittest.cc b/modules/congestion_controller/rtp/transport_feedback_adapter_unittest.cc
index 5aad74c..c6a6b6d 100644
--- a/modules/congestion_controller/rtp/transport_feedback_adapter_unittest.cc
+++ b/modules/congestion_controller/rtp/transport_feedback_adapter_unittest.cc
@@ -385,14 +385,14 @@
   packet_info.pacing_info = packet.sent_packet.pacing_info;
   packet_info.packet_type = RtpPacketMediaType::kVideo;
   adapter_->AddPacket(packet_info, 0u, clock_.CurrentTime());
-  absl::optional<SentPacket> sent_packet = adapter_->ProcessSentPacket(
+  std::optional<SentPacket> sent_packet = adapter_->ProcessSentPacket(
       rtc::SentPacket(packet.sent_packet.sequence_number,
                       packet.sent_packet.send_time.ms(), rtc::PacketInfo()));
   EXPECT_TRUE(sent_packet.has_value());
 
   // Call ProcessSentPacket() again with the same sequence number. This packet
   // has already been marked as sent and the call should be ignored.
-  absl::optional<SentPacket> duplicate_packet = adapter_->ProcessSentPacket(
+  std::optional<SentPacket> duplicate_packet = adapter_->ProcessSentPacket(
       rtc::SentPacket(packet.sent_packet.sequence_number,
                       packet.sent_packet.send_time.ms(), rtc::PacketInfo()));
   EXPECT_FALSE(duplicate_packet.has_value());
diff --git a/modules/desktop_capture/BUILD.gn b/modules/desktop_capture/BUILD.gn
index ddbf3c3..4ea31b9 100644
--- a/modules/desktop_capture/BUILD.gn
+++ b/modules/desktop_capture/BUILD.gn
@@ -280,7 +280,6 @@
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   public_configs = [ ":x11_config" ]
   sources = [
diff --git a/modules/desktop_capture/linux/wayland/egl_dmabuf.cc b/modules/desktop_capture/linux/wayland/egl_dmabuf.cc
index b529077..fff9764 100644
--- a/modules/desktop_capture/linux/wayland/egl_dmabuf.cc
+++ b/modules/desktop_capture/linux/wayland/egl_dmabuf.cc
@@ -19,8 +19,9 @@
 #include <unistd.h>
 #include <xf86drm.h>
 
+#include <optional>
+
 #include "absl/memory/memory.h"
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/sanitizer.h"
@@ -369,7 +370,7 @@
     RTC_LOG(LS_ERROR) << "Failed to obtain default EGL display: "
                       << FormatEGLError(EglGetError()) << "\n"
                       << "Defaulting to using first available render node";
-    absl::optional<std::string> render_node = GetRenderNode();
+    std::optional<std::string> render_node = GetRenderNode();
     if (!render_node) {
       return;
     }
@@ -724,19 +725,19 @@
   return modifiers;
 }
 
-absl::optional<std::string> EglDmaBuf::GetRenderNode() {
+std::optional<std::string> EglDmaBuf::GetRenderNode() {
   int max_devices = drmGetDevices2(0, nullptr, 0);
   if (max_devices <= 0) {
     RTC_LOG(LS_ERROR) << "drmGetDevices2() has not found any devices (errno="
                       << -max_devices << ")";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<drmDevicePtr> devices(max_devices);
   int ret = drmGetDevices2(0, devices.data(), max_devices);
   if (ret < 0) {
     RTC_LOG(LS_ERROR) << "drmGetDevices2() returned an error " << ret;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::string render_node;
diff --git a/modules/desktop_capture/linux/wayland/egl_dmabuf.h b/modules/desktop_capture/linux/wayland/egl_dmabuf.h
index 22a8f5a..61dd2b1 100644
--- a/modules/desktop_capture/linux/wayland/egl_dmabuf.h
+++ b/modules/desktop_capture/linux/wayland/egl_dmabuf.h
@@ -16,10 +16,10 @@
 #include <gbm.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "modules/desktop_capture/desktop_geometry.h"
 
 namespace webrtc {
@@ -66,7 +66,7 @@
   GLuint texture_ = 0;
   EGLStruct egl_;
 
-  absl::optional<std::string> GetRenderNode();
+  std::optional<std::string> GetRenderNode();
 };
 
 }  // namespace webrtc
diff --git a/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc b/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc
index 00b07f3..21f550b 100644
--- a/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc
+++ b/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc
@@ -40,7 +40,7 @@
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   RTC_DCHECK(callback_);
 
-  absl::optional<DesktopVector> mouse_cursor_position =
+  std::optional<DesktopVector> mouse_cursor_position =
       options_.screencast_stream()->CaptureCursorPosition();
   // Invalid cursor or position
   if (!mouse_cursor_position) {
diff --git a/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc b/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc
index 8177cfd..b0bac69 100644
--- a/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc
+++ b/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc
@@ -34,9 +34,9 @@
     return {};
   }
 
-  absl::optional<int> major = rtc::StringToNumber<int>(parsed_version.at(0));
-  absl::optional<int> minor = rtc::StringToNumber<int>(parsed_version.at(1));
-  absl::optional<int> micro = rtc::StringToNumber<int>(parsed_version.at(2));
+  std::optional<int> major = rtc::StringToNumber<int>(parsed_version.at(0));
+  std::optional<int> minor = rtc::StringToNumber<int>(parsed_version.at(1));
+  std::optional<int> micro = rtc::StringToNumber<int>(parsed_version.at(2));
 
   // Return invalid version if we failed to parse it
   if (!major || !minor || !micro) {
diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
index 047ad5a..9aa50e1 100644
--- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
+++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
@@ -1034,12 +1034,12 @@
   return private_->CaptureCursor();
 }
 
-absl::optional<DesktopVector> SharedScreenCastStream::CaptureCursorPosition() {
+std::optional<DesktopVector> SharedScreenCastStream::CaptureCursorPosition() {
   DesktopVector position = private_->CaptureCursorPosition();
 
   // Consider only (x >= 0 and y >= 0) a valid position
   if (position.x() < 0 || position.y() < 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return position;
diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.h b/modules/desktop_capture/linux/wayland/shared_screencast_stream.h
index 1b00e27..1784ad3 100644
--- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.h
+++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.h
@@ -12,8 +12,8 @@
 #define MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_SHARED_SCREENCAST_STREAM_H_
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/ref_counted_base.h"
 #include "api/scoped_refptr.h"
 #include "modules/desktop_capture/desktop_capturer.h"
@@ -81,7 +81,7 @@
 
   // Returns the most recent mouse cursor position. Will not return a value in
   // case we didn't manage to get it from PipeWire buffer.
-  absl::optional<DesktopVector> CaptureCursorPosition();
+  std::optional<DesktopVector> CaptureCursorPosition();
 
   ~SharedScreenCastStream();
 
diff --git a/modules/desktop_capture/win/wgc_capture_source.h b/modules/desktop_capture/win/wgc_capture_source.h
index 57b105c..f155cdd 100644
--- a/modules/desktop_capture/win/wgc_capture_source.h
+++ b/modules/desktop_capture/win/wgc_capture_source.h
@@ -16,8 +16,8 @@
 #include <wrl/client.h>
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "modules/desktop_capture/desktop_capturer.h"
 #include "modules/desktop_capture/desktop_geometry.h"
 
@@ -138,7 +138,7 @@
   // device index as it's SourceId. However, WGC requires we use an HMONITOR to
   // describe which screen to capture. So, we internally convert the supplied
   // device index into an HMONITOR when `IsCapturable()` is called.
-  absl::optional<HMONITOR> hmonitor_;
+  std::optional<HMONITOR> hmonitor_;
 };
 
 }  // namespace webrtc
diff --git a/modules/include/module_common_types_public.h b/modules/include/module_common_types_public.h
index 5a6f634..289b5d0 100644
--- a/modules/include/module_common_types_public.h
+++ b/modules/include/module_common_types_public.h
@@ -12,8 +12,7 @@
 #define MODULES_INCLUDE_MODULE_COMMON_TYPES_PUBLIC_H_
 
 #include <limits>
-
-#include "absl/types/optional.h"
+#include <optional>
 
 namespace webrtc {
 
diff --git a/modules/pacing/BUILD.gn b/modules/pacing/BUILD.gn
index b560557..7878676 100644
--- a/modules/pacing/BUILD.gn
+++ b/modules/pacing/BUILD.gn
@@ -64,7 +64,6 @@
     "//third_party/abseil-cpp/absl/container:inlined_vector",
     "//third_party/abseil-cpp/absl/functional:any_invocable",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/modules/pacing/bitrate_prober.cc b/modules/pacing/bitrate_prober.cc
index 29b4f4c..5b6142a 100644
--- a/modules/pacing/bitrate_prober.cc
+++ b/modules/pacing/bitrate_prober.cc
@@ -139,9 +139,9 @@
   return next_probe_time_;
 }
 
-absl::optional<PacedPacketInfo> BitrateProber::CurrentCluster(Timestamp now) {
+std::optional<PacedPacketInfo> BitrateProber::CurrentCluster(Timestamp now) {
   if (clusters_.empty() || probing_state_ != ProbingState::kActive) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (next_probe_time_.IsFinite() &&
@@ -153,7 +153,7 @@
     clusters_.pop();
     if (clusters_.empty()) {
       probing_state_ = ProbingState::kInactive;
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
diff --git a/modules/pacing/bitrate_prober.h b/modules/pacing/bitrate_prober.h
index 149d24f..7ceb129 100644
--- a/modules/pacing/bitrate_prober.h
+++ b/modules/pacing/bitrate_prober.h
@@ -72,7 +72,7 @@
   Timestamp NextProbeTime(Timestamp now) const;
 
   // Information about the current probing cluster.
-  absl::optional<PacedPacketInfo> CurrentCluster(Timestamp now);
+  std::optional<PacedPacketInfo> CurrentCluster(Timestamp now);
 
   // Returns the minimum number of bytes that the prober recommends for
   // the next probe, or zero if not probing. A probe can consist of multiple
diff --git a/modules/pacing/pacing_controller.cc b/modules/pacing/pacing_controller.cc
index a45c5d8..5999fa5 100644
--- a/modules/pacing/pacing_controller.cc
+++ b/modules/pacing/pacing_controller.cc
@@ -204,7 +204,7 @@
     // queue). Flush any pending packets currently in the queue for that stream
     // in order to get the new keyframe out as quickly as possible.
     packet_queue_.RemovePacketsForSsrc(packet->Ssrc());
-    absl::optional<uint32_t> rtx_ssrc =
+    std::optional<uint32_t> rtx_ssrc =
         packet_sender_->GetRtxSsrcForMedia(packet->Ssrc());
     if (rtx_ssrc) {
       packet_queue_.RemovePacketsForSsrc(*rtx_ssrc);
@@ -283,7 +283,7 @@
   return std::max(media_debt_, padding_debt_);
 }
 
-absl::optional<Timestamp> PacingController::FirstSentPacketTime() const {
+std::optional<Timestamp> PacingController::FirstSentPacketTime() const {
   return first_sent_packet_time_;
 }
 
diff --git a/modules/pacing/pacing_controller.h b/modules/pacing/pacing_controller.h
index 9d78912..db70ec9 100644
--- a/modules/pacing/pacing_controller.h
+++ b/modules/pacing/pacing_controller.h
@@ -17,9 +17,9 @@
 #include <array>
 #include <atomic>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/function_view.h"
 #include "api/rtp_packet_sender.h"
@@ -62,8 +62,8 @@
     virtual void OnAbortedRetransmissions(
         uint32_t ssrc,
         rtc::ArrayView<const uint16_t> sequence_numbers) {}
-    virtual absl::optional<uint32_t> GetRtxSsrcForMedia(uint32_t ssrc) const {
-      return absl::nullopt;
+    virtual std::optional<uint32_t> GetRtxSsrcForMedia(uint32_t ssrc) const {
+      return std::nullopt;
     }
   };
 
@@ -179,7 +179,7 @@
   DataSize CurrentBufferLevel() const;
 
   // Returns the time when the first packet was sent.
-  absl::optional<Timestamp> FirstSentPacketTime() const;
+  std::optional<Timestamp> FirstSentPacketTime() const;
 
   // Returns the number of milliseconds it will take to send the current
   // packets in the queue, given the current size and bitrate, ignoring prio.
@@ -275,7 +275,7 @@
 
   Timestamp last_process_time_;
   Timestamp last_send_time_;
-  absl::optional<Timestamp> first_sent_packet_time_;
+  std::optional<Timestamp> first_sent_packet_time_;
   bool seen_first_packet_;
 
   PrioritizedPacketQueue packet_queue_;
diff --git a/modules/pacing/pacing_controller_unittest.cc b/modules/pacing/pacing_controller_unittest.cc
index 8a37292..01430ff 100644
--- a/modules/pacing/pacing_controller_unittest.cc
+++ b/modules/pacing/pacing_controller_unittest.cc
@@ -134,7 +134,7 @@
               OnAbortedRetransmissions,
               (uint32_t, rtc::ArrayView<const uint16_t>),
               (override));
-  MOCK_METHOD(absl::optional<uint32_t>,
+  MOCK_METHOD(std::optional<uint32_t>,
               GetRtxSsrcForMedia,
               (uint32_t),
               (const, override));
@@ -162,7 +162,7 @@
               OnAbortedRetransmissions,
               (uint32_t, rtc::ArrayView<const uint16_t>),
               (override));
-  MOCK_METHOD(absl::optional<uint32_t>,
+  MOCK_METHOD(std::optional<uint32_t>,
               GetRtxSsrcForMedia,
               (uint32_t),
               (const, override));
@@ -200,8 +200,8 @@
 
   void OnAbortedRetransmissions(uint32_t,
                                 rtc::ArrayView<const uint16_t>) override {}
-  absl::optional<uint32_t> GetRtxSsrcForMedia(uint32_t) const override {
-    return absl::nullopt;
+  std::optional<uint32_t> GetRtxSsrcForMedia(uint32_t) const override {
+    return std::nullopt;
   }
 
   void OnBatchComplete() override {}
@@ -261,8 +261,8 @@
 
   void OnAbortedRetransmissions(uint32_t,
                                 rtc::ArrayView<const uint16_t>) override {}
-  absl::optional<uint32_t> GetRtxSsrcForMedia(uint32_t) const override {
-    return absl::nullopt;
+  std::optional<uint32_t> GetRtxSsrcForMedia(uint32_t) const override {
+    return std::nullopt;
   }
   void OnBatchComplete() override {}
 
diff --git a/modules/pacing/packet_router.cc b/modules/pacing/packet_router.cc
index 5124e94..8f4d492 100644
--- a/modules/pacing/packet_router.cc
+++ b/modules/pacing/packet_router.cc
@@ -14,10 +14,10 @@
 #include <cstdint>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "absl/functional/any_invocable.h"
-#include "absl/types/optional.h"
 #include "api/transport/network_types.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/rtcp_packet.h"
@@ -49,10 +49,10 @@
   RTC_DCHECK_RUN_ON(&thread_checker_);
 
   AddSendRtpModuleToMap(rtp_module, rtp_module->SSRC());
-  if (absl::optional<uint32_t> rtx_ssrc = rtp_module->RtxSsrc()) {
+  if (std::optional<uint32_t> rtx_ssrc = rtp_module->RtxSsrc()) {
     AddSendRtpModuleToMap(rtp_module, *rtx_ssrc);
   }
-  if (absl::optional<uint32_t> flexfec_ssrc = rtp_module->FlexfecSsrc()) {
+  if (std::optional<uint32_t> flexfec_ssrc = rtp_module->FlexfecSsrc()) {
     AddSendRtpModuleToMap(rtp_module, *flexfec_ssrc);
   }
 
@@ -119,10 +119,10 @@
   MaybeRemoveRembModuleCandidate(rtp_module, /* media_sender = */ true);
 
   RemoveSendRtpModuleFromMap(rtp_module->SSRC());
-  if (absl::optional<uint32_t> rtx_ssrc = rtp_module->RtxSsrc()) {
+  if (std::optional<uint32_t> rtx_ssrc = rtp_module->RtxSsrc()) {
     RemoveSendRtpModuleFromMap(*rtx_ssrc);
   }
-  if (absl::optional<uint32_t> flexfec_ssrc = rtp_module->FlexfecSsrc()) {
+  if (std::optional<uint32_t> flexfec_ssrc = rtp_module->FlexfecSsrc()) {
     RemoveSendRtpModuleFromMap(*flexfec_ssrc);
   }
 
@@ -275,7 +275,7 @@
   }
 }
 
-absl::optional<uint32_t> PacketRouter::GetRtxSsrcForMedia(uint32_t ssrc) const {
+std::optional<uint32_t> PacketRouter::GetRtxSsrcForMedia(uint32_t ssrc) const {
   RTC_DCHECK_RUN_ON(&thread_checker_);
   auto it = send_modules_map_.find(ssrc);
   if (it != send_modules_map_.end() && it->second->SSRC() == ssrc) {
@@ -283,7 +283,7 @@
     // media SSRC for that RTP module.
     return it->second->RtxSsrc();
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void PacketRouter::SendRemb(int64_t bitrate_bps, std::vector<uint32_t> ssrcs) {
diff --git a/modules/pacing/packet_router.h b/modules/pacing/packet_router.h
index ae10637..1422645 100644
--- a/modules/pacing/packet_router.h
+++ b/modules/pacing/packet_router.h
@@ -71,7 +71,7 @@
   void OnAbortedRetransmissions(
       uint32_t ssrc,
       rtc::ArrayView<const uint16_t> sequence_numbers) override;
-  absl::optional<uint32_t> GetRtxSsrcForMedia(uint32_t ssrc) const override;
+  std::optional<uint32_t> GetRtxSsrcForMedia(uint32_t ssrc) const override;
   void OnBatchComplete() override;
 
   // Send REMB feedback.
diff --git a/modules/pacing/packet_router_unittest.cc b/modules/pacing/packet_router_unittest.cc
index fdd45cc..20e9622 100644
--- a/modules/pacing/packet_router_unittest.cc
+++ b/modules/pacing/packet_router_unittest.cc
@@ -420,7 +420,7 @@
                     &RtpPacketToSend::HasExtension<TransportSequenceNumber>,
                     false)),
                 Pointee(Property(&RtpPacketToSend::transport_sequence_number,
-                                 absl::nullopt))),
+                                 std::nullopt))),
           _));
   packet_router_.SendPacket(std::move(packet), PacedPacketInfo());
   packet_router_.OnBatchComplete();
@@ -517,9 +517,9 @@
   packet_router_.AddSendRtpModule(&rtp_2, false);
 
   EXPECT_EQ(packet_router_.GetRtxSsrcForMedia(kSsrc1), kRtxSsrc1);
-  EXPECT_EQ(packet_router_.GetRtxSsrcForMedia(kRtxSsrc1), absl::nullopt);
-  EXPECT_EQ(packet_router_.GetRtxSsrcForMedia(kSsrc2), absl::nullopt);
-  EXPECT_EQ(packet_router_.GetRtxSsrcForMedia(kInvalidSsrc), absl::nullopt);
+  EXPECT_EQ(packet_router_.GetRtxSsrcForMedia(kRtxSsrc1), std::nullopt);
+  EXPECT_EQ(packet_router_.GetRtxSsrcForMedia(kSsrc2), std::nullopt);
+  EXPECT_EQ(packet_router_.GetRtxSsrcForMedia(kInvalidSsrc), std::nullopt);
 
   packet_router_.RemoveSendRtpModule(&rtp_1);
   packet_router_.RemoveSendRtpModule(&rtp_2);
diff --git a/modules/pacing/prioritized_packet_queue.cc b/modules/pacing/prioritized_packet_queue.cc
index 2d0d829..fa2ad7d 100644
--- a/modules/pacing/prioritized_packet_queue.cc
+++ b/modules/pacing/prioritized_packet_queue.cc
@@ -12,10 +12,10 @@
 
 #include <algorithm>
 #include <array>
+#include <optional>
 #include <utility>
 
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@@ -30,7 +30,7 @@
 
 int GetPriorityForType(
     RtpPacketMediaType type,
-    absl::optional<RtpPacketToSend::OriginalType> original_type) {
+    std::optional<RtpPacketToSend::OriginalType> original_type) {
   // Lower number takes priority over higher.
   switch (type) {
     case RtpPacketMediaType::kAudio:
@@ -69,7 +69,7 @@
   ttl_per_prio[GetPriorityForType(RtpPacketMediaType::kRetransmission,
                                   RtpPacketToSend::OriginalType::kVideo)] =
       packet_queue_ttl.video_retransmission;
-  ttl_per_prio[GetPriorityForType(RtpPacketMediaType::kVideo, absl::nullopt)] =
+  ttl_per_prio[GetPriorityForType(RtpPacketMediaType::kVideo, std::nullopt)] =
       packet_queue_ttl.video;
   return ttl_per_prio;
 }
@@ -170,7 +170,7 @@
   int prio_level =
       GetPriorityForType(packet_type, prioritize_audio_retransmission_
                                           ? packet->original_packet_type()
-                                          : absl::nullopt);
+                                          : std::nullopt);
   PurgeOldPacketsAtPriorityLevel(prio_level, enqueue_time);
   RTC_DCHECK_GE(prio_level, 0);
   RTC_DCHECK_LT(prio_level, kNumPriorityLevels);
@@ -253,7 +253,7 @@
 Timestamp PrioritizedPacketQueue::LeadingPacketEnqueueTime(
     RtpPacketMediaType type) const {
   RTC_DCHECK(type != RtpPacketMediaType::kRetransmission);
-  const int priority_level = GetPriorityForType(type, absl::nullopt);
+  const int priority_level = GetPriorityForType(type, std::nullopt);
   if (streams_by_prio_[priority_level].empty()) {
     return Timestamp::MinusInfinity();
   }
@@ -265,7 +265,7 @@
     const {
   if (!prioritize_audio_retransmission_) {
     const int priority_level =
-        GetPriorityForType(RtpPacketMediaType::kRetransmission, absl::nullopt);
+        GetPriorityForType(RtpPacketMediaType::kRetransmission, std::nullopt);
     if (streams_by_prio_[priority_level].empty()) {
       return Timestamp::PlusInfinity();
     }
diff --git a/modules/pacing/rtp_packet_pacer.h b/modules/pacing/rtp_packet_pacer.h
index 2caa665..f388c07 100644
--- a/modules/pacing/rtp_packet_pacer.h
+++ b/modules/pacing/rtp_packet_pacer.h
@@ -13,9 +13,9 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
 #include "api/units/data_size.h"
@@ -49,7 +49,7 @@
   virtual DataSize QueueSizeData() const = 0;
 
   // Returns the time when the first packet was sent.
-  virtual absl::optional<Timestamp> FirstSentPacketTime() const = 0;
+  virtual std::optional<Timestamp> FirstSentPacketTime() const = 0;
 
   // Returns the expected number of milliseconds it will take to send the
   // current packets in the queue, given the current size and bitrate, ignoring
diff --git a/modules/pacing/task_queue_paced_sender.cc b/modules/pacing/task_queue_paced_sender.cc
index 5559153..ca89770 100644
--- a/modules/pacing/task_queue_paced_sender.cc
+++ b/modules/pacing/task_queue_paced_sender.cc
@@ -160,7 +160,7 @@
   return GetStats().queue_size;
 }
 
-absl::optional<Timestamp> TaskQueuePacedSender::FirstSentPacketTime() const {
+std::optional<Timestamp> TaskQueuePacedSender::FirstSentPacketTime() const {
   return GetStats().first_sent_packet_time;
 }
 
diff --git a/modules/pacing/task_queue_paced_sender.h b/modules/pacing/task_queue_paced_sender.h
index a1d2474..be2bc84 100644
--- a/modules/pacing/task_queue_paced_sender.h
+++ b/modules/pacing/task_queue_paced_sender.h
@@ -15,9 +15,9 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/sequence_checker.h"
 #include "api/task_queue/pending_task_safety_flag.h"
@@ -107,7 +107,7 @@
   DataSize QueueSizeData() const override;
 
   // Returns the time when the first packet was sent;
-  absl::optional<Timestamp> FirstSentPacketTime() const override;
+  std::optional<Timestamp> FirstSentPacketTime() const override;
 
   // Returns the number of milliseconds it will take to send the current
   // packets in the queue, given the current size and bitrate, ignoring prio.
@@ -127,7 +127,7 @@
     Timestamp oldest_packet_enqueue_time;
     DataSize queue_size;
     TimeDelta expected_queue_time;
-    absl::optional<Timestamp> first_sent_packet_time;
+    std::optional<Timestamp> first_sent_packet_time;
   };
   void OnStatsUpdated(const Stats& stats);
 
diff --git a/modules/remote_bitrate_estimator/BUILD.gn b/modules/remote_bitrate_estimator/BUILD.gn
index 2cb8700..453ae66 100644
--- a/modules/remote_bitrate_estimator/BUILD.gn
+++ b/modules/remote_bitrate_estimator/BUILD.gn
@@ -51,7 +51,6 @@
     "../rtp_rtcp:rtp_rtcp_format",
     "//third_party/abseil-cpp/absl/base:nullability",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -89,7 +88,6 @@
     "../../rtc_base/synchronization:mutex",
     "../../system_wrappers",
     "../rtp_rtcp:rtp_rtcp_format",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -182,7 +180,6 @@
       "../../test:test_support",
       "../pacing",
       "../rtp_rtcp:rtp_rtcp_format",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control.cc b/modules/remote_bitrate_estimator/aimd_rate_control.cc
index 576d307..26ff73c 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control.cc
+++ b/modules/remote_bitrate_estimator/aimd_rate_control.cc
@@ -183,7 +183,7 @@
 }
 
 void AimdRateControl::SetNetworkStateEstimate(
-    const absl::optional<NetworkStateEstimate>& estimate) {
+    const std::optional<NetworkStateEstimate>& estimate) {
   network_estimate_ = estimate;
 }
 
@@ -221,7 +221,7 @@
 
 void AimdRateControl::ChangeBitrate(const RateControlInput& input,
                                     Timestamp at_time) {
-  absl::optional<DataRate> new_bitrate;
+  std::optional<DataRate> new_bitrate;
   DataRate estimated_throughput =
       input.estimated_throughput.value_or(latest_estimated_throughput_);
   if (input.estimated_throughput)
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control.h b/modules/remote_bitrate_estimator/aimd_rate_control.h
index b7a8ef6..55f1e37 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control.h
+++ b/modules/remote_bitrate_estimator/aimd_rate_control.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/field_trials_view.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
@@ -57,7 +58,7 @@
   void SetInApplicationLimitedRegion(bool in_alr);
   void SetEstimate(DataRate bitrate, Timestamp at_time);
   void SetNetworkStateEstimate(
-      const absl::optional<NetworkStateEstimate>& estimate);
+      const std::optional<NetworkStateEstimate>& estimate);
 
   // Returns the increase rate when used bandwidth is near the link capacity.
   double GetNearMaxIncreaseRateBpsPerSecond() const;
@@ -90,7 +91,7 @@
   DataRate current_bitrate_;
   DataRate latest_estimated_throughput_;
   LinkCapacityEstimator link_capacity_;
-  absl::optional<NetworkStateEstimate> network_estimate_;
+  std::optional<NetworkStateEstimate> network_estimate_;
   RateControlState rate_control_state_;
   Timestamp time_last_bitrate_change_;
   Timestamp time_last_bitrate_decrease_;
@@ -107,7 +108,7 @@
   FieldTrialFlag disable_estimate_bounded_increase_{"Disabled"};
   FieldTrialParameter<bool> use_current_estimate_as_min_upper_bound_{"c_upper",
                                                                      true};
-  absl::optional<DataRate> last_decrease_;
+  std::optional<DataRate> last_decrease_;
 };
 }  // namespace webrtc
 
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc b/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
index 401e87e..6c3c985 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
+++ b/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
@@ -165,7 +165,7 @@
   now += (kInitializationTime + TimeDelta::Millis(1));
   aimd_rate_control.Update({BandwidthUsage::kBwNormal, kInitialBitrate}, now);
   for (int i = 0; i < 100; ++i) {
-    aimd_rate_control.Update({BandwidthUsage::kBwNormal, absl::nullopt}, now);
+    aimd_rate_control.Update({BandwidthUsage::kBwNormal, std::nullopt}, now);
     now += TimeDelta::Millis(100);
   }
   EXPECT_LE(aimd_rate_control.LatestEstimate(),
@@ -187,7 +187,7 @@
   ASSERT_EQ(aimd_rate_control.LatestEstimate(), kInitialBitrate);
 
   for (int i = 0; i < 100; ++i) {
-    aimd_rate_control.Update({BandwidthUsage::kBwNormal, absl::nullopt}, now);
+    aimd_rate_control.Update({BandwidthUsage::kBwNormal, std::nullopt}, now);
     now += TimeDelta::Millis(100);
   }
   EXPECT_EQ(aimd_rate_control.LatestEstimate(), kInitialBitrate);
@@ -287,7 +287,7 @@
   aimd_rate_control.SetInApplicationLimitedRegion(false);
   aimd_rate_control.Update({BandwidthUsage::kBwNormal, kInitialBitrate}, now);
   for (int i = 0; i < 100; ++i) {
-    aimd_rate_control.Update({BandwidthUsage::kBwNormal, absl::nullopt}, now);
+    aimd_rate_control.Update({BandwidthUsage::kBwNormal, std::nullopt}, now);
     now += TimeDelta::Millis(100);
   }
   EXPECT_GT(aimd_rate_control.LatestEstimate(), kInitialBitrate);
@@ -306,7 +306,7 @@
   aimd_rate_control.SetNetworkStateEstimate(network_estimate);
 
   for (int i = 0; i < 100; ++i) {
-    aimd_rate_control.Update({BandwidthUsage::kBwNormal, absl::nullopt}, now);
+    aimd_rate_control.Update({BandwidthUsage::kBwNormal, std::nullopt}, now);
     now += TimeDelta::Millis(100);
   }
   EXPECT_GT(aimd_rate_control.LatestEstimate(),
diff --git a/modules/remote_bitrate_estimator/bwe_defines.cc b/modules/remote_bitrate_estimator/bwe_defines.cc
index db92f46..ca41732 100644
--- a/modules/remote_bitrate_estimator/bwe_defines.cc
+++ b/modules/remote_bitrate_estimator/bwe_defines.cc
@@ -16,7 +16,7 @@
 
 RateControlInput::RateControlInput(
     BandwidthUsage bw_state,
-    const absl::optional<DataRate>& estimated_throughput)
+    const std::optional<DataRate>& estimated_throughput)
     : bw_state(bw_state), estimated_throughput(estimated_throughput) {}
 
 RateControlInput::~RateControlInput() = default;
diff --git a/modules/remote_bitrate_estimator/congestion_control_feedback_generator.cc b/modules/remote_bitrate_estimator/congestion_control_feedback_generator.cc
index aba3586..7c5c648 100644
--- a/modules/remote_bitrate_estimator/congestion_control_feedback_generator.cc
+++ b/modules/remote_bitrate_estimator/congestion_control_feedback_generator.cc
@@ -103,8 +103,8 @@
   std::vector<rtcp::CongestionControlFeedback::PacketInfo> rtcp_packet_info;
   rtcp_packet_info.reserve(packets_.size());
 
-  absl::optional<uint32_t> previous_ssrc;
-  absl::optional<int64_t> previous_seq_no;
+  std::optional<uint32_t> previous_ssrc;
+  std::optional<int64_t> previous_seq_no;
   for (const PacketInfo packet : packets_) {
     if (previous_ssrc == packet.ssrc &&
         previous_seq_no == packet.unwrapped_sequence_number) {
diff --git a/modules/remote_bitrate_estimator/include/bwe_defines.h b/modules/remote_bitrate_estimator/include/bwe_defines.h
index 02646ef..e3f4e8c 100644
--- a/modules/remote_bitrate_estimator/include/bwe_defines.h
+++ b/modules/remote_bitrate_estimator/include/bwe_defines.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/transport/bandwidth_usage.h"
 #include "api/units/data_rate.h"
 #include "api/units/time_delta.h"
@@ -36,11 +37,11 @@
 
 struct RateControlInput {
   RateControlInput(BandwidthUsage bw_state,
-                   const absl::optional<DataRate>& estimated_throughput);
+                   const std::optional<DataRate>& estimated_throughput);
   ~RateControlInput();
 
   BandwidthUsage bw_state;
-  absl::optional<DataRate> estimated_throughput;
+  std::optional<DataRate> estimated_throughput;
 };
 }  // namespace webrtc
 
diff --git a/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc b/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc
index 278ad9d..af2cd5b 100644
--- a/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc
+++ b/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc
@@ -229,7 +229,7 @@
   // here.
 
   // Check if incoming bitrate estimate is valid, and if it needs to be reset.
-  absl::optional<DataRate> incoming_bitrate =
+  std::optional<DataRate> incoming_bitrate =
       incoming_bitrate_.Rate(arrival_time);
   if (incoming_bitrate) {
     incoming_bitrate_initialized_ = true;
@@ -302,7 +302,7 @@
             remote_rate_.GetFeedbackInterval().ms()) {
       update_estimate = true;
     } else if (detector_.State() == BandwidthUsage::kBwOverusing) {
-      absl::optional<DataRate> incoming_rate =
+      std::optional<DataRate> incoming_rate =
           incoming_bitrate_.Rate(arrival_time);
       if (incoming_rate.has_value() &&
           remote_rate_.TimeToReduceFurther(now, *incoming_rate)) {
diff --git a/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc b/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc
index 9db92ac..60c0852 100644
--- a/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc
+++ b/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc
@@ -11,10 +11,10 @@
 #include "modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
 
 #include <cstdint>
+#include <optional>
 #include <utility>
 
 #include "absl/base/nullability.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "modules/remote_bitrate_estimator/aimd_rate_control.h"
 #include "modules/remote_bitrate_estimator/include/bwe_defines.h"
@@ -58,7 +58,7 @@
 
 void RemoteBitrateEstimatorSingleStream::IncomingPacket(
     const RtpPacketReceived& rtp_packet) {
-  absl::optional<int32_t> transmission_time_offset =
+  std::optional<int32_t> transmission_time_offset =
       rtp_packet.GetExtension<TransmissionOffset>();
   if (!uma_recorded_) {
     BweNames type = transmission_time_offset.has_value()
@@ -75,7 +75,7 @@
   estimator.last_packet_time = now;
 
   // Check if incoming bitrate estimate is valid, and if it needs to be reset.
-  absl::optional<DataRate> incoming_bitrate = incoming_bitrate_.Rate(now);
+  std::optional<DataRate> incoming_bitrate = incoming_bitrate_.Rate(now);
   if (incoming_bitrate) {
     last_valid_incoming_bitrate_ = *incoming_bitrate;
   } else if (last_valid_incoming_bitrate_ > DataRate::Zero()) {
@@ -103,7 +103,7 @@
                               estimator.estimator.num_of_deltas(), now_ms);
   }
   if (estimator.detector.State() == BandwidthUsage::kBwOverusing) {
-    absl::optional<DataRate> incoming_bitrate = incoming_bitrate_.Rate(now);
+    std::optional<DataRate> incoming_bitrate = incoming_bitrate_.Rate(now);
     if (incoming_bitrate.has_value() &&
         (prior_state != BandwidthUsage::kBwOverusing ||
          remote_rate_.TimeToReduceFurther(now, *incoming_bitrate))) {
diff --git a/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h b/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h
index 16a0097..1efd807 100644
--- a/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h
+++ b/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h
@@ -15,10 +15,10 @@
 #include <stdint.h>
 
 #include <map>
+#include <optional>
 #include <vector>
 
 #include "absl/base/nullability.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/units/data_rate.h"
 #include "api/units/time_delta.h"
@@ -73,7 +73,7 @@
   BitrateTracker incoming_bitrate_;
   DataRate last_valid_incoming_bitrate_;
   AimdRateControl remote_rate_;
-  absl::optional<Timestamp> last_process_time_;
+  std::optional<Timestamp> last_process_time_;
   TimeDelta process_interval_;
   bool uma_recorded_;
 };
diff --git a/modules/remote_bitrate_estimator/transport_sequence_number_feedback_generator.cc b/modules/remote_bitrate_estimator/transport_sequence_number_feedback_generator.cc
index b764013..4433b35 100644
--- a/modules/remote_bitrate_estimator/transport_sequence_number_feedback_generator.cc
+++ b/modules/remote_bitrate_estimator/transport_sequence_number_feedback_generator.cc
@@ -14,9 +14,9 @@
 #include <cstdint>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/units/data_size.h"
 #include "api/units/time_delta.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/remote_estimate.h"
@@ -94,7 +94,7 @@
   }
 
   uint16_t seqnum = 0;
-  absl::optional<FeedbackRequest> feedback_request;
+  std::optional<FeedbackRequest> feedback_request;
   if (!packet.GetExtension<TransportSequenceNumber>(&seqnum) &&
       !packet.GetExtension<TransportSequenceNumberV2>(&seqnum,
                                                       &feedback_request)) {
@@ -139,7 +139,7 @@
     SendFeedbackOnRequest(seq, *feedback_request);
   }
 
-  absl::optional<uint32_t> absolute_send_time_24bits =
+  std::optional<uint32_t> absolute_send_time_24bits =
       packet.GetExtension<AbsoluteSendTime>();
   if (network_state_estimator_ && absolute_send_time_24bits.has_value()) {
     PacketResult packet_result;
@@ -217,7 +217,7 @@
 
   std::unique_ptr<rtcp::RemoteEstimate> remote_estimate;
   if (network_state_estimator_) {
-    absl::optional<NetworkStateEstimate> state_estimate =
+    std::optional<NetworkStateEstimate> state_estimate =
         network_state_estimator_->GetCurrentEstimate();
     if (state_estimate) {
       remote_estimate = std::make_unique<rtcp::RemoteEstimate>();
diff --git a/modules/remote_bitrate_estimator/transport_sequence_number_feedback_generator.h b/modules/remote_bitrate_estimator/transport_sequence_number_feedback_generator.h
index 4c2fb31..be9412d 100644
--- a/modules/remote_bitrate_estimator/transport_sequence_number_feedback_generator.h
+++ b/modules/remote_bitrate_estimator/transport_sequence_number_feedback_generator.h
@@ -14,9 +14,9 @@
 #include <deque>
 #include <functional>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/rtp_headers.h"
 #include "api/transport/network_control.h"
@@ -95,8 +95,8 @@
   DataSize packet_overhead_ RTC_GUARDED_BY(&lock_);
 
   // The next sequence number that should be the start sequence number during
-  // periodic reporting. Will be absl::nullopt before the first seen packet.
-  absl::optional<int64_t> periodic_window_start_seq_ RTC_GUARDED_BY(&lock_);
+  // periodic reporting. Will be std::nullopt before the first seen packet.
+  std::optional<int64_t> periodic_window_start_seq_ RTC_GUARDED_BY(&lock_);
 
   // Packet arrival times, by sequence number.
   PacketArrivalTimeMap packet_arrival_times_ RTC_GUARDED_BY(&lock_);
diff --git a/modules/remote_bitrate_estimator/transport_sequence_number_feedback_generator_unittest.cc b/modules/remote_bitrate_estimator/transport_sequence_number_feedback_generator_unittest.cc
index bc1ce81..5d628d1 100644
--- a/modules/remote_bitrate_estimator/transport_sequence_number_feedback_generator_unittest.cc
+++ b/modules/remote_bitrate_estimator/transport_sequence_number_feedback_generator_unittest.cc
@@ -12,9 +12,9 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/transport/test/mock_network_control.h"
 #include "api/units/data_rate.h"
 #include "api/units/data_size.h"
@@ -86,7 +86,7 @@
  protected:
   void IncomingPacket(uint16_t seq,
                       Timestamp arrival_time,
-                      absl::optional<uint32_t> abs_send_time = absl::nullopt) {
+                      std::optional<uint32_t> abs_send_time = std::nullopt) {
     RtpHeaderExtensionMap map;
     map.Register<TransportSequenceNumber>(1);
     map.Register<AbsoluteSendTime>(2);
@@ -102,7 +102,7 @@
   void IncomingPacketV2(
       uint16_t seq,
       Timestamp arrival_time,
-      absl::optional<FeedbackRequest> feedback_request = absl::nullopt) {
+      std::optional<FeedbackRequest> feedback_request = std::nullopt) {
     RtpHeaderExtensionMap map;
     map.Register<TransportSequenceNumberV2>(1);
     RtpPacketReceived packet(&map, arrival_time);
diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn
index ec05361..d0e6567 100644
--- a/modules/rtp_rtcp/BUILD.gn
+++ b/modules/rtp_rtcp/BUILD.gn
@@ -146,7 +146,6 @@
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -357,7 +356,6 @@
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -393,7 +391,6 @@
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -449,7 +446,6 @@
     "//third_party/abseil-cpp/absl/cleanup",
     "//third_party/abseil-cpp/absl/functional:any_invocable",
     "//third_party/abseil-cpp/absl/memory",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -468,7 +464,6 @@
     "../../api/video:video_rtp_headers",
     "../../modules/video_coding:codec_globals_headers",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -517,7 +512,6 @@
     "../../rtc_base:checks",
     "../../test:test_support",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -738,7 +732,6 @@
       "//third_party/abseil-cpp/absl/base:core_headers",
       "//third_party/abseil-cpp/absl/memory",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -767,7 +760,6 @@
       ":rtp_rtcp_format",
       "../../common_video:common_video",
       "../../test:test_support",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
diff --git a/modules/rtp_rtcp/include/flexfec_sender.h b/modules/rtp_rtcp/include/flexfec_sender.h
index 65ac0e9..83034cc 100644
--- a/modules/rtp_rtcp/include/flexfec_sender.h
+++ b/modules/rtp_rtcp/include/flexfec_sender.h
@@ -51,7 +51,7 @@
   FecType GetFecType() const override {
     return VideoFecGenerator::FecType::kFlexFec;
   }
-  absl::optional<uint32_t> FecSsrc() override { return ssrc_; }
+  std::optional<uint32_t> FecSsrc() override { return ssrc_; }
 
   // Sets the FEC rate, max frames sent before FEC packets are sent,
   // and what type of generator matrices are used.
@@ -72,7 +72,7 @@
   DataRate CurrentFecRate() const override;
 
   // Only called on the VideoSendStream queue, after operation has shut down.
-  absl::optional<RtpState> GetRtpState() override;
+  std::optional<RtpState> GetRtpState() override;
 
  private:
   // Utility.
diff --git a/modules/rtp_rtcp/include/receive_statistics.h b/modules/rtp_rtcp/include/receive_statistics.h
index 827fd3a..5faea15 100644
--- a/modules/rtp_rtcp/include/receive_statistics.h
+++ b/modules/rtp_rtcp/include/receive_statistics.h
@@ -13,9 +13,9 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "call/rtp_packet_sink_interface.h"
 #include "modules/rtp_rtcp/include/rtcp_statistics.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@@ -41,7 +41,7 @@
   virtual RtpReceiveStats GetStats() const = 0;
 
   // Returns average over the stream life time.
-  virtual absl::optional<int> GetFractionLostInPercent() const = 0;
+  virtual std::optional<int> GetFractionLostInPercent() const = 0;
 
   // TODO(bugs.webrtc.org/10679): Delete, migrate users to the above GetStats
   // method (and extend RtpReceiveStats if needed).
diff --git a/modules/rtp_rtcp/include/remote_ntp_time_estimator.h b/modules/rtp_rtcp/include/remote_ntp_time_estimator.h
index 01d0c85..f60763a 100644
--- a/modules/rtp_rtcp/include/remote_ntp_time_estimator.h
+++ b/modules/rtp_rtcp/include/remote_ntp_time_estimator.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
 #include "rtc_base/numerics/moving_percentile_filter.h"
@@ -58,7 +59,7 @@
   // local one. This is equal to local NTP clock - remote NTP clock.
   // The offset is returned in ntp time resolution, i.e. 1/2^32 sec ~= 0.2 ns.
   // Returns nullopt on failure.
-  absl::optional<int64_t> EstimateRemoteToLocalClockOffset();
+  std::optional<int64_t> EstimateRemoteToLocalClockOffset();
 
  private:
   Clock* clock_;
diff --git a/modules/rtp_rtcp/include/rtp_rtcp_defines.h b/modules/rtp_rtcp/include/rtp_rtcp_defines.h
index 911a4eb..eb4d1d0 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp_defines.h
+++ b/modules/rtp_rtcp/include/rtp_rtcp_defines.h
@@ -17,12 +17,12 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/array_view.h"
 #include "api/audio_codecs/audio_format.h"
@@ -200,11 +200,11 @@
                                 const PacedPacketInfo& pacing_info);
 
   uint16_t transport_sequence_number = 0;
-  absl::optional<uint32_t> media_ssrc;
+  std::optional<uint32_t> media_ssrc;
   uint16_t rtp_sequence_number = 0;  // Only valid if `media_ssrc` is set.
   uint32_t rtp_timestamp = 0;
   size_t length = 0;
-  absl::optional<RtpPacketMediaType> packet_type;
+  std::optional<RtpPacketMediaType> packet_type;
   PacedPacketInfo pacing_info;
 };
 
@@ -241,7 +241,7 @@
 
     // `rtp_sequence_number` and `is_retransmission` are only valid if `ssrc`
     // is populated.
-    absl::optional<uint32_t> ssrc;
+    std::optional<uint32_t> ssrc;
     uint16_t rtp_sequence_number;
     bool is_retransmission;
   };
@@ -403,7 +403,7 @@
 
   // Time of the last packet received in unix epoch,
   // i.e. Timestamp::Zero() represents 1st Jan 1970 00:00
-  absl::optional<Timestamp> last_packet_received;
+  std::optional<Timestamp> last_packet_received;
 
   // Counters exposed in RTCInboundRtpStreamStats, see
   // https://w3c.github.io/webrtc-stats/#inboundrtpstats-dict*
@@ -425,7 +425,7 @@
 class SendPacketObserver {
  public:
   virtual ~SendPacketObserver() = default;
-  virtual void OnSendPacket(absl::optional<uint16_t> packet_id,
+  virtual void OnSendPacket(std::optional<uint16_t> packet_id,
                             Timestamp capture_time,
                             uint32_t ssrc) = 0;
 };
diff --git a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
index 6aec723..4406ad6 100644
--- a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
+++ b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
@@ -12,13 +12,13 @@
 #define MODULES_RTP_RTCP_MOCKS_MOCK_RTP_RTCP_H_
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/video/video_bitrate_allocation.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
@@ -69,9 +69,9 @@
   MOCK_METHOD(void, SetMid, (absl::string_view mid), (override));
   MOCK_METHOD(void, SetRtxSendStatus, (int modes), (override));
   MOCK_METHOD(int, RtxSendStatus, (), (const, override));
-  MOCK_METHOD(absl::optional<uint32_t>, RtxSsrc, (), (const, override));
+  MOCK_METHOD(std::optional<uint32_t>, RtxSsrc, (), (const, override));
   MOCK_METHOD(void, SetRtxSendPayloadType, (int, int), (override));
-  MOCK_METHOD(absl::optional<uint32_t>, FlexfecSsrc, (), (const, override));
+  MOCK_METHOD(std::optional<uint32_t>, FlexfecSsrc, (), (const, override));
   MOCK_METHOD(int32_t, SetSendingStatus, (bool sending), (override));
   MOCK_METHOD(bool, Sending, (), (const, override));
   MOCK_METHOD(void, SetSendingMediaStatus, (bool sending), (override));
@@ -132,7 +132,7 @@
   MOCK_METHOD(RtcpMode, RTCP, (), (const, override));
   MOCK_METHOD(void, SetRTCPStatus, (RtcpMode method), (override));
   MOCK_METHOD(int32_t, SetCNAME, (absl::string_view cname), (override));
-  MOCK_METHOD(absl::optional<TimeDelta>, LastRtt, (), (const, override));
+  MOCK_METHOD(std::optional<TimeDelta>, LastRtt, (), (const, override));
   MOCK_METHOD(TimeDelta, ExpectedRetransmissionTime, (), (const, override));
   MOCK_METHOD(int32_t, SendRTCP, (RTCPPacketType packet_type), (override));
   MOCK_METHOD(void,
@@ -143,11 +143,11 @@
               GetLatestReportBlockData,
               (),
               (const, override));
-  MOCK_METHOD(absl::optional<SenderReportStats>,
+  MOCK_METHOD(std::optional<SenderReportStats>,
               GetSenderReportStats,
               (),
               (const, override));
-  MOCK_METHOD(absl::optional<NonSenderRttStats>,
+  MOCK_METHOD(std::optional<NonSenderRttStats>,
               GetNonSenderRttStats,
               (),
               (const, override));
diff --git a/modules/rtp_rtcp/source/absolute_capture_time_interpolator.cc b/modules/rtp_rtcp/source/absolute_capture_time_interpolator.cc
index f151084..5da0ce4 100644
--- a/modules/rtp_rtcp/source/absolute_capture_time_interpolator.cc
+++ b/modules/rtp_rtcp/source/absolute_capture_time_interpolator.cc
@@ -29,21 +29,21 @@
   return csrcs[0];
 }
 
-absl::optional<AbsoluteCaptureTime>
+std::optional<AbsoluteCaptureTime>
 AbsoluteCaptureTimeInterpolator::OnReceivePacket(
     uint32_t source,
     uint32_t rtp_timestamp,
     int rtp_clock_frequency_hz,
-    const absl::optional<AbsoluteCaptureTime>& received_extension) {
+    const std::optional<AbsoluteCaptureTime>& received_extension) {
   const Timestamp receive_time = clock_->CurrentTime();
 
   MutexLock lock(&mutex_);
 
-  if (received_extension == absl::nullopt) {
+  if (received_extension == std::nullopt) {
     if (!ShouldInterpolateExtension(receive_time, source, rtp_timestamp,
                                     rtp_clock_frequency_hz)) {
       last_receive_time_ = Timestamp::MinusInfinity();
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     return AbsoluteCaptureTime{
diff --git a/modules/rtp_rtcp/source/absolute_capture_time_interpolator.h b/modules/rtp_rtcp/source/absolute_capture_time_interpolator.h
index c830686..59ddead 100644
--- a/modules/rtp_rtcp/source/absolute_capture_time_interpolator.h
+++ b/modules/rtp_rtcp/source/absolute_capture_time_interpolator.h
@@ -44,12 +44,12 @@
                             rtc::ArrayView<const uint32_t> csrcs);
 
   // Returns a received header extension, an interpolated header extension, or
-  // `absl::nullopt` if it's not possible to interpolate a header extension.
-  absl::optional<AbsoluteCaptureTime> OnReceivePacket(
+  // `std::nullopt` if it's not possible to interpolate a header extension.
+  std::optional<AbsoluteCaptureTime> OnReceivePacket(
       uint32_t source,
       uint32_t rtp_timestamp,
       int rtp_clock_frequency_hz,
-      const absl::optional<AbsoluteCaptureTime>& received_extension);
+      const std::optional<AbsoluteCaptureTime>& received_extension);
 
  private:
   friend class AbsoluteCaptureTimeSender;
diff --git a/modules/rtp_rtcp/source/absolute_capture_time_interpolator_unittest.cc b/modules/rtp_rtcp/source/absolute_capture_time_interpolator_unittest.cc
index 4a48054..7471496 100644
--- a/modules/rtp_rtcp/source/absolute_capture_time_interpolator_unittest.cc
+++ b/modules/rtp_rtcp/source/absolute_capture_time_interpolator_unittest.cc
@@ -38,7 +38,7 @@
   const AbsoluteCaptureTime kExtension0 = {Int64MsToUQ32x32(9000),
                                            Int64MsToQ32x32(-350)};
   const AbsoluteCaptureTime kExtension1 = {Int64MsToUQ32x32(9020),
-                                           absl::nullopt};
+                                           std::nullopt};
 
   SimulatedClock clock(0);
   AbsoluteCaptureTimeInterpolator interpolator(&clock);
@@ -64,13 +64,13 @@
 
   EXPECT_EQ(
       interpolator.OnReceivePacket(kSource, kRtpTimestamp0, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt),
-      absl::nullopt);
+                                   /*received_extension=*/std::nullopt),
+      std::nullopt);
 
   EXPECT_EQ(
       interpolator.OnReceivePacket(kSource, kRtpTimestamp1, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt),
-      absl::nullopt);
+                                   /*received_extension=*/std::nullopt),
+      std::nullopt);
 }
 
 TEST(AbsoluteCaptureTimeInterpolatorTest, InterpolateLaterPacketArrivingLater) {
@@ -89,9 +89,9 @@
                                          kRtpClockFrequency, kExtension),
             kExtension);
 
-  absl::optional<AbsoluteCaptureTime> extension =
+  std::optional<AbsoluteCaptureTime> extension =
       interpolator.OnReceivePacket(kSource, kRtpTimestamp1, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt);
+                                   /*received_extension=*/std::nullopt);
   ASSERT_TRUE(extension.has_value());
   EXPECT_EQ(UQ32x32ToInt64Ms(extension->absolute_capture_timestamp),
             UQ32x32ToInt64Ms(kExtension.absolute_capture_timestamp) + 20);
@@ -100,7 +100,7 @@
 
   extension =
       interpolator.OnReceivePacket(kSource, kRtpTimestamp2, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt);
+                                   /*received_extension=*/std::nullopt);
   ASSERT_TRUE(extension.has_value());
   EXPECT_EQ(UQ32x32ToInt64Ms(extension->absolute_capture_timestamp),
             UQ32x32ToInt64Ms(kExtension.absolute_capture_timestamp) + 40);
@@ -125,9 +125,9 @@
                                          kRtpClockFrequency, kExtension),
             kExtension);
 
-  absl::optional<AbsoluteCaptureTime> extension =
+  std::optional<AbsoluteCaptureTime> extension =
       interpolator.OnReceivePacket(kSource, kRtpTimestamp1, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt);
+                                   /*received_extension=*/std::nullopt);
   ASSERT_TRUE(extension.has_value());
   EXPECT_EQ(UQ32x32ToInt64Ms(extension->absolute_capture_timestamp),
             UQ32x32ToInt64Ms(kExtension.absolute_capture_timestamp) - 20);
@@ -136,7 +136,7 @@
 
   extension =
       interpolator.OnReceivePacket(kSource, kRtpTimestamp2, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt);
+                                   /*received_extension=*/std::nullopt);
   ASSERT_TRUE(extension.has_value());
   EXPECT_EQ(UQ32x32ToInt64Ms(extension->absolute_capture_timestamp),
             UQ32x32ToInt64Ms(kExtension.absolute_capture_timestamp) - 40);
@@ -161,9 +161,9 @@
                                          kRtpClockFrequency, kExtension),
             kExtension);
 
-  absl::optional<AbsoluteCaptureTime> extension =
+  std::optional<AbsoluteCaptureTime> extension =
       interpolator.OnReceivePacket(kSource, kRtpTimestamp1, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt);
+                                   /*received_extension=*/std::nullopt);
   ASSERT_TRUE(extension.has_value());
   EXPECT_EQ(UQ32x32ToInt64Ms(extension->absolute_capture_timestamp),
             UQ32x32ToInt64Ms(kExtension.absolute_capture_timestamp) + 20);
@@ -172,7 +172,7 @@
 
   extension =
       interpolator.OnReceivePacket(kSource, kRtpTimestamp2, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt);
+                                   /*received_extension=*/std::nullopt);
   ASSERT_TRUE(extension.has_value());
   EXPECT_EQ(UQ32x32ToInt64Ms(extension->absolute_capture_timestamp),
             UQ32x32ToInt64Ms(kExtension.absolute_capture_timestamp) + 40);
@@ -197,9 +197,9 @@
                                          kRtpClockFrequency, kExtension),
             kExtension);
 
-  absl::optional<AbsoluteCaptureTime> extension =
+  std::optional<AbsoluteCaptureTime> extension =
       interpolator.OnReceivePacket(kSource, kRtpTimestamp1, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt);
+                                   /*received_extension=*/std::nullopt);
   ASSERT_TRUE(extension.has_value());
   EXPECT_EQ(UQ32x32ToInt64Ms(extension->absolute_capture_timestamp),
             UQ32x32ToInt64Ms(kExtension.absolute_capture_timestamp) - 20);
@@ -208,7 +208,7 @@
 
   extension =
       interpolator.OnReceivePacket(kSource, kRtpTimestamp2, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt);
+                                   /*received_extension=*/std::nullopt);
   ASSERT_TRUE(extension.has_value());
   EXPECT_EQ(UQ32x32ToInt64Ms(extension->absolute_capture_timestamp),
             UQ32x32ToInt64Ms(kExtension.absolute_capture_timestamp) - 40);
@@ -236,15 +236,15 @@
 
   EXPECT_NE(
       interpolator.OnReceivePacket(kSource, kRtpTimestamp1, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt),
-      absl::nullopt);
+                                   /*received_extension=*/std::nullopt),
+      std::nullopt);
 
   clock.AdvanceTime(TimeDelta::Millis(1));
 
   EXPECT_EQ(
       interpolator.OnReceivePacket(kSource, kRtpTimestamp2, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt),
-      absl::nullopt);
+                                   /*received_extension=*/std::nullopt),
+      std::nullopt);
 }
 
 TEST(AbsoluteCaptureTimeInterpolatorTest, SkipInterpolateIfSourceChanged) {
@@ -265,8 +265,8 @@
 
   EXPECT_EQ(
       interpolator.OnReceivePacket(kSource1, kRtpTimestamp1, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt),
-      absl::nullopt);
+                                   /*received_extension=*/std::nullopt),
+      std::nullopt);
 }
 
 TEST(AbsoluteCaptureTimeInterpolatorTest,
@@ -288,8 +288,8 @@
 
   EXPECT_EQ(
       interpolator.OnReceivePacket(kSource, kRtpTimestamp1, kRtpClockFrequency1,
-                                   /*received_extension=*/absl::nullopt),
-      absl::nullopt);
+                                   /*received_extension=*/std::nullopt),
+      std::nullopt);
 }
 
 TEST(AbsoluteCaptureTimeInterpolatorTest,
@@ -310,8 +310,8 @@
 
   EXPECT_EQ(interpolator.OnReceivePacket(kSource, kRtpTimestamp1,
                                          /*rtp_clock_frequency_hz=*/0,
-                                         /*received_extension=*/absl::nullopt),
-            absl::nullopt);
+                                         /*received_extension=*/std::nullopt),
+            std::nullopt);
 }
 
 TEST(AbsoluteCaptureTimeInterpolatorTest, SkipInterpolateIsSticky) {
@@ -333,13 +333,13 @@
 
   EXPECT_EQ(
       interpolator.OnReceivePacket(kSource1, kRtpTimestamp1, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt),
-      absl::nullopt);
+                                   /*received_extension=*/std::nullopt),
+      std::nullopt);
 
   EXPECT_EQ(
       interpolator.OnReceivePacket(kSource0, kRtpTimestamp2, kRtpClockFrequency,
-                                   /*received_extension=*/absl::nullopt),
-      absl::nullopt);
+                                   /*received_extension=*/std::nullopt),
+      std::nullopt);
 }
 
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/absolute_capture_time_sender.cc b/modules/rtp_rtcp/source/absolute_capture_time_sender.cc
index 09f61a0..ae7fe6e 100644
--- a/modules/rtp_rtcp/source/absolute_capture_time_sender.cc
+++ b/modules/rtp_rtcp/source/absolute_capture_time_sender.cc
@@ -31,29 +31,29 @@
   return AbsoluteCaptureTimeInterpolator::GetSource(ssrc, csrcs);
 }
 
-absl::optional<AbsoluteCaptureTime> AbsoluteCaptureTimeSender::OnSendPacket(
+std::optional<AbsoluteCaptureTime> AbsoluteCaptureTimeSender::OnSendPacket(
     uint32_t source,
     uint32_t rtp_timestamp,
     uint32_t rtp_clock_frequency,
     uint64_t absolute_capture_timestamp,
-    absl::optional<int64_t> estimated_capture_clock_offset) {
+    std::optional<int64_t> estimated_capture_clock_offset) {
   return OnSendPacket(source, rtp_timestamp, rtp_clock_frequency,
                       NtpTime(absolute_capture_timestamp),
                       estimated_capture_clock_offset, /*force=*/false);
 }
 
-absl::optional<AbsoluteCaptureTime> AbsoluteCaptureTimeSender::OnSendPacket(
+std::optional<AbsoluteCaptureTime> AbsoluteCaptureTimeSender::OnSendPacket(
     uint32_t source,
     uint32_t rtp_timestamp,
     int rtp_clock_frequency_hz,
     NtpTime absolute_capture_time,
-    absl::optional<int64_t> estimated_capture_clock_offset,
+    std::optional<int64_t> estimated_capture_clock_offset,
     bool force) {
   Timestamp send_time = clock_->CurrentTime();
   if (!(force || ShouldSendExtension(
                      send_time, source, rtp_timestamp, rtp_clock_frequency_hz,
                      absolute_capture_time, estimated_capture_clock_offset))) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   last_source_ = source;
@@ -75,7 +75,7 @@
     uint32_t rtp_timestamp,
     int rtp_clock_frequency_hz,
     NtpTime absolute_capture_time,
-    absl::optional<int64_t> estimated_capture_clock_offset) const {
+    std::optional<int64_t> estimated_capture_clock_offset) const {
   // Should if the last sent extension is too old, in particular if we've never
   // sent anything before.
   if (send_time - last_send_time_ > kInterpolationMaxInterval) {
diff --git a/modules/rtp_rtcp/source/absolute_capture_time_sender.h b/modules/rtp_rtcp/source/absolute_capture_time_sender.h
index a961c3b..595920f 100644
--- a/modules/rtp_rtcp/source/absolute_capture_time_sender.h
+++ b/modules/rtp_rtcp/source/absolute_capture_time_sender.h
@@ -49,7 +49,7 @@
                             rtc::ArrayView<const uint32_t> csrcs);
 
   // Returns value to write into AbsoluteCaptureTime RTP header extension to be
-  // sent, or `absl::nullopt` if the header extension shouldn't be attached to
+  // sent, or `std::nullopt` if the header extension shouldn't be attached to
   // the outgoing packet.
   //
   // - `source` - id of the capture system.
@@ -65,22 +65,22 @@
   // i.e. delta of 2^32 represents 1 second. See AbsoluteCaptureTime type
   // comments for more details.
   // - `force` - when set to true, OnSendPacket is forced to return non-nullopt.
-  absl::optional<AbsoluteCaptureTime> OnSendPacket(
+  std::optional<AbsoluteCaptureTime> OnSendPacket(
       uint32_t source,
       uint32_t rtp_timestamp,
       int rtp_clock_frequency_hz,
       NtpTime absolute_capture_time,
-      absl::optional<int64_t> estimated_capture_clock_offset,
+      std::optional<int64_t> estimated_capture_clock_offset,
       bool force = false);
 
-  // Returns a header extension to be sent, or `absl::nullopt` if the header
+  // Returns a header extension to be sent, or `std::nullopt` if the header
   // extension shouldn't be sent.
-  [[deprecated]] absl::optional<AbsoluteCaptureTime> OnSendPacket(
+  [[deprecated]] std::optional<AbsoluteCaptureTime> OnSendPacket(
       uint32_t source,
       uint32_t rtp_timestamp,
       uint32_t rtp_clock_frequency,
       uint64_t absolute_capture_timestamp,
-      absl::optional<int64_t> estimated_capture_clock_offset);
+      std::optional<int64_t> estimated_capture_clock_offset);
 
  private:
   bool ShouldSendExtension(
@@ -89,7 +89,7 @@
       uint32_t rtp_timestamp,
       int rtp_clock_frequency_hz,
       NtpTime absolute_capture_time,
-      absl::optional<int64_t> estimated_capture_clock_offset) const;
+      std::optional<int64_t> estimated_capture_clock_offset) const;
 
   Clock* const clock_;
 
@@ -99,7 +99,7 @@
   uint32_t last_rtp_timestamp_;
   int last_rtp_clock_frequency_hz_;
   NtpTime last_absolute_capture_time_;
-  absl::optional<int64_t> last_estimated_capture_clock_offset_;
+  std::optional<int64_t> last_estimated_capture_clock_offset_;
 };
 
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/absolute_capture_time_sender_unittest.cc b/modules/rtp_rtcp/source/absolute_capture_time_sender_unittest.cc
index d9146e4..dcb951e 100644
--- a/modules/rtp_rtcp/source/absolute_capture_time_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/absolute_capture_time_sender_unittest.cc
@@ -52,12 +52,12 @@
   EXPECT_EQ(sender.OnSendPacket(kSource, kRtpTimestamp1, kRtpClockFrequency,
                                 NtpTime(kExtension1.absolute_capture_timestamp),
                                 kExtension1.estimated_capture_clock_offset),
-            absl::nullopt);
+            std::nullopt);
 
   EXPECT_EQ(sender.OnSendPacket(kSource, kRtpTimestamp2, kRtpClockFrequency,
                                 NtpTime(kExtension2.absolute_capture_timestamp),
                                 kExtension2.estimated_capture_clock_offset),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(AbsoluteCaptureTimeSenderTest, InterpolateEarlierPacketSentLater) {
@@ -84,12 +84,12 @@
   EXPECT_EQ(sender.OnSendPacket(kSource, kRtpTimestamp1, kRtpClockFrequency,
                                 NtpTime(kExtension1.absolute_capture_timestamp),
                                 kExtension1.estimated_capture_clock_offset),
-            absl::nullopt);
+            std::nullopt);
 
   EXPECT_EQ(sender.OnSendPacket(kSource, kRtpTimestamp2, kRtpClockFrequency,
                                 NtpTime(kExtension2.absolute_capture_timestamp),
                                 kExtension2.estimated_capture_clock_offset),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(AbsoluteCaptureTimeSenderTest,
@@ -117,12 +117,12 @@
   EXPECT_EQ(sender.OnSendPacket(kSource, kRtpTimestamp1, kRtpClockFrequency,
                                 NtpTime(kExtension1.absolute_capture_timestamp),
                                 kExtension1.estimated_capture_clock_offset),
-            absl::nullopt);
+            std::nullopt);
 
   EXPECT_EQ(sender.OnSendPacket(kSource, kRtpTimestamp2, kRtpClockFrequency,
                                 NtpTime(kExtension2.absolute_capture_timestamp),
                                 kExtension2.estimated_capture_clock_offset),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(AbsoluteCaptureTimeSenderTest,
@@ -150,12 +150,12 @@
   EXPECT_EQ(sender.OnSendPacket(kSource, kRtpTimestamp1, kRtpClockFrequency,
                                 NtpTime(kExtension1.absolute_capture_timestamp),
                                 kExtension1.estimated_capture_clock_offset),
-            absl::nullopt);
+            std::nullopt);
 
   EXPECT_EQ(sender.OnSendPacket(kSource, kRtpTimestamp2, kRtpClockFrequency,
                                 NtpTime(kExtension2.absolute_capture_timestamp),
                                 kExtension2.estimated_capture_clock_offset),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(AbsoluteCaptureTimeSenderTest, SkipInterpolateIfTooLate) {
@@ -184,7 +184,7 @@
   EXPECT_EQ(sender.OnSendPacket(kSource, kRtpTimestamp1, kRtpClockFrequency,
                                 NtpTime(kExtension1.absolute_capture_timestamp),
                                 kExtension1.estimated_capture_clock_offset),
-            absl::nullopt);
+            std::nullopt);
 
   clock.AdvanceTime(TimeDelta::Millis(1));
 
@@ -224,7 +224,7 @@
   EXPECT_EQ(sender.OnSendPacket(kSource1, kRtpTimestamp2, kRtpClockFrequency,
                                 NtpTime(kExtension2.absolute_capture_timestamp),
                                 kExtension2.estimated_capture_clock_offset),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(AbsoluteCaptureTimeSenderTest, SkipInterpolateWhenForced) {
@@ -258,7 +258,7 @@
                                 NtpTime(kExtension2.absolute_capture_timestamp),
                                 kExtension2.estimated_capture_clock_offset,
                                 /*force=*/false),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(AbsoluteCaptureTimeSenderTest, SkipInterpolateIfRtpClockFrequencyChanged) {
@@ -291,7 +291,7 @@
   EXPECT_EQ(sender.OnSendPacket(kSource, kRtpTimestamp2, kRtpClockFrequency1,
                                 NtpTime(kExtension2.absolute_capture_timestamp),
                                 kExtension2.estimated_capture_clock_offset),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(AbsoluteCaptureTimeSenderTest,
@@ -337,7 +337,7 @@
   const AbsoluteCaptureTime kExtension1 = {Int64MsToUQ32x32(9000 + 20),
                                            Int64MsToQ32x32(370)};
   const AbsoluteCaptureTime kExtension2 = {Int64MsToUQ32x32(9000 + 40),
-                                           absl::nullopt};
+                                           std::nullopt};
 
   SimulatedClock clock(0);
   AbsoluteCaptureTimeSender sender(&clock);
@@ -388,7 +388,7 @@
   EXPECT_EQ(sender.OnSendPacket(kSource, kRtpTimestamp1, kRtpClockFrequency,
                                 NtpTime(kExtension1.absolute_capture_timestamp),
                                 kExtension1.estimated_capture_clock_offset),
-            absl::nullopt);
+            std::nullopt);
 
   EXPECT_EQ(sender.OnSendPacket(kSource, kRtpTimestamp2, kRtpClockFrequency,
                                 NtpTime(kExtension2.absolute_capture_timestamp),
diff --git a/modules/rtp_rtcp/source/active_decode_targets_helper.h b/modules/rtp_rtcp/source/active_decode_targets_helper.h
index 13755e8..319fcd6 100644
--- a/modules/rtp_rtcp/source/active_decode_targets_helper.h
+++ b/modules/rtp_rtcp/source/active_decode_targets_helper.h
@@ -14,8 +14,8 @@
 #include <stdint.h>
 
 #include <bitset>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 
 namespace webrtc {
@@ -41,9 +41,9 @@
                rtc::ArrayView<const int> chain_diffs);
 
   // Returns active decode target to attach to the dependency descriptor.
-  absl::optional<uint32_t> ActiveDecodeTargetsBitmask() const {
+  std::optional<uint32_t> ActiveDecodeTargetsBitmask() const {
     if (unsent_on_chain_.none())
-      return absl::nullopt;
+      return std::nullopt;
     return last_active_decode_targets_.to_ulong();
   }
 
diff --git a/modules/rtp_rtcp/source/active_decode_targets_helper_unittest.cc b/modules/rtp_rtcp/source/active_decode_targets_helper_unittest.cc
index 6f64fd1..2e7f687 100644
--- a/modules/rtp_rtcp/source/active_decode_targets_helper_unittest.cc
+++ b/modules/rtp_rtcp/source/active_decode_targets_helper_unittest.cc
@@ -10,9 +10,9 @@
 
 #include "modules/rtp_rtcp/source/active_decode_targets_helper.h"
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "test/gtest.h"
 
 namespace webrtc {
@@ -29,7 +29,7 @@
                  /*active_decode_targets=*/0b11,
                  /*is_keyframe=*/true, /*frame_id=*/1, chain_diffs);
 
-  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
+  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), std::nullopt);
 }
 
 TEST(ActiveDecodeTargetsHelperTest,
@@ -50,7 +50,7 @@
                  /*active_decode_targets=*/0b11,
                  /*is_keyframe=*/true, /*frame_id=*/3, chain_diffs_key);
 
-  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
+  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), std::nullopt);
 }
 
 TEST(ActiveDecodeTargetsHelperTest,
@@ -78,7 +78,7 @@
                  /*active_decode_targets=*/0b01,
                  /*is_keyframe=*/false, /*frame_id=*/2, chain_diffs_delta);
 
-  ASSERT_EQ(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
+  ASSERT_EQ(helper.ActiveDecodeTargetsBitmask(), std::nullopt);
   helper.OnFrame(kDecodeTargetProtectedByChain,
                  /*active_decode_targets=*/0b01,
                  /*is_keyframe=*/true, /*frame_id=*/3, chain_diffs_key);
@@ -94,12 +94,12 @@
   helper.OnFrame(kDecodeTargetProtectedByChain,
                  /*active_decode_targets=*/kAll,
                  /*is_keyframe=*/true, /*frame_id=*/1, chain_diffs);
-  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
+  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), std::nullopt);
 
   helper.OnFrame(kDecodeTargetProtectedByChain,
                  /*active_decode_targets=*/kAll,
                  /*is_keyframe=*/false, /*frame_id=*/2, chain_diffs);
-  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
+  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), std::nullopt);
 }
 
 TEST(ActiveDecodeTargetsHelperTest,
@@ -115,7 +115,7 @@
                  /*active_decode_targets=*/0b01,
                  /*is_keyframe=*/false, /*frame_id=*/2, chain_diffs_delta);
 
-  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
+  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), std::nullopt);
 }
 
 TEST(ActiveDecodeTargetsHelperTest, ReturnsNewBitmaskOnDeltaFrame) {
@@ -125,7 +125,7 @@
   helper.OnFrame(kDecodeTargetProtectedByChain,
                  /*active_decode_targets=*/0b11,
                  /*is_keyframe=*/true, /*frame_id=*/1, chain_diffs_key);
-  ASSERT_EQ(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
+  ASSERT_EQ(helper.ActiveDecodeTargetsBitmask(), std::nullopt);
   int chain_diffs_delta[] = {1};
   helper.OnFrame(kDecodeTargetProtectedByChain,
                  /*active_decode_targets=*/0b01,
@@ -142,12 +142,12 @@
   helper.OnFrame(kDecodeTargetProtectedByChain,
                  /*active_decode_targets=*/0b01,
                  /*is_keyframe=*/true, /*frame_id=*/1, chain_diffs_key);
-  ASSERT_NE(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
+  ASSERT_NE(helper.ActiveDecodeTargetsBitmask(), std::nullopt);
   int chain_diffs_delta[] = {1};
   helper.OnFrame(kDecodeTargetProtectedByChain,
                  /*active_decode_targets=*/0b01,
                  /*is_keyframe=*/false, /*frame_id=*/2, chain_diffs_delta);
-  ASSERT_EQ(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
+  ASSERT_EQ(helper.ActiveDecodeTargetsBitmask(), std::nullopt);
 
   // Reactive all the decode targets
   helper.OnFrame(kDecodeTargetProtectedByChain,
@@ -167,7 +167,7 @@
                  /*active_decode_targets=*/0b111,
                  /*is_keyframe=*/true,
                  /*frame_id=*/0, chain_diffs_key);
-  ASSERT_EQ(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
+  ASSERT_EQ(helper.ActiveDecodeTargetsBitmask(), std::nullopt);
 
   int chain_diffs_delta1[] = {1, 1, 1};
   helper.OnFrame(kDecodeTargetProtectedByChain,
@@ -190,7 +190,7 @@
                  /*active_decode_targets=*/kSome,
                  /*is_keyframe=*/false,
                  /*frame_id=*/3, chain_diffs_delta3);
-  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
+  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), std::nullopt);
 }
 
 TEST(ActiveDecodeTargetsHelperTest, ReturnsBitmaskWhenChanged) {
@@ -232,13 +232,13 @@
   helper.OnFrame(kDecodeTargetProtectedByChain, /*active_decode_targets=*/kAll,
                  /*is_keyframe=*/true,
                  /*frame_id=*/0, kNoChainDiffs);
-  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
+  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), std::nullopt);
 
   helper.OnFrame(kDecodeTargetProtectedByChain,
                  /*active_decode_targets=*/0b101,
                  /*is_keyframe=*/false,
                  /*frame_id=*/1, kNoChainDiffs);
-  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
+  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), std::nullopt);
 }
 
 TEST(ActiveDecodeTargetsHelperTest, Supports32DecodeTargets) {
@@ -261,7 +261,7 @@
                  /*active_decode_targets=*/some,
                  /*is_keyframe=*/false,
                  /*frame_id=*/2, chain_diffs_delta);
-  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
+  EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), std::nullopt);
   helper.OnFrame(decode_target_protected_by_chain,
                  /*active_decode_targets=*/kAll,
                  /*is_keyframe=*/false,
diff --git a/modules/rtp_rtcp/source/capture_clock_offset_updater.cc b/modules/rtp_rtcp/source/capture_clock_offset_updater.cc
index ad935a9..9378520 100644
--- a/modules/rtp_rtcp/source/capture_clock_offset_updater.cc
+++ b/modules/rtp_rtcp/source/capture_clock_offset_updater.cc
@@ -14,12 +14,12 @@
 
 namespace webrtc {
 
-absl::optional<int64_t>
+std::optional<int64_t>
 CaptureClockOffsetUpdater::AdjustEstimatedCaptureClockOffset(
-    absl::optional<int64_t> remote_capture_clock_offset) const {
-  if (remote_capture_clock_offset == absl::nullopt ||
-      remote_to_local_clock_offset_ == absl::nullopt) {
-    return absl::nullopt;
+    std::optional<int64_t> remote_capture_clock_offset) const {
+  if (remote_capture_clock_offset == std::nullopt ||
+      remote_to_local_clock_offset_ == std::nullopt) {
+    return std::nullopt;
   }
 
   // Do calculations as "unsigned" to make overflows deterministic.
@@ -27,16 +27,16 @@
          static_cast<uint64_t>(*remote_to_local_clock_offset_);
 }
 
-absl::optional<TimeDelta> CaptureClockOffsetUpdater::ConvertsToTimeDela(
-    absl::optional<int64_t> q32x32) {
-  if (q32x32 == absl::nullopt) {
-    return absl::nullopt;
+std::optional<TimeDelta> CaptureClockOffsetUpdater::ConvertsToTimeDela(
+    std::optional<int64_t> q32x32) {
+  if (q32x32 == std::nullopt) {
+    return std::nullopt;
   }
   return TimeDelta::Millis(Q32x32ToInt64Ms(*q32x32));
 }
 
 void CaptureClockOffsetUpdater::SetRemoteToLocalClockOffset(
-    absl::optional<int64_t> offset_q32x32) {
+    std::optional<int64_t> offset_q32x32) {
   remote_to_local_clock_offset_ = offset_q32x32;
 }
 
diff --git a/modules/rtp_rtcp/source/capture_clock_offset_updater.h b/modules/rtp_rtcp/source/capture_clock_offset_updater.h
index 9b28848..5bae8b8 100644
--- a/modules/rtp_rtcp/source/capture_clock_offset_updater.h
+++ b/modules/rtp_rtcp/source/capture_clock_offset_updater.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/time_delta.h"
 
 namespace webrtc {
@@ -32,8 +33,8 @@
   // Adjusts remote_capture_clock_offset, which originates from Absolute Capture
   // Time RTP header extension, to get the local clock offset against the
   // capturer's clock.
-  absl::optional<int64_t> AdjustEstimatedCaptureClockOffset(
-      absl::optional<int64_t> remote_capture_clock_offset) const;
+  std::optional<int64_t> AdjustEstimatedCaptureClockOffset(
+      std::optional<int64_t> remote_capture_clock_offset) const;
 
   // Sets the NTP clock offset between the sender system (which may be different
   // from the capture system) and the local system. This information is normally
@@ -41,14 +42,14 @@
   // by RTCP sender reports (see DLSR/DLRR).
   //
   // Note that the value must be in Q32.32-formatted fixed-point seconds.
-  void SetRemoteToLocalClockOffset(absl::optional<int64_t> offset_q32x32);
+  void SetRemoteToLocalClockOffset(std::optional<int64_t> offset_q32x32);
 
   // Converts a signed Q32.32-formatted fixed-point to a TimeDelta.
-  static absl::optional<TimeDelta> ConvertsToTimeDela(
-      absl::optional<int64_t> q32x32);
+  static std::optional<TimeDelta> ConvertsToTimeDela(
+      std::optional<int64_t> q32x32);
 
  private:
-  absl::optional<int64_t> remote_to_local_clock_offset_;
+  std::optional<int64_t> remote_to_local_clock_offset_;
 };
 
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/capture_clock_offset_updater_unittest.cc b/modules/rtp_rtcp/source/capture_clock_offset_updater_unittest.cc
index f6bea4b..f05dae2 100644
--- a/modules/rtp_rtcp/source/capture_clock_offset_updater_unittest.cc
+++ b/modules/rtp_rtcp/source/capture_clock_offset_updater_unittest.cc
@@ -18,24 +18,24 @@
 
 TEST(AbsoluteCaptureTimeReceiverTest,
      SkipEstimatedCaptureClockOffsetIfRemoteToLocalClockOffsetIsUnknown) {
-  static const absl::optional<int64_t> kRemoteCaptureClockOffset =
+  static const std::optional<int64_t> kRemoteCaptureClockOffset =
       Int64MsToQ32x32(-350);
   CaptureClockOffsetUpdater updater;
-  updater.SetRemoteToLocalClockOffset(absl::nullopt);
+  updater.SetRemoteToLocalClockOffset(std::nullopt);
   EXPECT_EQ(
       updater.AdjustEstimatedCaptureClockOffset(kRemoteCaptureClockOffset),
-      absl::nullopt);
+      std::nullopt);
 }
 
 TEST(AbsoluteCaptureTimeReceiverTest,
      SkipEstimatedCaptureClockOffsetIfRemoteCaptureClockOffsetIsUnknown) {
-  static const absl::optional<int64_t> kCaptureClockOffsetNull = absl::nullopt;
+  static const std::optional<int64_t> kCaptureClockOffsetNull = std::nullopt;
   CaptureClockOffsetUpdater updater;
   updater.SetRemoteToLocalClockOffset(0);
   EXPECT_EQ(updater.AdjustEstimatedCaptureClockOffset(kCaptureClockOffsetNull),
             kCaptureClockOffsetNull);
 
-  static const absl::optional<int64_t> kRemoteCaptureClockOffset =
+  static const std::optional<int64_t> kRemoteCaptureClockOffset =
       Int64MsToQ32x32(-350);
   EXPECT_EQ(
       updater.AdjustEstimatedCaptureClockOffset(kRemoteCaptureClockOffset),
@@ -43,9 +43,9 @@
 }
 
 TEST(AbsoluteCaptureTimeReceiverTest, EstimatedCaptureClockOffsetArithmetic) {
-  static const absl::optional<int64_t> kRemoteCaptureClockOffset =
+  static const std::optional<int64_t> kRemoteCaptureClockOffset =
       Int64MsToQ32x32(-350);
-  static const absl::optional<int64_t> kRemoteToLocalClockOffset =
+  static const std::optional<int64_t> kRemoteToLocalClockOffset =
       Int64MsToQ32x32(-7000007);
   CaptureClockOffsetUpdater updater;
   updater.SetRemoteToLocalClockOffset(kRemoteToLocalClockOffset);
@@ -63,7 +63,7 @@
   constexpr int64_t kPositiveQ32x32 =
       kPositive.ms() * (NtpTime::kFractionsPerSecond / 1000);
   constexpr TimeDelta kEpsilon = TimeDelta::Millis(1);
-  absl::optional<TimeDelta> converted =
+  std::optional<TimeDelta> converted =
       CaptureClockOffsetUpdater::ConvertsToTimeDela(kNegativeQ32x32);
   EXPECT_GT(converted, kNegative - kEpsilon);
   EXPECT_LT(converted, kNegative + kEpsilon);
@@ -73,7 +73,7 @@
   EXPECT_LT(converted, kPositive + kEpsilon);
 
   EXPECT_FALSE(
-      CaptureClockOffsetUpdater::ConvertsToTimeDela(absl::nullopt).has_value());
+      CaptureClockOffsetUpdater::ConvertsToTimeDela(std::nullopt).has_value());
 }
 
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/corruption_detection_extension_unittest.cc b/modules/rtp_rtcp/source/corruption_detection_extension_unittest.cc
index be47e84..26d7006 100644
--- a/modules/rtp_rtcp/source/corruption_detection_extension_unittest.cc
+++ b/modules/rtp_rtcp/source/corruption_detection_extension_unittest.cc
@@ -12,8 +12,8 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "common_video/corruption_detection_message.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
@@ -25,7 +25,7 @@
 using ::testing::ElementsAre;
 
 TEST(CorruptionDetectionExtensionTest, ValueSizeIs1UnlessSamplesAreSpecified) {
-  const absl::optional<CorruptionDetectionMessage> kMessage =
+  const std::optional<CorruptionDetectionMessage> kMessage =
       CorruptionDetectionMessage::Builder()
           .WithSequenceIndex(0b0110'1111)
           .WithInterpretSequenceIndexAsMostSignificantBits(true)
@@ -33,53 +33,53 @@
           .WithSampleValues({})
           .Build();
 
-  ASSERT_NE(kMessage, absl::nullopt);
+  ASSERT_NE(kMessage, std::nullopt);
   EXPECT_EQ(CorruptionDetectionExtension::ValueSize(*kMessage), size_t{1});
 }
 
 TEST(CorruptionDetectionExtensionTest,
      GivenSamplesTheValueSizeIsTheSumOfTheNumberOfSamplesPlus3) {
   const double kSampleValues[] = {1.0, 2.0, 3.0, 4.0};
-  const absl::optional<CorruptionDetectionMessage> kMessage =
+  const std::optional<CorruptionDetectionMessage> kMessage =
       CorruptionDetectionMessage::Builder()
           .WithSampleValues(kSampleValues)
           .Build();
 
-  ASSERT_NE(kMessage, absl::nullopt);
+  ASSERT_NE(kMessage, std::nullopt);
   EXPECT_EQ(CorruptionDetectionExtension::ValueSize(*kMessage), size_t{7});
 }
 
 TEST(CorruptionDetectionExtensionTest,
      WritesMandatoryWhenEnoughMemoryIsAllocatedWithoutSamples) {
-  const absl::optional<CorruptionDetectionMessage> kMessage =
+  const std::optional<CorruptionDetectionMessage> kMessage =
       CorruptionDetectionMessage::Builder()
           .WithSequenceIndex(0b0110'1111)
           .WithInterpretSequenceIndexAsMostSignificantBits(true)
           .Build();
   uint8_t data[] = {0};
 
-  ASSERT_NE(kMessage, absl::nullopt);
+  ASSERT_NE(kMessage, std::nullopt);
   EXPECT_TRUE(CorruptionDetectionExtension::Write(data, *kMessage));
   EXPECT_THAT(data, ElementsAre(0b1110'1111));
 }
 
 TEST(CorruptionDetectionExtensionTest,
      FailsToWriteWhenTooMuchMemoryIsAllocatedWithoutSamples) {
-  const absl::optional<CorruptionDetectionMessage> kMessage =
+  const std::optional<CorruptionDetectionMessage> kMessage =
       CorruptionDetectionMessage::Builder()
           .WithSequenceIndex(0b0110'1111)
           .WithInterpretSequenceIndexAsMostSignificantBits(true)
           .Build();
   uint8_t data[] = {0, 0, 0};
 
-  ASSERT_NE(kMessage, absl::nullopt);
+  ASSERT_NE(kMessage, std::nullopt);
   EXPECT_FALSE(CorruptionDetectionExtension::Write(data, *kMessage));
 }
 
 TEST(CorruptionDetectionExtensionTest,
      FailsToWriteWhenTooMuchMemoryIsAllocatedWithSamples) {
   const double kSampleValues[] = {1.0};
-  const absl::optional<CorruptionDetectionMessage> kMessage =
+  const std::optional<CorruptionDetectionMessage> kMessage =
       CorruptionDetectionMessage::Builder()
           .WithSequenceIndex(0b0110'1111)
           .WithInterpretSequenceIndexAsMostSignificantBits(true)
@@ -88,14 +88,14 @@
           .Build();
   uint8_t data[] = {0, 0, 0, 0, 0};
 
-  ASSERT_NE(kMessage, absl::nullopt);
+  ASSERT_NE(kMessage, std::nullopt);
   EXPECT_FALSE(CorruptionDetectionExtension::Write(data, *kMessage));
 }
 
 TEST(CorruptionDetectionExtensionTest,
      WritesEverythingWhenEnoughMemoryIsAllocatedWithSamples) {
   const double kSampleValues[] = {1.0};
-  const absl::optional<CorruptionDetectionMessage> kMessage =
+  const std::optional<CorruptionDetectionMessage> kMessage =
       CorruptionDetectionMessage::Builder()
           .WithSequenceIndex(0b0110'1111)
           .WithInterpretSequenceIndexAsMostSignificantBits(true)
@@ -104,7 +104,7 @@
           .Build();
   uint8_t data[] = {0, 0, 0, 0};
 
-  ASSERT_NE(kMessage, absl::nullopt);
+  ASSERT_NE(kMessage, std::nullopt);
   EXPECT_TRUE(CorruptionDetectionExtension::Write(data, *kMessage));
   EXPECT_THAT(data, ElementsAre(0b1110'1111, 51, 0, 1));
 }
@@ -113,7 +113,7 @@
      WritesEverythingToExtensionWhenUpperBitsAreUsedForSequenceIndex) {
   const double kSampleValues[] = {1.0, 2.0, 3.0,  4.0,  5.0,  6.0, 7.0,
                                   8.0, 9.0, 10.0, 11.0, 12.0, 13.0};
-  const absl::optional<CorruptionDetectionMessage> kMessage =
+  const std::optional<CorruptionDetectionMessage> kMessage =
       CorruptionDetectionMessage::Builder()
           .WithSequenceIndex(0b0110'1111)
           .WithInterpretSequenceIndexAsMostSignificantBits(true)
@@ -124,7 +124,7 @@
           .Build();
   uint8_t data[16];
 
-  ASSERT_NE(kMessage, absl::nullopt);
+  ASSERT_NE(kMessage, std::nullopt);
   EXPECT_TRUE(CorruptionDetectionExtension::Write(data, *kMessage));
   EXPECT_THAT(data, ElementsAre(0b1110'1111, 220, 0b1110'1111, 1, 2, 3, 4, 5, 6,
                                 7, 8, 9, 10, 11, 12, 13));
@@ -134,7 +134,7 @@
      WritesEverythingToExtensionWhenLowerBitsAreUsedForSequenceIndex) {
   const double kSampleValues[] = {1.0, 2.0, 3.0,  4.0,  5.0,  6.0, 7.0,
                                   8.0, 9.0, 10.0, 11.0, 12.0, 13.0};
-  const absl::optional<CorruptionDetectionMessage> kMessage =
+  const std::optional<CorruptionDetectionMessage> kMessage =
       CorruptionDetectionMessage::Builder()
           .WithSequenceIndex(0b0110'1111)
           .WithInterpretSequenceIndexAsMostSignificantBits(false)
@@ -145,7 +145,7 @@
           .Build();
   uint8_t data[16];
 
-  ASSERT_NE(kMessage, absl::nullopt);
+  ASSERT_NE(kMessage, std::nullopt);
   EXPECT_TRUE(CorruptionDetectionExtension::Write(data, *kMessage));
   EXPECT_THAT(data, ElementsAre(0b0110'1111, 220, 0b1110'1111, 1, 2, 3, 4, 5, 6,
                                 7, 8, 9, 10, 11, 12, 13));
@@ -153,13 +153,13 @@
 
 TEST(CorruptionDetectionExtensionTest, TruncatesSampleValuesWhenWriting) {
   const double kSampleValues[] = {1.4, 2.5, 3.6};
-  const absl::optional<CorruptionDetectionMessage> kMessage =
+  const std::optional<CorruptionDetectionMessage> kMessage =
       CorruptionDetectionMessage::Builder()
           .WithSampleValues(kSampleValues)
           .Build();
   uint8_t data[6];
 
-  ASSERT_NE(kMessage, absl::nullopt);
+  ASSERT_NE(kMessage, std::nullopt);
   EXPECT_TRUE(CorruptionDetectionExtension::Write(data, *kMessage));
   EXPECT_THAT(data, ElementsAre(0, 0, 0, 1, 2, 3));
 }
diff --git a/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc b/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc
index 445b141..5566aee 100644
--- a/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc
+++ b/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc
@@ -62,7 +62,7 @@
     : ssrc_(config.local_media_ssrc),
       rtx_ssrc_(config.rtx_send_ssrc),
       flexfec_ssrc_(config.fec_generator ? config.fec_generator->FecSsrc()
-                                         : absl::nullopt),
+                                         : std::nullopt),
       populate_network2_timestamp_(config.populate_network2_timestamp),
       clock_(config.clock),
       packet_history_(packet_history),
diff --git a/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.h b/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.h
index d29a434..7ed0d6c 100644
--- a/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.h
+++ b/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.h
@@ -13,9 +13,9 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/call/transport.h"
 #include "api/rtc_event_log/rtc_event_log.h"
 #include "api/units/data_rate.h"
@@ -58,8 +58,8 @@
   void SendPacket(RtpPacketToSend* packet, const PacedPacketInfo& pacing_info)
       RTC_LOCKS_EXCLUDED(lock_);
   uint32_t Ssrc() const { return ssrc_; }
-  absl::optional<uint32_t> RtxSsrc() const { return rtx_ssrc_; }
-  absl::optional<uint32_t> FlexFecSsrc() const { return flexfec_ssrc_; }
+  std::optional<uint32_t> RtxSsrc() const { return rtx_ssrc_; }
+  std::optional<uint32_t> FlexFecSsrc() const { return flexfec_ssrc_; }
 
   void ProcessBitrateAndNotifyObservers() RTC_LOCKS_EXCLUDED(lock_);
   RtpSendRates GetSendRates() const RTC_LOCKS_EXCLUDED(lock_);
@@ -99,8 +99,8 @@
       RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
   const uint32_t ssrc_;
-  const absl::optional<uint32_t> rtx_ssrc_;
-  const absl::optional<uint32_t> flexfec_ssrc_;
+  const std::optional<uint32_t> rtx_ssrc_;
+  const std::optional<uint32_t> flexfec_ssrc_;
   const bool populate_network2_timestamp_;
   Clock* const clock_;
   RtpPacketHistory* const packet_history_;
diff --git a/modules/rtp_rtcp/source/flexfec_sender.cc b/modules/rtp_rtcp/source/flexfec_sender.cc
index ab99d28..0f3c661 100644
--- a/modules/rtp_rtcp/source/flexfec_sender.cc
+++ b/modules/rtp_rtcp/source/flexfec_sender.cc
@@ -196,7 +196,7 @@
       .value_or(DataRate::Zero());
 }
 
-absl::optional<RtpState> FlexfecSender::GetRtpState() {
+std::optional<RtpState> FlexfecSender::GetRtpState() {
   RtpState rtp_state;
   rtp_state.sequence_number = seq_num_;
   rtp_state.start_timestamp = timestamp_offset_;
diff --git a/modules/rtp_rtcp/source/frame_object.cc b/modules/rtp_rtcp/source/frame_object.cc
index 23abe3a..5fa8225 100644
--- a/modules/rtp_rtcp/source/frame_object.cc
+++ b/modules/rtp_rtcp/source/frame_object.cc
@@ -34,7 +34,7 @@
     VideoRotation rotation,
     VideoContentType content_type,
     const RTPVideoHeader& video_header,
-    const absl::optional<webrtc::ColorSpace>& color_space,
+    const std::optional<webrtc::ColorSpace>& color_space,
     RtpPacketInfos packet_infos,
     rtc::scoped_refptr<EncodedImageBuffer> image_buffer)
     : image_buffer_(image_buffer),
diff --git a/modules/rtp_rtcp/source/frame_object.h b/modules/rtp_rtcp/source/frame_object.h
index 481c561..4c57b69 100644
--- a/modules/rtp_rtcp/source/frame_object.h
+++ b/modules/rtp_rtcp/source/frame_object.h
@@ -11,9 +11,9 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_FRAME_OBJECT_H_
 #define MODULES_RTP_RTCP_SOURCE_FRAME_OBJECT_H_
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/video/encoded_frame.h"
 #include "api/video/video_frame_metadata.h"
 
@@ -35,7 +35,7 @@
                  VideoRotation rotation,
                  VideoContentType content_type,
                  const RTPVideoHeader& video_header,
-                 const absl::optional<webrtc::ColorSpace>& color_space,
+                 const std::optional<webrtc::ColorSpace>& color_space,
                  RtpPacketInfos packet_infos,
                  rtc::scoped_refptr<EncodedImageBuffer> image_buffer);
 
diff --git a/modules/rtp_rtcp/source/packet_sequencer.cc b/modules/rtp_rtcp/source/packet_sequencer.cc
index f640351..4d1ac6c 100644
--- a/modules/rtp_rtcp/source/packet_sequencer.cc
+++ b/modules/rtp_rtcp/source/packet_sequencer.cc
@@ -24,7 +24,7 @@
 }  // namespace
 
 PacketSequencer::PacketSequencer(uint32_t media_ssrc,
-                                 absl::optional<uint32_t> rtx_ssrc,
+                                 std::optional<uint32_t> rtx_ssrc,
                                  bool require_marker_before_media_padding,
                                  Clock* clock)
     : media_ssrc_(media_ssrc),
diff --git a/modules/rtp_rtcp/source/packet_sequencer.h b/modules/rtp_rtcp/source/packet_sequencer.h
index 0ae069d..a6e1ba7 100644
--- a/modules/rtp_rtcp/source/packet_sequencer.h
+++ b/modules/rtp_rtcp/source/packet_sequencer.h
@@ -28,7 +28,7 @@
   // last packets of a video frame).
   // Packets with unknown SSRCs will be ignored.
   PacketSequencer(uint32_t media_ssrc,
-                  absl::optional<uint32_t> rtx_ssrc,
+                  std::optional<uint32_t> rtx_ssrc,
                   bool require_marker_before_media_padding,
                   Clock* clock);
 
@@ -58,7 +58,7 @@
   void PopulatePaddingFields(RtpPacketToSend& packet);
 
   const uint32_t media_ssrc_;
-  const absl::optional<uint32_t> rtx_ssrc_;
+  const std::optional<uint32_t> rtx_ssrc_;
   const bool require_marker_before_media_padding_;
   Clock* const clock_;
 
diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.cc b/modules/rtp_rtcp/source/receive_statistics_impl.cc
index 1ca7795..abdd76c 100644
--- a/modules/rtp_rtcp/source/receive_statistics_impl.cc
+++ b/modules/rtp_rtcp/source/receive_statistics_impl.cc
@@ -72,7 +72,7 @@
     --cumulative_loss_;
 
     uint16_t expected_sequence_number = *received_seq_out_of_order_ + 1;
-    received_seq_out_of_order_ = absl::nullopt;
+    received_seq_out_of_order_ = std::nullopt;
     if (packet.SequenceNumber() == expected_sequence_number) {
       // Ignore sequence number gap caused by stream restart for packet loss
       // calculation, by setting received_seq_max_ to the sequence number just
@@ -283,13 +283,13 @@
   last_report_seq_max_ = received_seq_max_;
 }
 
-absl::optional<int> StreamStatisticianImpl::GetFractionLostInPercent() const {
+std::optional<int> StreamStatisticianImpl::GetFractionLostInPercent() const {
   if (!ReceivedRtpPacket()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   int64_t expected_packets = 1 + received_seq_max_ - received_seq_first_;
   if (expected_packets <= 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (cumulative_loss_ <= 0) {
     return 0;
diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.h b/modules/rtp_rtcp/source/receive_statistics_impl.h
index ccac2d5..a6e2d8b 100644
--- a/modules/rtp_rtcp/source/receive_statistics_impl.h
+++ b/modules/rtp_rtcp/source/receive_statistics_impl.h
@@ -14,10 +14,10 @@
 #include <algorithm>
 #include <functional>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
 #include "modules/rtp_rtcp/include/receive_statistics.h"
@@ -51,7 +51,7 @@
 
   // Implements StreamStatistician
   RtpReceiveStats GetStats() const override;
-  absl::optional<int> GetFractionLostInPercent() const override;
+  std::optional<int> GetFractionLostInPercent() const override;
   StreamDataCounters GetReceiveStreamDataCounters() const override;
   uint32_t BitrateReceived() const override;
 
@@ -96,14 +96,14 @@
   // senders, in particular, our own loss-based bandwidth estimator.
   int32_t cumulative_loss_rtcp_offset_;
 
-  absl::optional<Timestamp> last_receive_time_;
+  std::optional<Timestamp> last_receive_time_;
   uint32_t last_received_timestamp_;
   RtpSequenceNumberUnwrapper seq_unwrapper_;
   int64_t received_seq_first_;
   int64_t received_seq_max_;
   // Assume that the other side restarted when there are two sequential packets
   // with large jump from received_seq_max_.
-  absl::optional<uint16_t> received_seq_out_of_order_;
+  std::optional<uint16_t> received_seq_out_of_order_;
 
   // Current counter values.
   StreamDataCounters receive_counters_;
@@ -129,7 +129,7 @@
     MutexLock lock(&stream_lock_);
     return impl_.GetStats();
   }
-  absl::optional<int> GetFractionLostInPercent() const override {
+  std::optional<int> GetFractionLostInPercent() const override {
     MutexLock lock(&stream_lock_);
     return impl_.GetFractionLostInPercent();
   }
diff --git a/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc b/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc
index d70882c..21ef24a 100644
--- a/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc
+++ b/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc
@@ -97,11 +97,11 @@
   return receiver_capture;
 }
 
-absl::optional<int64_t>
+std::optional<int64_t>
 RemoteNtpTimeEstimator::EstimateRemoteToLocalClockOffset() {
   if (ntp_clocks_offset_estimator_.GetNumberOfSamplesStored() <
       kMinimumNumberOfSamples) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ntp_clocks_offset_estimator_.GetFilteredValue();
 }
diff --git a/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc b/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc
index b356da7..e9e8ce9 100644
--- a/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc
+++ b/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc
@@ -10,7 +10,8 @@
 
 #include "modules/rtp_rtcp/include/remote_ntp_time_estimator.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/rtp_rtcp/source/ntp_time_util.h"
 #include "system_wrappers/include/clock.h"
 #include "system_wrappers/include/ntp_time.h"
@@ -78,7 +79,7 @@
   // Local peer needs at least 2 RTCP SR to calculate the capture time.
   const int64_t kNotEnoughRtcpSr = -1;
   EXPECT_EQ(kNotEnoughRtcpSr, estimator_.Estimate(rtp_timestamp));
-  EXPECT_EQ(estimator_.EstimateRemoteToLocalClockOffset(), absl::nullopt);
+  EXPECT_EQ(estimator_.EstimateRemoteToLocalClockOffset(), std::nullopt);
 
   AdvanceTime(TimeDelta::Millis(800));
   // Remote sends second RTCP SR.
diff --git a/modules/rtp_rtcp/source/rtcp_packet/extended_reports.cc b/modules/rtp_rtcp/source/rtcp_packet/extended_reports.cc
index ce57bd5..84a3a53 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/extended_reports.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/extended_reports.cc
@@ -59,7 +59,7 @@
   SetSenderSsrc(ByteReader<uint32_t>::ReadBigEndian(packet.payload()));
   rrtr_block_.reset();
   dlrr_block_.ClearItems();
-  target_bitrate_ = absl::nullopt;
+  target_bitrate_ = std::nullopt;
 
   const uint8_t* current_block = packet.payload() + kXrBaseLength;
   const uint8_t* const packet_end =
diff --git a/modules/rtp_rtcp/source/rtcp_packet/extended_reports.h b/modules/rtp_rtcp/source/rtcp_packet/extended_reports.h
index 6c804bb..d71e759 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/extended_reports.h
+++ b/modules/rtp_rtcp/source/rtcp_packet/extended_reports.h
@@ -11,9 +11,9 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_EXTENDED_REPORTS_H_
 #define MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_EXTENDED_REPORTS_H_
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "modules/rtp_rtcp/source/rtcp_packet.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/rrtr.h"
@@ -40,9 +40,9 @@
   bool AddDlrrItem(const ReceiveTimeInfo& time_info);
   void SetTargetBitrate(const TargetBitrate& target_bitrate);
 
-  const absl::optional<Rrtr>& rrtr() const { return rrtr_block_; }
+  const std::optional<Rrtr>& rrtr() const { return rrtr_block_; }
   const Dlrr& dlrr() const { return dlrr_block_; }
-  const absl::optional<TargetBitrate>& target_bitrate() const {
+  const std::optional<TargetBitrate>& target_bitrate() const {
     return target_bitrate_;
   }
 
@@ -64,9 +64,9 @@
   void ParseDlrrBlock(const uint8_t* block, uint16_t block_length);
   void ParseTargetBitrateBlock(const uint8_t* block, uint16_t block_length);
 
-  absl::optional<Rrtr> rrtr_block_;
+  std::optional<Rrtr> rrtr_block_;
   Dlrr dlrr_block_;  // Dlrr without items treated same as no dlrr block.
-  absl::optional<TargetBitrate> target_bitrate_;
+  std::optional<TargetBitrate> target_bitrate_;
 };
 }  // namespace rtcp
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtcp_packet/target_bitrate_unittest.cc b/modules/rtp_rtcp/source/rtcp_packet/target_bitrate_unittest.cc
index b16bb5b..0073e0e 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/target_bitrate_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/target_bitrate_unittest.cc
@@ -67,7 +67,7 @@
   rtcp::ExtendedReports xr;
   EXPECT_TRUE(ParseSinglePacket(kRtcpPacket, &xr));
   EXPECT_EQ(kSsrc, xr.sender_ssrc());
-  const absl::optional<TargetBitrate>& target_bitrate = xr.target_bitrate();
+  const std::optional<TargetBitrate>& target_bitrate = xr.target_bitrate();
   ASSERT_TRUE(static_cast<bool>(target_bitrate));
   CheckBitrateItems(target_bitrate->GetTargetBitrates());
 }
diff --git a/modules/rtp_rtcp/source/rtcp_packet/transport_feedback_unittest.cc b/modules/rtp_rtcp/source/rtcp_packet/transport_feedback_unittest.cc
index 92ca464..264d613 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/transport_feedback_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/transport_feedback_unittest.cc
@@ -12,9 +12,9 @@
 
 #include <limits>
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -170,7 +170,7 @@
   std::vector<TimeDelta> expected_deltas_;
   size_t expected_size_;
   TimeDelta default_delta_;
-  absl::optional<TransportFeedback> feedback_;
+  std::optional<TransportFeedback> feedback_;
   rtc::Buffer serialized_;
   bool include_timestamps_;
 };
diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc
index 983545a..14653cb 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -101,7 +101,7 @@
     ssrcs_.push_back(*config.rtx_send_ssrc);
   }
   if (config.fec_generator) {
-    absl::optional<uint32_t> flexfec_ssrc = config.fec_generator->FecSsrc();
+    std::optional<uint32_t> flexfec_ssrc = config.fec_generator->FecSsrc();
     if (flexfec_ssrc) {
       ssrcs_.push_back(*flexfec_ssrc);
     }
@@ -131,12 +131,12 @@
   uint32_t remote_ssrc = 0;
   std::vector<uint16_t> nack_sequence_numbers;
   std::vector<ReportBlockData> report_block_datas;
-  absl::optional<TimeDelta> rtt;
+  std::optional<TimeDelta> rtt;
   uint32_t receiver_estimated_max_bitrate_bps = 0;
   std::unique_ptr<rtcp::TransportFeedback> transport_feedback;
-  absl::optional<rtcp::CongestionControlFeedback> congestion_control_feedback;
-  absl::optional<VideoBitrateAllocation> target_bitrate_allocation;
-  absl::optional<NetworkStateEstimate> network_state_estimate;
+  std::optional<rtcp::CongestionControlFeedback> congestion_control_feedback;
+  std::optional<VideoBitrateAllocation> target_bitrate_allocation;
+  std::optional<NetworkStateEstimate> network_state_estimate;
   std::unique_ptr<rtcp::LossNotification> loss_notification;
 };
 
@@ -258,20 +258,20 @@
   ++num_rtts_;
 }
 
-absl::optional<TimeDelta> RTCPReceiver::AverageRtt() const {
+std::optional<TimeDelta> RTCPReceiver::AverageRtt() const {
   MutexLock lock(&rtcp_receiver_lock_);
   auto it = rtts_.find(remote_ssrc_);
   if (it == rtts_.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return it->second.average_rtt();
 }
 
-absl::optional<TimeDelta> RTCPReceiver::LastRtt() const {
+std::optional<TimeDelta> RTCPReceiver::LastRtt() const {
   MutexLock lock(&rtcp_receiver_lock_);
   auto it = rtts_.find(remote_ssrc_);
   if (it == rtts_.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return it->second.last_rtt();
 }
@@ -290,19 +290,18 @@
   xr_rrtr_status_ = enabled;
 }
 
-absl::optional<TimeDelta> RTCPReceiver::GetAndResetXrRrRtt() {
+std::optional<TimeDelta> RTCPReceiver::GetAndResetXrRrRtt() {
   MutexLock lock(&rtcp_receiver_lock_);
-  absl::optional<TimeDelta> rtt = xr_rr_rtt_;
-  xr_rr_rtt_ = absl::nullopt;
+  std::optional<TimeDelta> rtt = xr_rr_rtt_;
+  xr_rr_rtt_ = std::nullopt;
   return rtt;
 }
 
 // Called regularly (1/sec) on the worker thread to do rtt  calculations.
-absl::optional<TimeDelta> RTCPReceiver::OnPeriodicRttUpdate(
-    Timestamp newer_than,
-    bool sending) {
+std::optional<TimeDelta> RTCPReceiver::OnPeriodicRttUpdate(Timestamp newer_than,
+                                                           bool sending) {
   // Running on the worker thread (same as construction thread).
-  absl::optional<TimeDelta> rtt;
+  std::optional<TimeDelta> rtt;
 
   if (sending) {
     // Check if we've received a report block within the last kRttUpdateInterval
@@ -336,11 +335,11 @@
   return rtt;
 }
 
-absl::optional<RtpRtcpInterface::SenderReportStats>
+std::optional<RtpRtcpInterface::SenderReportStats>
 RTCPReceiver::GetSenderReportStats() const {
   MutexLock lock(&rtcp_receiver_lock_);
   if (!remote_sender_.last_arrival_timestamp.Valid()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return remote_sender_;
@@ -799,7 +798,7 @@
     received_rrtrs_.erase(it->second);
     received_rrtrs_ssrc_it_.erase(it);
   }
-  xr_rr_rtt_ = absl::nullopt;
+  xr_rr_rtt_ = std::nullopt;
   return true;
 }
 
diff --git a/modules/rtp_rtcp/source/rtcp_receiver.h b/modules/rtp_rtcp/source/rtcp_receiver.h
index 6bfd1e1..361822a 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver.h
+++ b/modules/rtp_rtcp/source/rtcp_receiver.h
@@ -13,10 +13,10 @@
 
 #include <list>
 #include <map>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/sequence_checker.h"
 #include "api/units/time_delta.h"
@@ -75,7 +75,7 @@
     }
     void Invalidate() { round_trip_time_.reset(); }
     // https://www.w3.org/TR/webrtc-stats/#dom-rtcremoteoutboundrtpstreamstats-roundtriptime
-    absl::optional<TimeDelta> round_trip_time() const {
+    std::optional<TimeDelta> round_trip_time() const {
       return round_trip_time_;
     }
     // https://www.w3.org/TR/webrtc-stats/#dom-rtcremoteoutboundrtpstreamstats-totalroundtriptime
@@ -86,7 +86,7 @@
     }
 
    private:
-    absl::optional<TimeDelta> round_trip_time_;
+    std::optional<TimeDelta> round_trip_time_;
     TimeDelta total_round_trip_time_ = TimeDelta::Zero();
     int round_trip_time_measurements_ = 0;
   };
@@ -112,24 +112,24 @@
   bool receiver_only() const { return receiver_only_; }
 
   // Returns stats based on the received RTCP Sender Reports.
-  absl::optional<RtpRtcpInterface::SenderReportStats> GetSenderReportStats()
+  std::optional<RtpRtcpInterface::SenderReportStats> GetSenderReportStats()
       const;
 
   std::vector<rtcp::ReceiveTimeInfo> ConsumeReceivedXrReferenceTimeInfo();
 
-  absl::optional<TimeDelta> AverageRtt() const;
-  absl::optional<TimeDelta> LastRtt() const;
+  std::optional<TimeDelta> AverageRtt() const;
+  std::optional<TimeDelta> LastRtt() const;
 
   // Returns non-sender RTT metrics for the remote SSRC.
   NonSenderRttStats GetNonSenderRTT() const;
 
   void SetNonSenderRttMeasurement(bool enabled);
-  absl::optional<TimeDelta> GetAndResetXrRrRtt();
+  std::optional<TimeDelta> GetAndResetXrRrRtt();
 
   // Called once per second on the worker thread to do rtt calculations.
   // Returns an optional rtt value if one is available.
-  absl::optional<TimeDelta> OnPeriodicRttUpdate(Timestamp newer_than,
-                                                bool sending);
+  std::optional<TimeDelta> OnPeriodicRttUpdate(Timestamp newer_than,
+                                               bool sending);
 
   // A snapshot of Report Blocks with additional data of interest to statistics.
   // Within this list, the source SSRC is unique and ReportBlockData represents
@@ -382,7 +382,7 @@
 
   // Estimated rtt, nullopt when there is no valid estimate.
   bool xr_rrtr_status_ RTC_GUARDED_BY(rtcp_receiver_lock_);
-  absl::optional<TimeDelta> xr_rr_rtt_;
+  std::optional<TimeDelta> xr_rr_rtt_;
 
   Timestamp oldest_tmmbr_info_ RTC_GUARDED_BY(rtcp_receiver_lock_);
   // Mapped by remote ssrc.
diff --git a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
index 2194ec2..7b8a15f 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
@@ -237,7 +237,7 @@
   const uint32_t kDelayNtp = 0x4321;
   const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp);
 
-  EXPECT_EQ(receiver.LastRtt(), absl::nullopt);
+  EXPECT_EQ(receiver.LastRtt(), std::nullopt);
 
   uint32_t sent_ntp = CompactNtp(mocks.clock.CurrentNtpTime());
   mocks.clock.AdvanceTime(kRtt + kDelay);
@@ -266,7 +266,7 @@
   const uint32_t kDelayNtp = 0x4321;
   const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp);
 
-  EXPECT_EQ(receiver.LastRtt(), absl::nullopt);
+  EXPECT_EQ(receiver.LastRtt(), std::nullopt);
 
   uint32_t sent_ntp = CompactNtp(mocks.clock.CurrentNtpTime());
   mocks.clock.AdvanceTime(kRtt + kDelay);
@@ -565,8 +565,8 @@
   receiver.SetRemoteSSRC(kSenderSsrc);
 
   // No report block received.
-  EXPECT_EQ(receiver.LastRtt(), absl::nullopt);
-  EXPECT_EQ(receiver.AverageRtt(), absl::nullopt);
+  EXPECT_EQ(receiver.LastRtt(), std::nullopt);
+  EXPECT_EQ(receiver.AverageRtt(), std::nullopt);
 
   rtcp::ReportBlock rb;
   rb.SetMediaSsrc(kReceiverMainSsrc);
@@ -584,8 +584,8 @@
   receiver.IncomingPacket(rr.Build());
 
   EXPECT_EQ(receiver.LastReceivedReportBlockMs(), now.ms());
-  EXPECT_NE(receiver.LastRtt(), absl::nullopt);
-  EXPECT_NE(receiver.AverageRtt(), absl::nullopt);
+  EXPECT_NE(receiver.LastRtt(), std::nullopt);
+  EXPECT_NE(receiver.AverageRtt(), std::nullopt);
 }
 
 // App packets are ignored.
diff --git a/modules/rtp_rtcp/source/rtcp_sender.cc b/modules/rtp_rtcp/source/rtcp_sender.cc
index 7ec3b17..cea49e4 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -14,10 +14,10 @@
 
 #include <algorithm>  // std::min
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/rtc_event_log/rtc_event_log.h"
 #include "api/rtp_headers.h"
 #include "api/units/data_rate.h"
@@ -197,7 +197,7 @@
   MutexLock lock(&mutex_rtcp_sender_);
 
   if (new_method == RtcpMode::kOff) {
-    next_time_to_send_rtcp_ = absl::nullopt;
+    next_time_to_send_rtcp_ = std::nullopt;
   } else if (method_ == RtcpMode::kOff) {
     // When switching on, reschedule the next packet
     SetNextRtcpSendEvaluationDuration(report_interval_ / 2);
@@ -234,7 +234,7 @@
       event_log_->Log(std::make_unique<RtcEventRtcpPacketOutgoing>(packet));
     }
   };
-  absl::optional<PacketSender> sender;
+  std::optional<PacketSender> sender;
   {
     MutexLock lock(&mutex_rtcp_sender_);
 
@@ -302,8 +302,8 @@
 }
 
 void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp,
-                                absl::optional<Timestamp> capture_time,
-                                absl::optional<int8_t> payload_type) {
+                                std::optional<Timestamp> capture_time,
+                                std::optional<int8_t> payload_type) {
   MutexLock lock(&mutex_rtcp_sender_);
   // For compatibility with clients who don't set payload type correctly on all
   // calls.
@@ -594,7 +594,7 @@
       }
     }
   };
-  absl::optional<PacketSender> sender;
+  std::optional<PacketSender> sender;
   {
     MutexLock lock(&mutex_rtcp_sender_);
     sender.emplace(callback, max_packet_size_);
@@ -609,7 +609,7 @@
   return error_code;
 }
 
-absl::optional<int32_t> RTCPSender::ComputeCompoundRTCPPacket(
+std::optional<int32_t> RTCPSender::ComputeCompoundRTCPPacket(
     const FeedbackState& feedback_state,
     RTCPPacketType packet_type,
     int32_t nack_size,
@@ -684,7 +684,7 @@
   }
 
   RTC_DCHECK(AllVolatileFlagsConsumed());
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 TimeDelta RTCPSender::ComputeTimeUntilNextReport(DataRate send_bitrate) {
@@ -831,7 +831,7 @@
   // Check if this allocation is first ever, or has a different set of
   // spatial/temporal layers signaled and enabled, if so trigger an rtcp report
   // as soon as possible.
-  absl::optional<VideoBitrateAllocation> new_bitrate =
+  std::optional<VideoBitrateAllocation> new_bitrate =
       CheckAndUpdateLayerStructure(bitrate);
   if (new_bitrate) {
     video_bitrate_allocation_ = *new_bitrate;
@@ -847,9 +847,9 @@
   SetFlag(kRtcpAnyExtendedReports, true);
 }
 
-absl::optional<VideoBitrateAllocation> RTCPSender::CheckAndUpdateLayerStructure(
+std::optional<VideoBitrateAllocation> RTCPSender::CheckAndUpdateLayerStructure(
     const VideoBitrateAllocation& bitrate) const {
-  absl::optional<VideoBitrateAllocation> updated_bitrate;
+  std::optional<VideoBitrateAllocation> updated_bitrate;
   for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
     for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
       if (!updated_bitrate &&
diff --git a/modules/rtp_rtcp/source/rtcp_sender.h b/modules/rtp_rtcp/source/rtcp_sender.h
index fe2ec9b..1274aea 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.h
+++ b/modules/rtp_rtcp/source/rtcp_sender.h
@@ -13,12 +13,12 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/call/transport.h"
 #include "api/units/data_rate.h"
 #include "api/units/time_delta.h"
@@ -79,7 +79,7 @@
     std::function<void(TimeDelta)> schedule_next_rtcp_send_evaluation_function;
 
     RtcEventLog* event_log = nullptr;
-    absl::optional<TimeDelta> rtcp_report_interval;
+    std::optional<TimeDelta> rtcp_report_interval;
     ReceiveStatisticsProvider* receive_statistics = nullptr;
     RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer = nullptr;
   };
@@ -126,8 +126,8 @@
       RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_);
 
   void SetLastRtpTime(uint32_t rtp_timestamp,
-                      absl::optional<Timestamp> capture_time,
-                      absl::optional<int8_t> payload_type)
+                      std::optional<Timestamp> capture_time,
+                      std::optional<int8_t> payload_type)
       RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_);
 
   void SetRtpClockRate(int8_t payload_type, int rtp_clock_rate_hz)
@@ -185,7 +185,7 @@
   class RtcpContext;
   class PacketSender;
 
-  absl::optional<int32_t> ComputeCompoundRTCPPacket(
+  std::optional<int32_t> ComputeCompoundRTCPPacket(
       const FeedbackState& feedback_state,
       RTCPPacketType packet_type,
       int32_t nack_size,
@@ -256,12 +256,12 @@
   mutable Mutex mutex_rtcp_sender_;
   bool sending_ RTC_GUARDED_BY(mutex_rtcp_sender_);
 
-  absl::optional<Timestamp> next_time_to_send_rtcp_
+  std::optional<Timestamp> next_time_to_send_rtcp_
       RTC_GUARDED_BY(mutex_rtcp_sender_);
 
   uint32_t timestamp_offset_ RTC_GUARDED_BY(mutex_rtcp_sender_);
   uint32_t last_rtp_timestamp_ RTC_GUARDED_BY(mutex_rtcp_sender_);
-  absl::optional<Timestamp> last_frame_capture_time_
+  std::optional<Timestamp> last_frame_capture_time_
       RTC_GUARDED_BY(mutex_rtcp_sender_);
   // SSRC that we receive on our RTP channel
   uint32_t remote_ssrc_ RTC_GUARDED_BY(mutex_rtcp_sender_);
@@ -303,7 +303,7 @@
   std::map<int8_t, int> rtp_clock_rates_khz_ RTC_GUARDED_BY(mutex_rtcp_sender_);
   int8_t last_payload_type_ RTC_GUARDED_BY(mutex_rtcp_sender_);
 
-  absl::optional<VideoBitrateAllocation> CheckAndUpdateLayerStructure(
+  std::optional<VideoBitrateAllocation> CheckAndUpdateLayerStructure(
       const VideoBitrateAllocation& bitrate) const
       RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_);
 
diff --git a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
index f58098b..023f923 100644
--- a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
@@ -720,7 +720,7 @@
   EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport));
   EXPECT_EQ(1, parser()->xr()->num_packets());
   EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
-  const absl::optional<rtcp::TargetBitrate>& target_bitrate =
+  const std::optional<rtcp::TargetBitrate>& target_bitrate =
       parser()->xr()->target_bitrate();
   ASSERT_TRUE(target_bitrate);
   const std::vector<rtcp::TargetBitrate::BitrateItem>& bitrates =
@@ -786,7 +786,7 @@
   allocation.SetBitrate(1, 0, 200000);
   rtcp_sender->SetVideoBitrateAllocation(allocation);
   EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport));
-  absl::optional<rtcp::TargetBitrate> target_bitrate =
+  std::optional<rtcp::TargetBitrate> target_bitrate =
       parser()->xr()->target_bitrate();
   ASSERT_TRUE(target_bitrate);
   std::vector<rtcp::TargetBitrate::BitrateItem> bitrates =
diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
index 9ada3cdc..f07d765 100644
--- a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
+++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
@@ -11,11 +11,11 @@
 #include "modules/rtp_rtcp/source/rtcp_transceiver_impl.h"
 
 #include <algorithm>
+#include <optional>
 #include <utility>
 
 #include "absl/algorithm/container.h"
 #include "absl/memory/memory.h"
-#include "absl/types/optional.h"
 #include "api/video/video_bitrate_allocation.h"
 #include "modules/rtp_rtcp/include/receive_statistics.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@@ -68,7 +68,7 @@
 
 struct RtcpTransceiverImpl::RemoteSenderState {
   uint8_t fir_sequence_number = 0;
-  absl::optional<SenderReportTimes> last_received_sender_report;
+  std::optional<SenderReportTimes> last_received_sender_report;
   std::vector<MediaReceiverRtcpObserver*> observers;
 };
 
@@ -234,7 +234,7 @@
   // immideately on large bitrate change when there is one RtcpTransceiver per
   // rtp transport.
   if (send_now) {
-    absl::optional<rtcp::Remb> remb;
+    std::optional<rtcp::Remb> remb;
     remb.swap(remb_);
     SendImmediateFeedback(*remb);
     remb.swap(remb_);
@@ -366,7 +366,7 @@
       Timestamp::Millis(now_ntp.ToMs() - rtc::kNtpJan1970Millisecs);
 
   for (const rtcp::ReportBlock& block : rtcp_report_blocks) {
-    absl::optional<TimeDelta> rtt;
+    std::optional<TimeDelta> rtt;
     if (block.last_sr() != 0) {
       rtt = CompactNtpRttToTimeDelta(
           receive_time_ntp - block.delay_since_last_sr() - block.last_sr());
@@ -736,7 +736,7 @@
                                                PacketSender& sender) {
   RTC_DCHECK(sender.IsEmpty());
   ReservedBytes reserved = {.per_packet = reserved_bytes};
-  absl::optional<rtcp::Sdes> sdes;
+  std::optional<rtcp::Sdes> sdes;
   if (!config_.cname.empty()) {
     sdes.emplace();
     bool added = sdes->AddCName(config_.feedback_ssrc, config_.cname);
@@ -747,7 +747,7 @@
   if (remb_.has_value()) {
     reserved.per_packet += remb_->BlockLength();
   }
-  absl::optional<rtcp::ExtendedReports> xr_with_dlrr;
+  std::optional<rtcp::ExtendedReports> xr_with_dlrr;
   if (!received_rrtrs_.empty()) {
     RTC_DCHECK(config_.reply_to_non_sender_rtt_measurement);
     xr_with_dlrr.emplace();
diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl.h b/modules/rtp_rtcp/source/rtcp_transceiver_impl.h
index c73b292..d4f12dc 100644
--- a/modules/rtp_rtcp/source/rtcp_transceiver_impl.h
+++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl.h
@@ -13,10 +13,10 @@
 
 #include <list>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/units/timestamp.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
@@ -154,7 +154,7 @@
   std::function<void(rtc::ArrayView<const uint8_t>)> rtcp_transport_;
 
   bool ready_to_send_;
-  absl::optional<rtcp::Remb> remb_;
+  std::optional<rtcp::Remb> remb_;
   // TODO(bugs.webrtc.org/8239): Remove entries from remote_senders_ that are no
   // longer needed.
   flat_map<uint32_t, RemoteSenderState> remote_senders_;
diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc b/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc
index 8bd3652..988bccc 100644
--- a/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc
@@ -221,7 +221,7 @@
   config.rtcp_transport = transport.AsStdFunction();
   config.initial_report_delay = TimeDelta::Millis(10);
   config.task_queue = queue.get();
-  absl::optional<RtcpTransceiverImpl> rtcp_transceiver;
+  std::optional<RtcpTransceiverImpl> rtcp_transceiver;
 
   Timestamp started = CurrentTime();
   queue->PostTask([&] { rtcp_transceiver.emplace(config); });
@@ -248,7 +248,7 @@
   config.initial_report_delay = TimeDelta::Zero();
   config.report_period = kReportPeriod;
   config.task_queue = queue.get();
-  absl::optional<RtcpTransceiverImpl> rtcp_transceiver;
+  std::optional<RtcpTransceiverImpl> rtcp_transceiver;
   Timestamp time_just_before_1st_packet = Timestamp::MinusInfinity();
   queue->PostTask([&] {
     // Because initial_report_delay_ms is set to 0, time_just_before_the_packet
@@ -283,7 +283,7 @@
   config.initial_report_delay = TimeDelta::Zero();
   config.report_period = kReportPeriod;
   config.task_queue = queue.get();
-  absl::optional<RtcpTransceiverImpl> rtcp_transceiver;
+  std::optional<RtcpTransceiverImpl> rtcp_transceiver;
   queue->PostTask([&] { rtcp_transceiver.emplace(config); });
 
   // Wait for the first packet.
@@ -365,7 +365,7 @@
   config.initial_ready_to_send = false;
   config.rtcp_transport = transport.AsStdFunction();
   config.task_queue = queue.get();
-  absl::optional<RtcpTransceiverImpl> rtcp_transceiver;
+  std::optional<RtcpTransceiverImpl> rtcp_transceiver;
   rtcp_transceiver.emplace(config);
 
   queue->PostTask([&] { rtcp_transceiver->SetReadyToSend(true); });
diff --git a/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.cc b/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.cc
index 1a56efd..e1b05b0 100644
--- a/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.cc
+++ b/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.cc
@@ -199,7 +199,7 @@
     ReadFrameChains();
 
   if (structure_->resolutions.empty()) {
-    descriptor_->resolution = absl::nullopt;
+    descriptor_->resolution = std::nullopt;
   } else {
     // Format guarantees that if there were resolutions in the last structure,
     // then each spatial layer got one.
diff --git a/modules/rtp_rtcp/source/rtp_format.cc b/modules/rtp_rtcp/source/rtp_format.cc
index f4e0514..dffa50e 100644
--- a/modules/rtp_rtcp/source/rtp_format.cc
+++ b/modules/rtp_rtcp/source/rtp_format.cc
@@ -29,7 +29,7 @@
 namespace webrtc {
 
 std::unique_ptr<RtpPacketizer> RtpPacketizer::Create(
-    absl::optional<VideoCodecType> type,
+    std::optional<VideoCodecType> type,
     rtc::ArrayView<const uint8_t> payload,
     PayloadSizeLimits limits,
     // Codec-specific details.
diff --git a/modules/rtp_rtcp/source/rtp_format.h b/modules/rtp_rtcp/source/rtp_format.h
index 91b0367..097481d 100644
--- a/modules/rtp_rtcp/source/rtp_format.h
+++ b/modules/rtp_rtcp/source/rtp_format.h
@@ -14,9 +14,9 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/rtp_rtcp/source/rtp_video_header.h"
 
@@ -36,7 +36,7 @@
 
   // If type is not set, returns a raw packetizer.
   static std::unique_ptr<RtpPacketizer> Create(
-      absl::optional<VideoCodecType> type,
+      std::optional<VideoCodecType> type,
       rtc::ArrayView<const uint8_t> payload,
       PayloadSizeLimits limits,
       // Codec-specific details.
diff --git a/modules/rtp_rtcp/source/rtp_format_h264.cc b/modules/rtp_rtcp/source/rtp_format_h264.cc
index 7e11add..917cb1b 100644
--- a/modules/rtp_rtcp/source/rtp_format_h264.cc
+++ b/modules/rtp_rtcp/source/rtp_format_h264.cc
@@ -16,11 +16,11 @@
 #include <cstdint>
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "common_video/h264/h264_common.h"
 #include "common_video/h264/pps_parser.h"
diff --git a/modules/rtp_rtcp/source/rtp_format_video_generic.cc b/modules/rtp_rtcp/source/rtp_format_video_generic.cc
index f5c7f2e..d91e6b4 100644
--- a/modules/rtp_rtcp/source/rtp_format_video_generic.cc
+++ b/modules/rtp_rtcp/source/rtp_format_video_generic.cc
@@ -12,7 +12,8 @@
 
 #include <string.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
diff --git a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h
index 8760acc..b48f1302 100644
--- a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h
+++ b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h
@@ -13,9 +13,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/rtp_header_extensions.cc b/modules/rtp_rtcp/source/rtp_header_extensions.cc
index 43770a7..46c8218 100644
--- a/modules/rtp_rtcp/source/rtp_header_extensions.cc
+++ b/modules/rtp_rtcp/source/rtp_header_extensions.cc
@@ -16,11 +16,11 @@
 #include <cstddef>
 #include <cstdint>
 #include <limits>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/rtp_headers.h"
 #include "api/video/color_space.h"
@@ -119,7 +119,7 @@
 
 size_t AbsoluteCaptureTimeExtension::ValueSize(
     const AbsoluteCaptureTime& extension) {
-  if (extension.estimated_capture_clock_offset != absl::nullopt) {
+  if (extension.estimated_capture_clock_offset != std::nullopt) {
     return kValueSizeBytes;
   } else {
     return kValueSizeBytesWithoutEstimatedCaptureClockOffset;
@@ -304,14 +304,14 @@
 bool TransportSequenceNumberV2::Parse(
     rtc::ArrayView<const uint8_t> data,
     uint16_t* transport_sequence_number,
-    absl::optional<FeedbackRequest>* feedback_request) {
+    std::optional<FeedbackRequest>* feedback_request) {
   if (data.size() != kValueSizeBytes &&
       data.size() != kValueSizeBytesWithoutFeedbackRequest)
     return false;
 
   *transport_sequence_number = ByteReader<uint16_t>::ReadBigEndian(data.data());
 
-  *feedback_request = absl::nullopt;
+  *feedback_request = std::nullopt;
   if (data.size() == kValueSizeBytes) {
     uint16_t feedback_request_raw =
         ByteReader<uint16_t>::ReadBigEndian(data.data() + 2);
@@ -330,7 +330,7 @@
 bool TransportSequenceNumberV2::Write(
     rtc::ArrayView<uint8_t> data,
     uint16_t transport_sequence_number,
-    const absl::optional<FeedbackRequest>& feedback_request) {
+    const std::optional<FeedbackRequest>& feedback_request) {
   RTC_DCHECK_EQ(data.size(),
                 ValueSize(transport_sequence_number, feedback_request));
 
@@ -792,17 +792,17 @@
 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 // Sample Audio Level Encoding Using the Two-Byte Header Format
 bool InbandComfortNoiseExtension::Parse(rtc::ArrayView<const uint8_t> data,
-                                        absl::optional<uint8_t>* level) {
+                                        std::optional<uint8_t>* level) {
   if (data.size() != kValueSizeBytes)
     return false;
   *level = (data[0] & 0b1000'0000) != 0
-               ? absl::nullopt
-               : absl::make_optional(data[0] & 0b0111'1111);
+               ? std::nullopt
+               : std::make_optional(data[0] & 0b0111'1111);
   return true;
 }
 
 bool InbandComfortNoiseExtension::Write(rtc::ArrayView<uint8_t> data,
-                                        absl::optional<uint8_t> level) {
+                                        std::optional<uint8_t> level) {
   RTC_DCHECK_EQ(data.size(), kValueSizeBytes);
   data[0] = 0b0000'0000;
   if (level) {
diff --git a/modules/rtp_rtcp/source/rtp_header_extensions.h b/modules/rtp_rtcp/source/rtp_header_extensions.h
index 02a1543..b8495f4 100644
--- a/modules/rtp_rtcp/source/rtp_header_extensions.h
+++ b/modules/rtp_rtcp/source/rtp_header_extensions.h
@@ -163,16 +163,16 @@
 
   static bool Parse(rtc::ArrayView<const uint8_t> data,
                     uint16_t* transport_sequence_number,
-                    absl::optional<FeedbackRequest>* feedback_request);
+                    std::optional<FeedbackRequest>* feedback_request);
   static size_t ValueSize(
       uint16_t /*transport_sequence_number*/,
-      const absl::optional<FeedbackRequest>& feedback_request) {
+      const std::optional<FeedbackRequest>& feedback_request) {
     return feedback_request ? kValueSizeBytes
                             : kValueSizeBytesWithoutFeedbackRequest;
   }
   static bool Write(rtc::ArrayView<uint8_t> data,
                     uint16_t transport_sequence_number,
-                    const absl::optional<FeedbackRequest>& feedback_request);
+                    const std::optional<FeedbackRequest>& feedback_request);
 
  private:
   static constexpr uint16_t kIncludeTimestampsBit = 1 << 15;
@@ -344,7 +344,7 @@
 
 class InbandComfortNoiseExtension {
  public:
-  using value_type = absl::optional<uint8_t>;
+  using value_type = std::optional<uint8_t>;
 
   static constexpr RTPExtensionType kId = kRtpExtensionInbandComfortNoise;
   static constexpr uint8_t kValueSizeBytes = 1;
@@ -353,12 +353,11 @@
   static constexpr absl::string_view Uri() { return kUri; }
 
   static bool Parse(rtc::ArrayView<const uint8_t> data,
-                    absl::optional<uint8_t>* level);
-  static size_t ValueSize(absl::optional<uint8_t> level) {
+                    std::optional<uint8_t>* level);
+  static size_t ValueSize(std::optional<uint8_t> level) {
     return kValueSizeBytes;
   }
-  static bool Write(rtc::ArrayView<uint8_t> data,
-                    absl::optional<uint8_t> level);
+  static bool Write(rtc::ArrayView<uint8_t> data, std::optional<uint8_t> level);
 };
 
 class VideoFrameTrackingIdExtension {
diff --git a/modules/rtp_rtcp/source/rtp_packet.h b/modules/rtp_rtcp/source/rtp_packet.h
index c002e51..872d2da 100644
--- a/modules/rtp_rtcp/source/rtp_packet.h
+++ b/modules/rtp_rtcp/source/rtp_packet.h
@@ -10,11 +10,11 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_
 #define MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@@ -131,7 +131,7 @@
   bool GetExtension(FirstValue&&, Values&&...) const;
 
   template <typename Extension>
-  absl::optional<typename Extension::value_type> GetExtension() const;
+  std::optional<typename Extension::value_type> GetExtension() const;
 
   // Returns view of the raw extension or empty view on failure.
   template <typename Extension>
@@ -241,11 +241,11 @@
 }
 
 template <typename Extension>
-absl::optional<typename Extension::value_type> RtpPacket::GetExtension() const {
-  absl::optional<typename Extension::value_type> result;
+std::optional<typename Extension::value_type> RtpPacket::GetExtension() const {
+  std::optional<typename Extension::value_type> result;
   auto raw = FindExtension(Extension::kId);
   if (raw.empty() || !Extension::Parse(raw, &result.emplace()))
-    result = absl::nullopt;
+    result = std::nullopt;
   return result;
 }
 
diff --git a/modules/rtp_rtcp/source/rtp_packet_history.cc b/modules/rtp_rtcp/source/rtp_packet_history.cc
index 93bd4ab..936f6f2 100644
--- a/modules/rtp_rtcp/source/rtp_packet_history.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_history.cc
@@ -309,7 +309,7 @@
 
 void RtpPacketHistory::Reset() {
   packet_history_.clear();
-  large_payload_packet_ = absl::nullopt;
+  large_payload_packet_ = std::nullopt;
 }
 
 void RtpPacketHistory::CullOldPackets() {
diff --git a/modules/rtp_rtcp/source/rtp_packet_history.h b/modules/rtp_rtcp/source/rtp_packet_history.h
index 46db9d7..512ffda 100644
--- a/modules/rtp_rtcp/source/rtp_packet_history.h
+++ b/modules/rtp_rtcp/source/rtp_packet_history.h
@@ -14,11 +14,11 @@
 #include <deque>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/function_view.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -190,7 +190,7 @@
   // Total number of packets with inserted.
   uint64_t packets_inserted_ RTC_GUARDED_BY(lock_);
 
-  absl::optional<RtpPacketToSend> large_payload_packet_ RTC_GUARDED_BY(lock_);
+  std::optional<RtpPacketToSend> large_payload_packet_ RTC_GUARDED_BY(lock_);
 };
 }  // namespace webrtc
 #endif  // MODULES_RTP_RTCP_SOURCE_RTP_PACKET_HISTORY_H_
diff --git a/modules/rtp_rtcp/source/rtp_packet_send_info.cc b/modules/rtp_rtcp/source/rtp_packet_send_info.cc
index 6ec7671..2fc5ce5 100644
--- a/modules/rtp_rtcp/source/rtp_packet_send_info.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_send_info.cc
@@ -9,8 +9,8 @@
  */
 
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
@@ -24,7 +24,7 @@
     packet_info.transport_sequence_number =
         *packet.transport_sequence_number() & 0xFFFF;
   } else {
-    absl::optional<uint16_t> packet_id =
+    std::optional<uint16_t> packet_id =
         packet.GetExtension<TransportSequenceNumber>();
     if (packet_id) {
       packet_info.transport_sequence_number = *packet_id;
diff --git a/modules/rtp_rtcp/source/rtp_packet_send_info_unittest.cc b/modules/rtp_rtcp/source/rtp_packet_send_info_unittest.cc
index 223ce26..4dcbe17 100644
--- a/modules/rtp_rtcp/source/rtp_packet_send_info_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_send_info_unittest.cc
@@ -9,8 +9,8 @@
  */
 
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
@@ -70,7 +70,7 @@
   paced_info.probe_cluster_id = 8;
 
   RtpPacketSendInfo send_info = RtpPacketSendInfo::From(packet, paced_info);
-  EXPECT_EQ(send_info.media_ssrc, absl::nullopt);
+  EXPECT_EQ(send_info.media_ssrc, std::nullopt);
   VerifyDefaultProperties(send_info, packet, paced_info);
 }
 
@@ -81,7 +81,7 @@
   paced_info.probe_cluster_id = 8;
 
   RtpPacketSendInfo send_info = RtpPacketSendInfo::From(packet, paced_info);
-  EXPECT_EQ(send_info.media_ssrc, absl::nullopt);
+  EXPECT_EQ(send_info.media_ssrc, std::nullopt);
   VerifyDefaultProperties(send_info, packet, paced_info);
 }
 
diff --git a/modules/rtp_rtcp/source/rtp_packet_to_send.h b/modules/rtp_rtcp/source/rtp_packet_to_send.h
index 47747a0..7eaf1cd 100644
--- a/modules/rtp_rtcp/source/rtp_packet_to_send.h
+++ b/modules/rtp_rtcp/source/rtp_packet_to_send.h
@@ -13,9 +13,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/ref_counted_base.h"
 #include "api/scoped_refptr.h"
@@ -51,13 +51,11 @@
 
   void set_packet_type(RtpPacketMediaType type);
 
-  absl::optional<RtpPacketMediaType> packet_type() const {
-    return packet_type_;
-  }
+  std::optional<RtpPacketMediaType> packet_type() const { return packet_type_; }
 
   enum class OriginalType { kAudio, kVideo };
   // Original type does not change if packet type is changed to kRetransmission.
-  absl::optional<OriginalType> original_packet_type() const {
+  std::optional<OriginalType> original_packet_type() const {
     return original_packet_type_;
   }
 
@@ -67,14 +65,14 @@
   void set_retransmitted_sequence_number(uint16_t sequence_number) {
     retransmitted_sequence_number_ = sequence_number;
   }
-  absl::optional<uint16_t> retransmitted_sequence_number() const {
+  std::optional<uint16_t> retransmitted_sequence_number() const {
     return retransmitted_sequence_number_;
   }
 
   // If this is a retransmission, indicates the SSRC of the original
   // media packet that this packet represents.
   void set_original_ssrc(uint32_t ssrc) { original_ssrc_ = ssrc; }
-  absl::optional<uint32_t> original_ssrc() const { return original_ssrc_; }
+  std::optional<uint32_t> original_ssrc() const { return original_ssrc_; }
 
   void set_allow_retransmission(bool allow_retransmission) {
     allow_retransmission_ = allow_retransmission;
@@ -138,12 +136,12 @@
   void set_time_in_send_queue(TimeDelta time_in_send_queue) {
     time_in_send_queue_ = time_in_send_queue;
   }
-  absl::optional<TimeDelta> time_in_send_queue() const {
+  std::optional<TimeDelta> time_in_send_queue() const {
     return time_in_send_queue_;
   }
   // A sequence number guaranteed to be monotically increasing by one for all
   // packets where transport feedback is expected.
-  absl::optional<int64_t> transport_sequence_number() const {
+  std::optional<int64_t> transport_sequence_number() const {
     return transport_sequence_number_;
   }
   void set_transport_sequence_number(int64_t transport_sequence_number) {
@@ -152,18 +150,18 @@
 
  private:
   webrtc::Timestamp capture_time_ = webrtc::Timestamp::Zero();
-  absl::optional<RtpPacketMediaType> packet_type_;
-  absl::optional<OriginalType> original_packet_type_;
-  absl::optional<uint32_t> original_ssrc_;
-  absl::optional<int64_t> transport_sequence_number_;
+  std::optional<RtpPacketMediaType> packet_type_;
+  std::optional<OriginalType> original_packet_type_;
+  std::optional<uint32_t> original_ssrc_;
+  std::optional<int64_t> transport_sequence_number_;
   bool allow_retransmission_ = false;
-  absl::optional<uint16_t> retransmitted_sequence_number_;
+  std::optional<uint16_t> retransmitted_sequence_number_;
   rtc::scoped_refptr<rtc::RefCountedBase> additional_data_;
   bool is_first_packet_of_frame_ = false;
   bool is_key_frame_ = false;
   bool fec_protect_packet_ = false;
   bool is_red_ = false;
-  absl::optional<TimeDelta> time_in_send_queue_;
+  std::optional<TimeDelta> time_in_send_queue_;
 };
 
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_packet_unittest.cc b/modules/rtp_rtcp/source/rtp_packet_unittest.cc
index ccdb5f8..5f9544d 100644
--- a/modules/rtp_rtcp/source/rtp_packet_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_unittest.cc
@@ -399,7 +399,7 @@
   EXPECT_FALSE(packet.SetExtension<TransportSequenceNumber>(42));
 
   EXPECT_FALSE(packet.HasExtension<TransportSequenceNumber>());
-  EXPECT_EQ(packet.GetExtension<TransportSequenceNumber>(), absl::nullopt);
+  EXPECT_EQ(packet.GetExtension<TransportSequenceNumber>(), std::nullopt);
 }
 
 TEST(RtpPacketTest, SetReservedExtensionsAfterPayload) {
@@ -605,7 +605,7 @@
   auto time_offset = packet.GetExtension<TransmissionOffset>();
   static_assert(
       std::is_same<decltype(time_offset),
-                   absl::optional<TransmissionOffset::value_type>>::value,
+                   std::optional<TransmissionOffset::value_type>>::value,
       "");
   EXPECT_EQ(time_offset, kTimeOffset);
   EXPECT_FALSE(packet.GetExtension<RtpStreamId>().has_value());
@@ -1043,7 +1043,7 @@
 
   constexpr AbsoluteCaptureTime kAbsoluteCaptureTime{
       /*absolute_capture_timestamp=*/9876543210123456789ULL,
-      /*estimated_capture_clock_offset=*/absl::nullopt};
+      /*estimated_capture_clock_offset=*/std::nullopt};
   ASSERT_TRUE(send_packet.SetExtension<AbsoluteCaptureTimeExtension>(
       kAbsoluteCaptureTime));
 
@@ -1099,7 +1099,7 @@
 
   constexpr int kTransportSequenceNumber = 12345;
   send_packet.SetExtension<TransportSequenceNumberV2>(kTransportSequenceNumber,
-                                                      absl::nullopt);
+                                                      std::nullopt);
   EXPECT_EQ(send_packet.GetRawExtension<TransportSequenceNumberV2>().size(),
             2u);
 
@@ -1108,7 +1108,7 @@
   EXPECT_TRUE(receive_packet.Parse(send_packet.Buffer()));
 
   uint16_t received_transport_sequeunce_number;
-  absl::optional<FeedbackRequest> received_feedback_request;
+  std::optional<FeedbackRequest> received_feedback_request;
   EXPECT_TRUE(receive_packet.GetExtension<TransportSequenceNumberV2>(
       &received_transport_sequeunce_number, &received_feedback_request));
   EXPECT_EQ(received_transport_sequeunce_number, kTransportSequenceNumber);
@@ -1130,7 +1130,7 @@
   send_packet.SetSsrc(kSsrc);
 
   constexpr int kTransportSequenceNumber = 12345;
-  constexpr absl::optional<FeedbackRequest> kNoFeedbackRequest =
+  constexpr std::optional<FeedbackRequest> kNoFeedbackRequest =
       FeedbackRequest{/*include_timestamps=*/false, /*sequence_count=*/0};
   send_packet.ReserveExtension<TransportSequenceNumberV2>();
   send_packet.SetExtension<TransportSequenceNumberV2>(kTransportSequenceNumber,
@@ -1143,7 +1143,7 @@
   EXPECT_TRUE(receive_packet.Parse(send_packet.Buffer()));
 
   uint16_t received_transport_sequeunce_number;
-  absl::optional<FeedbackRequest> received_feedback_request;
+  std::optional<FeedbackRequest> received_feedback_request;
   EXPECT_TRUE(receive_packet.GetExtension<TransportSequenceNumberV2>(
       &received_transport_sequeunce_number, &received_feedback_request));
   EXPECT_EQ(received_transport_sequeunce_number, kTransportSequenceNumber);
@@ -1163,7 +1163,7 @@
   send_packet.SetSsrc(kSsrc);
 
   constexpr int kTransportSequenceNumber = 12345;
-  constexpr absl::optional<FeedbackRequest> kFeedbackRequest =
+  constexpr std::optional<FeedbackRequest> kFeedbackRequest =
       FeedbackRequest{/*include_timestamps=*/true, /*sequence_count=*/3};
   send_packet.SetExtension<TransportSequenceNumberV2>(kTransportSequenceNumber,
                                                       kFeedbackRequest);
@@ -1174,7 +1174,7 @@
 
   // Parse transport sequence number and feedback request.
   uint16_t received_transport_sequeunce_number;
-  absl::optional<FeedbackRequest> received_feedback_request;
+  std::optional<FeedbackRequest> received_feedback_request;
   EXPECT_TRUE(receive_packet.GetExtension<TransportSequenceNumberV2>(
       &received_transport_sequeunce_number, &received_feedback_request));
   EXPECT_EQ(received_transport_sequeunce_number, kTransportSequenceNumber);
diff --git a/modules/rtp_rtcp/source/rtp_packetizer_h265.cc b/modules/rtp_rtcp/source/rtp_packetizer_h265.cc
index 901b68b..efc0d8a 100644
--- a/modules/rtp_rtcp/source/rtp_packetizer_h265.cc
+++ b/modules/rtp_rtcp/source/rtp_packetizer_h265.cc
@@ -10,9 +10,9 @@
 
 #include "modules/rtp_rtcp/source/rtp_packetizer_h265.h"
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "common_video/h264/h264_common.h"
 #include "common_video/h265/h265_common.h"
 #include "modules/rtp_rtcp/source/byte_io.h"
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index e13b043..a2c309e 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -15,12 +15,12 @@
 #include <algorithm>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "modules/rtp_rtcp/source/ntp_time_util.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h"
 #include "modules/rtp_rtcp/source/rtcp_sender.h"
@@ -155,7 +155,7 @@
   } else {
     // Report rtt from receiver.
     if (process_rtt && rtt_stats_ != nullptr) {
-      absl::optional<TimeDelta> rtt = rtcp_receiver_.GetAndResetXrRrRtt();
+      std::optional<TimeDelta> rtt = rtcp_receiver_.GetAndResetXrRrRtt();
       if (rtt.has_value()) {
         rtt_stats_->OnRttUpdate(rtt->ms());
       }
@@ -195,15 +195,15 @@
                                                   associated_payload_type);
 }
 
-absl::optional<uint32_t> ModuleRtpRtcpImpl::RtxSsrc() const {
-  return rtp_sender_ ? rtp_sender_->packet_generator.RtxSsrc() : absl::nullopt;
+std::optional<uint32_t> ModuleRtpRtcpImpl::RtxSsrc() const {
+  return rtp_sender_ ? rtp_sender_->packet_generator.RtxSsrc() : std::nullopt;
 }
 
-absl::optional<uint32_t> ModuleRtpRtcpImpl::FlexfecSsrc() const {
+std::optional<uint32_t> ModuleRtpRtcpImpl::FlexfecSsrc() const {
   if (rtp_sender_) {
     return rtp_sender_->packet_generator.FlexfecSsrc();
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void ModuleRtpRtcpImpl::IncomingRtcpPacket(
@@ -295,7 +295,7 @@
   }
   state.receiver = &rtcp_receiver_;
 
-  if (absl::optional<RtpRtcpInterface::SenderReportStats> last_sr =
+  if (std::optional<RtpRtcpInterface::SenderReportStats> last_sr =
           rtcp_receiver_.GetSenderReportStats();
       last_sr.has_value()) {
     state.remote_sr = CompactNtp(last_sr->last_remote_timestamp);
@@ -346,11 +346,11 @@
 
   // TODO(bugs.webrtc.org/12873): Migrate this method and it's users to use
   // optional Timestamps.
-  absl::optional<Timestamp> capture_time;
+  std::optional<Timestamp> capture_time;
   if (capture_time_ms > 0) {
     capture_time = Timestamp::Millis(capture_time_ms);
   }
-  absl::optional<int> payload_type_optional;
+  std::optional<int> payload_type_optional;
   if (payload_type >= 0)
     payload_type_optional = payload_type;
   rtcp_sender_.SetLastRtpTime(timestamp, capture_time, payload_type_optional);
@@ -475,8 +475,8 @@
   return rtcp_sender_.SetCNAME(c_name);
 }
 
-absl::optional<TimeDelta> ModuleRtpRtcpImpl::LastRtt() const {
-  absl::optional<TimeDelta> rtt = rtcp_receiver_.LastRtt();
+std::optional<TimeDelta> ModuleRtpRtcpImpl::LastRtt() const {
+  std::optional<TimeDelta> rtt = rtcp_receiver_.LastRtt();
   if (!rtt.has_value()) {
     MutexLock lock(&mutex_rtt_);
     if (rtt_ms_ > 0) {
@@ -493,7 +493,7 @@
   }
   // No rtt available (`kRtpRtcpRttProcessTimeMs` not yet passed?), so try to
   // poll avg_rtt_ms directly from rtcp receiver.
-  if (absl::optional<TimeDelta> rtt = rtcp_receiver_.AverageRtt()) {
+  if (std::optional<TimeDelta> rtt = rtcp_receiver_.AverageRtt()) {
     return *rtt;
   }
   return kDefaultExpectedRetransmissionTime;
@@ -517,15 +517,15 @@
   return rtcp_receiver_.GetLatestReportBlockData();
 }
 
-absl::optional<RtpRtcpInterface::SenderReportStats>
+std::optional<RtpRtcpInterface::SenderReportStats>
 ModuleRtpRtcpImpl::GetSenderReportStats() const {
   return rtcp_receiver_.GetSenderReportStats();
 }
 
-absl::optional<RtpRtcpInterface::NonSenderRttStats>
+std::optional<RtpRtcpInterface::NonSenderRttStats>
 ModuleRtpRtcpImpl::GetNonSenderRttStats() const {
   // This is not implemented for this legacy class.
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // (REMB) Receiver Estimated Max Bitrate.
@@ -603,7 +603,7 @@
   // Use RTT from RtcpRttStats class if provided.
   int64_t rtt = rtt_ms();
   if (rtt == 0) {
-    if (absl::optional<TimeDelta> average_rtt = rtcp_receiver_.AverageRtt()) {
+    if (std::optional<TimeDelta> average_rtt = rtcp_receiver_.AverageRtt()) {
       rtt = average_rtt->ms();
     }
   }
@@ -676,7 +676,7 @@
   // Use RTT from RtcpRttStats class if provided.
   int64_t rtt = rtt_ms();
   if (rtt == 0) {
-    if (absl::optional<TimeDelta> average_rtt = rtcp_receiver_.AverageRtt()) {
+    if (std::optional<TimeDelta> average_rtt = rtcp_receiver_.AverageRtt()) {
       rtt = average_rtt->ms();
     }
   }
@@ -687,7 +687,7 @@
     rtc::ArrayView<const ReportBlockData> report_blocks) {
   if (rtp_sender_) {
     uint32_t ssrc = SSRC();
-    absl::optional<uint32_t> rtx_ssrc;
+    std::optional<uint32_t> rtx_ssrc;
     if (rtp_sender_->packet_generator.RtxStatus() != kRtxOff) {
       rtx_ssrc = rtp_sender_->packet_generator.RtxSsrc();
     }
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index 143b5f1..ba703bb 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -15,12 +15,12 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/rtp_headers.h"
 #include "api/video/video_bitrate_allocation.h"
 #include "modules/include/module_fec_types.h"
@@ -107,12 +107,12 @@
 
   void SetRtxSendStatus(int mode) override;
   int RtxSendStatus() const override;
-  absl::optional<uint32_t> RtxSsrc() const override;
+  std::optional<uint32_t> RtxSsrc() const override;
 
   void SetRtxSendPayloadType(int payload_type,
                              int associated_payload_type) override;
 
-  absl::optional<uint32_t> FlexfecSsrc() const override;
+  std::optional<uint32_t> FlexfecSsrc() const override;
 
   // Sends kRtcpByeCode when going from true to false.
   int32_t SetSendingStatus(bool sending) override;
@@ -185,7 +185,7 @@
   int32_t SetCNAME(absl::string_view c_name) override;
 
   // Get RoundTripTime.
-  absl::optional<TimeDelta> LastRtt() const override;
+  std::optional<TimeDelta> LastRtt() const override;
 
   TimeDelta ExpectedRetransmissionTime() const override;
 
@@ -202,10 +202,10 @@
   // Within this list, the `ReportBlockData::source_ssrc()`, which is the SSRC
   // of the corresponding outbound RTP stream, is unique.
   std::vector<ReportBlockData> GetLatestReportBlockData() const override;
-  absl::optional<SenderReportStats> GetSenderReportStats() const override;
+  std::optional<SenderReportStats> GetSenderReportStats() const override;
   // Round trip time statistics computed from the XR block contained in the last
   // report.
-  absl::optional<NonSenderRttStats> GetNonSenderRttStats() const override;
+  std::optional<NonSenderRttStats> GetNonSenderRttStats() const override;
 
   // (REMB) Receiver Estimated Max Bitrate.
   void SetRemb(int64_t bitrate_bps, std::vector<uint32_t> ssrcs) override;
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc
index a4aae47..b8cf585 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc
@@ -15,13 +15,13 @@
 #include <algorithm>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
 
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/sequence_checker.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -156,15 +156,15 @@
                                                   associated_payload_type);
 }
 
-absl::optional<uint32_t> ModuleRtpRtcpImpl2::RtxSsrc() const {
-  return rtp_sender_ ? rtp_sender_->packet_generator.RtxSsrc() : absl::nullopt;
+std::optional<uint32_t> ModuleRtpRtcpImpl2::RtxSsrc() const {
+  return rtp_sender_ ? rtp_sender_->packet_generator.RtxSsrc() : std::nullopt;
 }
 
-absl::optional<uint32_t> ModuleRtpRtcpImpl2::FlexfecSsrc() const {
+std::optional<uint32_t> ModuleRtpRtcpImpl2::FlexfecSsrc() const {
   if (rtp_sender_) {
     return rtp_sender_->packet_generator.FlexfecSsrc();
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void ModuleRtpRtcpImpl2::IncomingRtcpPacket(
@@ -277,7 +277,7 @@
   }
   state.receiver = &rtcp_receiver_;
 
-  if (absl::optional<RtpRtcpInterface::SenderReportStats> last_sr =
+  if (std::optional<RtpRtcpInterface::SenderReportStats> last_sr =
           rtcp_receiver_.GetSenderReportStats();
       last_sr.has_value()) {
     state.remote_sr = CompactNtp(last_sr->last_remote_timestamp);
@@ -329,11 +329,11 @@
   }
   // TODO(bugs.webrtc.org/12873): Migrate this method and it's users to use
   // optional Timestamps.
-  absl::optional<Timestamp> capture_time;
+  std::optional<Timestamp> capture_time;
   if (capture_time_ms > 0) {
     capture_time = Timestamp::Millis(capture_time_ms);
   }
-  absl::optional<int> payload_type_optional;
+  std::optional<int> payload_type_optional;
   if (payload_type >= 0)
     payload_type_optional = payload_type;
 
@@ -497,8 +497,8 @@
   return rtcp_sender_.SetCNAME(c_name);
 }
 
-absl::optional<TimeDelta> ModuleRtpRtcpImpl2::LastRtt() const {
-  absl::optional<TimeDelta> rtt = rtcp_receiver_.LastRtt();
+std::optional<TimeDelta> ModuleRtpRtcpImpl2::LastRtt() const {
+  std::optional<TimeDelta> rtt = rtcp_receiver_.LastRtt();
   if (!rtt.has_value()) {
     MutexLock lock(&mutex_rtt_);
     if (rtt_ms_ > 0) {
@@ -515,7 +515,7 @@
   }
   // No rtt available (`kRttUpdateInterval` not yet passed?), so try to
   // poll avg_rtt_ms directly from rtcp receiver.
-  if (absl::optional<TimeDelta> rtt = rtcp_receiver_.AverageRtt()) {
+  if (std::optional<TimeDelta> rtt = rtcp_receiver_.AverageRtt()) {
     return *rtt;
   }
   return kDefaultExpectedRetransmissionTime;
@@ -539,12 +539,12 @@
   return rtcp_receiver_.GetLatestReportBlockData();
 }
 
-absl::optional<RtpRtcpInterface::SenderReportStats>
+std::optional<RtpRtcpInterface::SenderReportStats>
 ModuleRtpRtcpImpl2::GetSenderReportStats() const {
   return rtcp_receiver_.GetSenderReportStats();
 }
 
-absl::optional<RtpRtcpInterface::NonSenderRttStats>
+std::optional<RtpRtcpInterface::NonSenderRttStats>
 ModuleRtpRtcpImpl2::GetNonSenderRttStats() const {
   RTCPReceiver::NonSenderRttStats non_sender_rtt_stats =
       rtcp_receiver_.GetNonSenderRTT();
@@ -630,7 +630,7 @@
   // Use RTT from RtcpRttStats class if provided.
   int64_t rtt = rtt_ms();
   if (rtt == 0) {
-    if (absl::optional<TimeDelta> average_rtt = rtcp_receiver_.AverageRtt()) {
+    if (std::optional<TimeDelta> average_rtt = rtcp_receiver_.AverageRtt()) {
       rtt = average_rtt->ms();
     }
   }
@@ -705,7 +705,7 @@
   // Use RTT from RtcpRttStats class if provided.
   int64_t rtt = rtt_ms();
   if (rtt == 0) {
-    if (absl::optional<TimeDelta> average_rtt = rtcp_receiver_.AverageRtt()) {
+    if (std::optional<TimeDelta> average_rtt = rtcp_receiver_.AverageRtt()) {
       rtt = average_rtt->ms();
     }
   }
@@ -716,7 +716,7 @@
     rtc::ArrayView<const ReportBlockData> report_blocks) {
   if (rtp_sender_) {
     uint32_t ssrc = SSRC();
-    absl::optional<uint32_t> rtx_ssrc;
+    std::optional<uint32_t> rtx_ssrc;
     if (rtp_sender_->packet_generator.RtxStatus() != kRtxOff) {
       rtx_ssrc = rtp_sender_->packet_generator.RtxSsrc();
     }
@@ -766,7 +766,7 @@
   RTC_DCHECK_RUN_ON(worker_queue_);
 
   Timestamp check_since = clock_->CurrentTime() - kRttUpdateInterval;
-  absl::optional<TimeDelta> rtt =
+  std::optional<TimeDelta> rtt =
       rtcp_receiver_.OnPeriodicRttUpdate(check_since, rtcp_sender_.Sending());
   if (rtt) {
     if (rtt_stats_) {
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2.h b/modules/rtp_rtcp/source/rtp_rtcp_impl2.h
index cd365b2..b2c0537 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl2.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl2.h
@@ -15,12 +15,12 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/rtp_headers.h"
 #include "api/sequence_checker.h"
@@ -119,12 +119,12 @@
 
   void SetRtxSendStatus(int mode) override;
   int RtxSendStatus() const override;
-  absl::optional<uint32_t> RtxSsrc() const override;
+  std::optional<uint32_t> RtxSsrc() const override;
 
   void SetRtxSendPayloadType(int payload_type,
                              int associated_payload_type) override;
 
-  absl::optional<uint32_t> FlexfecSsrc() const override;
+  std::optional<uint32_t> FlexfecSsrc() const override;
 
   // Sends kRtcpByeCode when going from true to false.
   int32_t SetSendingStatus(bool sending) override;
@@ -189,7 +189,7 @@
   int32_t SetCNAME(absl::string_view c_name) override;
 
   // Get RoundTripTime.
-  absl::optional<TimeDelta> LastRtt() const override;
+  std::optional<TimeDelta> LastRtt() const override;
 
   TimeDelta ExpectedRetransmissionTime() const override;
 
@@ -207,8 +207,8 @@
   // Within this list, the `ReportBlockData::source_ssrc()`, which is the SSRC
   // of the corresponding outbound RTP stream, is unique.
   std::vector<ReportBlockData> GetLatestReportBlockData() const override;
-  absl::optional<SenderReportStats> GetSenderReportStats() const override;
-  absl::optional<NonSenderRttStats> GetNonSenderRttStats() const override;
+  std::optional<SenderReportStats> GetSenderReportStats() const override;
+  std::optional<NonSenderRttStats> GetNonSenderRttStats() const override;
 
   // (REMB) Receiver Estimated Max Bitrate.
   void SetRemb(int64_t bitrate_bps, std::vector<uint32_t> ssrcs) override;
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2_unittest.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl2_unittest.cc
index 9332813..63224e7 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl2_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl2_unittest.cc
@@ -13,10 +13,10 @@
 #include <deque>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
 #include "api/field_trials_registry.h"
@@ -194,7 +194,7 @@
     counter_map_[ssrc] = packet_counter;
   }
 
-  void OnSendPacket(absl::optional<uint16_t> packet_id,
+  void OnSendPacket(std::optional<uint16_t> packet_id,
                     Timestamp capture_time,
                     uint32_t ssrc) override {
     if (packet_id.has_value()) {
@@ -202,7 +202,7 @@
     }
   }
 
-  absl::optional<SentPacket> last_sent_packet() const {
+  std::optional<SentPacket> last_sent_packet() const {
     return last_sent_packet_;
   }
 
@@ -245,7 +245,7 @@
     config.rtcp_report_interval_ms = rtcp_report_interval_.ms();
     config.local_media_ssrc = is_sender_ ? kSenderSsrc : kReceiverSsrc;
     config.rtx_send_ssrc =
-        is_sender_ ? absl::make_optional(kRtxSenderSsrc) : absl::nullopt;
+        is_sender_ ? std::make_optional(kRtxSenderSsrc) : std::nullopt;
     config.need_rtp_packet_infos = true;
     config.non_sender_rtt_measurement = true;
     config.send_packet_observer = this;
@@ -257,7 +257,7 @@
 
  private:
   std::map<uint32_t, RtcpPacketTypeCounter> counter_map_;
-  absl::optional<SentPacket> last_sent_packet_;
+  std::optional<SentPacket> last_sent_packet_;
   VideoFecGenerator* fec_generator_ = nullptr;
   TimeDelta rtcp_report_interval_ = kDefaultReportInterval;
 };
@@ -302,7 +302,7 @@
   }
 
   void ReinitWithFec(VideoFecGenerator* fec_generator,
-                     absl::optional<int> red_payload_type) {
+                     std::optional<int> red_payload_type) {
     sender_.ReinintWithFec(fec_generator);
     EXPECT_EQ(0, sender_.impl_->SetSendingStatus(true));
     sender_.impl_->SetSendingMediaStatus(true);
@@ -765,7 +765,7 @@
 
 // Checks that the sender report stats are not available if no RTCP SR was sent.
 TEST_F(RtpRtcpImpl2Test, SenderReportStatsNotAvailable) {
-  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Eq(absl::nullopt));
+  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Eq(std::nullopt));
 }
 
 // Checks that the sender report stats are available if an RTCP SR was sent.
@@ -775,7 +775,7 @@
   // Send an SR.
   ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0));
   AdvanceTime(kOneWayNetworkDelay);
-  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Not(Eq(absl::nullopt)));
+  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Not(Eq(std::nullopt)));
 }
 
 // Checks that the sender report stats are not available if an RTCP SR with an
@@ -792,7 +792,7 @@
   sr.SetOctetCount(456u);
   auto raw_packet = sr.Build();
   receiver_.impl_->IncomingRtcpPacket(raw_packet);
-  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Eq(absl::nullopt));
+  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Eq(std::nullopt));
 }
 
 // Checks the stats derived from the last received RTCP SR are set correctly.
@@ -844,7 +844,7 @@
   ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0));
   AdvanceTime(kOneWayNetworkDelay);
   auto stats = receiver_.impl_->GetSenderReportStats();
-  ASSERT_THAT(stats, Not(Eq(absl::nullopt)));
+  ASSERT_THAT(stats, Not(Eq(std::nullopt)));
   EXPECT_TRUE(stats->last_arrival_timestamp.Valid());
 }
 
@@ -1006,7 +1006,7 @@
   FlexfecSender flexfec_sender(env_, kFlexfecPayloadType, kFlexfecSsrc,
                                kSenderSsrc, kNoMid, kNoRtpExtensions,
                                kNoRtpExtensionSizes, &start_state);
-  ReinitWithFec(&flexfec_sender, /*red_payload_type=*/absl::nullopt);
+  ReinitWithFec(&flexfec_sender, /*red_payload_type=*/std::nullopt);
 
   // Parameters selected to generate a single FEC packet per media packet.
   FecProtectionParams params;
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
index abf3b63..1ed37e0 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
@@ -599,7 +599,7 @@
 
 // Checks that the remote sender stats are not available if no RTCP SR was sent.
 TEST_F(RtpRtcpImplTest, SenderReportStatsNotAvailable) {
-  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Eq(absl::nullopt));
+  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Eq(std::nullopt));
 }
 
 // Checks that the remote sender stats are available if an RTCP SR was sent.
@@ -608,7 +608,7 @@
   SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
   // Send an SR.
   ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0));
-  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Not(Eq(absl::nullopt)));
+  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Not(Eq(std::nullopt)));
 }
 
 // Checks that the remote sender stats are not available if an RTCP SR with an
@@ -624,7 +624,7 @@
   sr.SetPacketCount(123u);
   sr.SetOctetCount(456u);
   receiver_.impl_->IncomingRtcpPacket(sr.Build());
-  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Eq(absl::nullopt));
+  EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Eq(std::nullopt));
 }
 
 // Checks the stats derived from the last received RTCP SR are set correctly.
@@ -672,7 +672,7 @@
   // Send an SR.
   ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0));
   auto stats = receiver_.impl_->GetSenderReportStats();
-  ASSERT_THAT(stats, Not(Eq(absl::nullopt)));
+  ASSERT_THAT(stats, Not(Eq(std::nullopt)));
   EXPECT_TRUE(stats->last_arrival_timestamp.Valid());
 }
 
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_interface.h b/modules/rtp_rtcp/source/rtp_rtcp_interface.h
index dfdc13d..d400b76 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_interface.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_interface.h
@@ -12,11 +12,11 @@
 #define MODULES_RTP_RTCP_SOURCE_RTP_RTCP_INTERFACE_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/frame_transformer_interface.h"
 #include "api/rtp_packet_sender.h"
@@ -127,7 +127,7 @@
     // SSRCs for media and retransmission, respectively.
     // FlexFec SSRC is fetched from `flexfec_sender`.
     uint32_t local_media_ssrc = 0;
-    absl::optional<uint32_t> rtx_send_ssrc;
+    std::optional<uint32_t> rtx_send_ssrc;
 
     bool need_rtp_packet_infos = false;
 
@@ -171,7 +171,7 @@
   // Refer to https://datatracker.ietf.org/doc/html/rfc3611#section-2.
   struct NonSenderRttStats {
     // https://www.w3.org/TR/webrtc-stats/#dom-rtcremoteoutboundrtpstreamstats-roundtriptime
-    absl::optional<TimeDelta> round_trip_time;
+    std::optional<TimeDelta> round_trip_time;
     // https://www.w3.org/TR/webrtc-stats/#dom-rtcremoteoutboundrtpstreamstats-totalroundtriptime
     TimeDelta total_round_trip_time = TimeDelta::Zero();
     // https://www.w3.org/TR/webrtc-stats/#dom-rtcremoteoutboundrtpstreamstats-roundtriptimemeasurements
@@ -263,7 +263,7 @@
   virtual int RtxSendStatus() const = 0;
 
   // Returns the SSRC used for RTX if set, otherwise a nullopt.
-  virtual absl::optional<uint32_t> RtxSsrc() const = 0;
+  virtual std::optional<uint32_t> RtxSsrc() const = 0;
 
   // Sets the payload type to use when sending RTX packets. Note that this
   // doesn't enable RTX, only the payload type is set.
@@ -271,7 +271,7 @@
                                      int associated_payload_type) = 0;
 
   // Returns the FlexFEC SSRC, if there is one.
-  virtual absl::optional<uint32_t> FlexfecSsrc() const = 0;
+  virtual std::optional<uint32_t> FlexfecSsrc() const = 0;
 
   // Sets sending status.
   // Returns -1 on failure else 0.
@@ -386,7 +386,7 @@
   virtual int32_t SetCNAME(absl::string_view cname) = 0;
 
   // Returns current RTT (round-trip time) estimate.
-  virtual absl::optional<TimeDelta> LastRtt() const = 0;
+  virtual std::optional<TimeDelta> LastRtt() const = 0;
 
   // Returns the estimated RTT, with fallback to a default value.
   virtual TimeDelta ExpectedRetransmissionTime() const = 0;
@@ -407,9 +407,9 @@
   // that pair.
   virtual std::vector<ReportBlockData> GetLatestReportBlockData() const = 0;
   // Returns stats based on the received RTCP SRs.
-  virtual absl::optional<SenderReportStats> GetSenderReportStats() const = 0;
+  virtual std::optional<SenderReportStats> GetSenderReportStats() const = 0;
   // Returns non-sender RTT stats, based on DLRR.
-  virtual absl::optional<NonSenderRttStats> GetNonSenderRttStats() const = 0;
+  virtual std::optional<NonSenderRttStats> GetNonSenderRttStats() const = 0;
 
   // (REMB) Receiver Estimated Max Bitrate.
   // Schedules sending REMB on next and following sender/receiver reports.
diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc
index 2abbfe5..bfdaca0 100644
--- a/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/modules/rtp_rtcp/source/rtp_sender.cc
@@ -15,12 +15,12 @@
 #include <cstdint>
 #include <cstring>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/rtp_headers.h"
 #include "api/rtp_packet_sender.h"
@@ -161,7 +161,7 @@
       ssrc_(config.local_media_ssrc),
       rtx_ssrc_(config.rtx_send_ssrc),
       flexfec_ssrc_(config.fec_generator ? config.fec_generator->FecSsrc()
-                                         : absl::nullopt),
+                                         : std::nullopt),
       packet_history_(packet_history),
       paced_sender_(packet_sender),
       sending_media_(true),                   // Default to sending media.
diff --git a/modules/rtp_rtcp/source/rtp_sender.h b/modules/rtp_rtcp/source/rtp_sender.h
index 61a1a5f..0877857 100644
--- a/modules/rtp_rtcp/source/rtp_sender.h
+++ b/modules/rtp_rtcp/source/rtp_sender.h
@@ -13,12 +13,12 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/call/transport.h"
 #include "api/field_trials_view.h"
@@ -102,7 +102,7 @@
   // RTX.
   void SetRtxStatus(int mode) RTC_LOCKS_EXCLUDED(send_mutex_);
   int RtxStatus() const RTC_LOCKS_EXCLUDED(send_mutex_);
-  absl::optional<uint32_t> RtxSsrc() const RTC_LOCKS_EXCLUDED(send_mutex_) {
+  std::optional<uint32_t> RtxSsrc() const RTC_LOCKS_EXCLUDED(send_mutex_) {
     return rtx_ssrc_;
   }
   // Returns expected size difference between an RTX packet and media packet
@@ -140,7 +140,7 @@
 
   uint32_t SSRC() const RTC_LOCKS_EXCLUDED(send_mutex_) { return ssrc_; }
 
-  absl::optional<uint32_t> FlexfecSsrc() const RTC_LOCKS_EXCLUDED(send_mutex_) {
+  std::optional<uint32_t> FlexfecSsrc() const RTC_LOCKS_EXCLUDED(send_mutex_) {
     return flexfec_ssrc_;
   }
 
@@ -172,8 +172,8 @@
   const bool audio_configured_;
 
   const uint32_t ssrc_;
-  const absl::optional<uint32_t> rtx_ssrc_;
-  const absl::optional<uint32_t> flexfec_ssrc_;
+  const std::optional<uint32_t> rtx_ssrc_;
+  const std::optional<uint32_t> flexfec_ssrc_;
 
   RtpPacketHistory* const packet_history_;
   RtpPacketSender* const paced_sender_;
diff --git a/modules/rtp_rtcp/source/rtp_sender_audio.cc b/modules/rtp_rtcp/source/rtp_sender_audio.cc
index aec54d3..3330f39 100644
--- a/modules/rtp_rtcp/source/rtp_sender_audio.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_audio.cc
@@ -13,11 +13,11 @@
 #include <string.h>
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_format.h"
 #include "api/rtp_headers.h"
 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
@@ -137,7 +137,7 @@
   // updates, with a value of 50 ms RECOMMENDED.
   constexpr int kDtmfIntervalTimeMs = 50;
   uint32_t dtmf_payload_freq = 0;
-  absl::optional<AbsoluteCaptureTime> absolute_capture_time;
+  std::optional<AbsoluteCaptureTime> absolute_capture_time;
   {
     MutexLock lock(&send_audio_mutex_);
     dtmf_payload_freq = dtmf_payload_freq_;
diff --git a/modules/rtp_rtcp/source/rtp_sender_audio.h b/modules/rtp_rtcp/source/rtp_sender_audio.h
index 83a2cb2..d17c96c 100644
--- a/modules/rtp_rtcp/source/rtp_sender_audio.h
+++ b/modules/rtp_rtcp/source/rtp_sender_audio.h
@@ -55,12 +55,12 @@
     uint32_t rtp_timestamp = 0;
 
     // capture time of the audio frame in the same epoch as `clock->CurrentTime`
-    absl::optional<Timestamp> capture_time;
+    std::optional<Timestamp> capture_time;
 
     // Audio level in dBov for
     // header-extension-for-audio-level-indication.
     // Valid range is [0,127]. Actual value is negative.
-    absl::optional<int> audio_level_dbov;
+    std::optional<int> audio_level_dbov;
 
     // Contributing sources list.
     rtc::ArrayView<const uint32_t> csrcs;
@@ -107,7 +107,7 @@
 
   OneTimeEvent first_packet_sent_;
 
-  absl::optional<int> encoder_rtp_timestamp_frequency_
+  std::optional<int> encoder_rtp_timestamp_frequency_
       RTC_GUARDED_BY(send_audio_mutex_);
 
   AbsoluteCaptureTimeSender absolute_capture_time_sender_
diff --git a/modules/rtp_rtcp/source/rtp_sender_egress.cc b/modules/rtp_rtcp/source/rtp_sender_egress.cc
index 5c97ef8..0753ec3 100644
--- a/modules/rtp_rtcp/source/rtp_sender_egress.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_egress.cc
@@ -94,7 +94,7 @@
       ssrc_(config.local_media_ssrc),
       rtx_ssrc_(config.rtx_send_ssrc),
       flexfec_ssrc_(config.fec_generator ? config.fec_generator->FecSsrc()
-                                         : absl::nullopt),
+                                         : std::nullopt),
       populate_network2_timestamp_(config.populate_network2_timestamp),
       clock_(config.clock),
       packet_history_(packet_history),
@@ -175,7 +175,7 @@
     // This packet should be protected by FEC, add it to packet generator.
     RTC_DCHECK(fec_generator_);
     RTC_DCHECK(packet->packet_type() == RtpPacketMediaType::kVideo);
-    absl::optional<std::pair<FecProtectionParams, FecProtectionParams>>
+    std::optional<std::pair<FecProtectionParams, FecProtectionParams>>
         new_fec_params;
     new_fec_params.swap(pending_fec_params_);
     if (new_fec_params) {
@@ -275,7 +275,7 @@
   // bit and will wrap. We should be able to use the 64bit value as id, but in
   // order to not change behaviour we use the 16bit extension value if it is
   // used.
-  absl::optional<uint16_t> packet_id =
+  std::optional<uint16_t> packet_id =
       packet->GetExtension<TransportSequenceNumber>();
   if (packet_id.has_value()) {
     options.packet_id = *packet_id;
diff --git a/modules/rtp_rtcp/source/rtp_sender_egress.h b/modules/rtp_rtcp/source/rtp_sender_egress.h
index 49ee8c1..3e4fa66 100644
--- a/modules/rtp_rtcp/source/rtp_sender_egress.h
+++ b/modules/rtp_rtcp/source/rtp_sender_egress.h
@@ -13,10 +13,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/call/transport.h"
 #include "api/rtc_event_log/rtc_event_log.h"
 #include "api/sequence_checker.h"
@@ -72,8 +72,8 @@
                   const PacedPacketInfo& pacing_info);
   void OnBatchComplete();
   uint32_t Ssrc() const { return ssrc_; }
-  absl::optional<uint32_t> RtxSsrc() const { return rtx_ssrc_; }
-  absl::optional<uint32_t> FlexFecSsrc() const { return flexfec_ssrc_; }
+  std::optional<uint32_t> RtxSsrc() const { return rtx_ssrc_; }
+  std::optional<uint32_t> FlexFecSsrc() const { return flexfec_ssrc_; }
 
   RtpSendRates GetSendRates(Timestamp now) const;
   void GetDataCounters(StreamDataCounters* rtp_stats,
@@ -126,8 +126,8 @@
   const bool enable_send_packet_batching_;
   TaskQueueBase* const worker_queue_;
   const uint32_t ssrc_;
-  const absl::optional<uint32_t> rtx_ssrc_;
-  const absl::optional<uint32_t> flexfec_ssrc_;
+  const std::optional<uint32_t> rtx_ssrc_;
+  const std::optional<uint32_t> flexfec_ssrc_;
   const bool populate_network2_timestamp_;
   Clock* const clock_;
   RtpPacketHistory* const packet_history_ RTC_GUARDED_BY(worker_queue_);
@@ -136,8 +136,8 @@
   const bool is_audio_;
   const bool need_rtp_packet_infos_;
   VideoFecGenerator* const fec_generator_ RTC_GUARDED_BY(worker_queue_);
-  absl::optional<uint16_t> last_sent_seq_ RTC_GUARDED_BY(worker_queue_);
-  absl::optional<uint16_t> last_sent_rtx_seq_ RTC_GUARDED_BY(worker_queue_);
+  std::optional<uint16_t> last_sent_seq_ RTC_GUARDED_BY(worker_queue_);
+  std::optional<uint16_t> last_sent_rtx_seq_ RTC_GUARDED_BY(worker_queue_);
 
   SendPacketObserver* const send_packet_observer_;
   StreamDataCountersCallback* const rtp_stats_callback_;
@@ -151,7 +151,7 @@
   StreamDataCounters rtx_rtp_stats_ RTC_GUARDED_BY(worker_queue_);
   // One element per value in RtpPacketMediaType, with index matching value.
   std::vector<BitrateTracker> send_rates_ RTC_GUARDED_BY(worker_queue_);
-  absl::optional<std::pair<FecProtectionParams, FecProtectionParams>>
+  std::optional<std::pair<FecProtectionParams, FecProtectionParams>>
       pending_fec_params_ RTC_GUARDED_BY(worker_queue_);
 
   // Maps sent packets' sequence numbers to a tuple consisting of:
diff --git a/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc
index 1835627..af88f0b 100644
--- a/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc
@@ -11,9 +11,9 @@
 #include "modules/rtp_rtcp/source/rtp_sender_egress.h"
 
 #include <cstdint>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/call/transport.h"
 #include "api/environment/environment.h"
@@ -62,7 +62,7 @@
  public:
   MOCK_METHOD(void,
               OnSendPacket,
-              (absl::optional<uint16_t>, Timestamp, uint32_t),
+              (std::optional<uint16_t>, Timestamp, uint32_t),
               (override));
 };
 
@@ -102,11 +102,11 @@
     RTC_CHECK_NOTREACHED();
   }
 
-  absl::optional<TransmittedPacket> last_packet() { return last_packet_; }
+  std::optional<TransmittedPacket> last_packet() { return last_packet_; }
 
  private:
   DataSize total_data_sent_;
-  absl::optional<TransmittedPacket> last_packet_;
+  std::optional<TransmittedPacket> last_packet_;
   RtpHeaderExtensionMap* const extensions_;
 };
 
@@ -289,7 +289,7 @@
   std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
   sender->SendPacket(std::move(padding), PacedPacketInfo());
 
-  absl::optional<int32_t> offset =
+  std::optional<int32_t> offset =
       transport_.last_packet()->packet.GetExtension<TransmissionOffset>();
   EXPECT_EQ(offset, 0);
 }
@@ -375,7 +375,7 @@
   std::unique_ptr<RtpSenderEgress> sender = CreateRtpSenderEgress();
 
   EXPECT_CALL(send_packet_observer_,
-              OnSendPacket(Eq(absl::nullopt), clock_->CurrentTime(), kSsrc));
+              OnSendPacket(Eq(std::nullopt), clock_->CurrentTime(), kSsrc));
   sender->SendPacket(BuildRtpPacket(), PacedPacketInfo());
 }
 
diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
index bd434dd..bfe71d4 100644
--- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
@@ -174,7 +174,7 @@
   RateLimiter retransmission_rate_limiter_;
   FlexfecSender flexfec_sender_;
 
-  absl::optional<PacketSequencer> sequencer_;
+  std::optional<PacketSequencer> sequencer_;
   std::unique_ptr<RtpPacketHistory> packet_history_;
   std::unique_ptr<RTPSender> rtp_sender_;
 
@@ -434,7 +434,7 @@
 
 TEST_F(RtpSenderTest, RequiresRtxSsrcToEnableRtx) {
   RtpRtcpInterface::Configuration config = GetDefaultConfig();
-  config.rtx_send_ssrc = absl::nullopt;
+  config.rtx_send_ssrc = std::nullopt;
   RTPSender rtp_sender(config, packet_history_.get(), config.paced_sender);
   rtp_sender.SetRtxPayloadType(kRtxPayload, kPayload);
 
@@ -1369,7 +1369,7 @@
   RTPSenderVideo rtp_sender_video(video_config);
 
   const uint8_t kPayloadType = 127;
-  const absl::optional<VideoCodecType> kCodecType =
+  const std::optional<VideoCodecType> kCodecType =
       VideoCodecType::kVideoCodecGeneric;
 
   const uint32_t kCaptureTimeMsToRtpTimestamp = 90;  // 90 kHz clock
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc
index fc39225..e505e28 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -100,18 +100,18 @@
   return true;
 }
 
-absl::optional<VideoPlayoutDelay> LoadVideoPlayoutDelayOverride(
+std::optional<VideoPlayoutDelay> LoadVideoPlayoutDelayOverride(
     const FieldTrialsView* key_value_config) {
   RTC_DCHECK(key_value_config);
-  FieldTrialOptional<int> playout_delay_min_ms("min_ms", absl::nullopt);
-  FieldTrialOptional<int> playout_delay_max_ms("max_ms", absl::nullopt);
+  FieldTrialOptional<int> playout_delay_min_ms("min_ms", std::nullopt);
+  FieldTrialOptional<int> playout_delay_max_ms("max_ms", std::nullopt);
   ParseFieldTrial({&playout_delay_max_ms, &playout_delay_min_ms},
                   key_value_config->Lookup("WebRTC-ForceSendPlayoutDelay"));
   return playout_delay_max_ms && playout_delay_min_ms
-             ? absl::make_optional<VideoPlayoutDelay>(
+             ? std::make_optional<VideoPlayoutDelay>(
                    TimeDelta::Millis(*playout_delay_min_ms),
                    TimeDelta::Millis(*playout_delay_max_ms))
-             : absl::nullopt;
+             : std::nullopt;
 }
 
 // Some packets can be skipped and the stream can still be decoded. Those
@@ -456,7 +456,7 @@
 }
 
 bool RTPSenderVideo::SendVideo(int payload_type,
-                               absl::optional<VideoCodecType> codec_type,
+                               std::optional<VideoCodecType> codec_type,
                                uint32_t rtp_timestamp,
                                Timestamp capture_time,
                                rtc::ArrayView<const uint8_t> payload,
@@ -746,7 +746,7 @@
 }
 
 bool RTPSenderVideo::SendEncodedImage(int payload_type,
-                                      absl::optional<VideoCodecType> codec_type,
+                                      std::optional<VideoCodecType> codec_type,
                                       uint32_t rtp_timestamp,
                                       const EncodedImage& encoded_image,
                                       RTPVideoHeader video_header,
@@ -832,7 +832,7 @@
       Timestamp expected_next_frame_time = Timestamp::PlusInfinity();
       for (int i = temporal_id - 1; i >= 0; --i) {
         TemporalLayerStats* stats = &frame_stats_by_temporal_layer_[i];
-        absl::optional<Frequency> rate = stats->frame_rate.Rate(now);
+        std::optional<Frequency> rate = stats->frame_rate.Rate(now);
         if (rate > Frequency::Zero()) {
           Timestamp tl_next = stats->last_frame_time + 1 / *rate;
           if (tl_next - now > -expected_retransmission_time &&
@@ -856,7 +856,7 @@
 
 void RTPSenderVideo::MaybeUpdateCurrentPlayoutDelay(
     const RTPVideoHeader& header) {
-  absl::optional<VideoPlayoutDelay> requested_delay =
+  std::optional<VideoPlayoutDelay> requested_delay =
       forced_playout_delay_.has_value() ? forced_playout_delay_
                                         : header.playout_delay;
 
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.h b/modules/rtp_rtcp/source/rtp_sender_video.h
index fa5f3b6..4e8abf8 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.h
+++ b/modules/rtp_rtcp/source/rtp_sender_video.h
@@ -13,10 +13,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/frame_transformer_interface.h"
 #include "api/scoped_refptr.h"
@@ -77,12 +77,12 @@
     RTPSender* rtp_sender = nullptr;
     // Some FEC data is duplicated here in preparation of moving FEC to
     // the egress stage.
-    absl::optional<VideoFecGenerator::FecType> fec_type;
+    std::optional<VideoFecGenerator::FecType> fec_type;
     size_t fec_overhead_bytes = 0;  // Per packet max FEC overhead.
     FrameEncryptorInterface* frame_encryptor = nullptr;
     bool require_frame_encryption = false;
     bool enable_retransmit_all_layers = false;
-    absl::optional<int> red_payload_type;
+    std::optional<int> red_payload_type;
     const FieldTrialsView* field_trials = nullptr;
     rtc::scoped_refptr<FrameTransformerInterface> frame_transformer;
     TaskQueueFactory* task_queue_factory = nullptr;
@@ -98,7 +98,7 @@
   // video encoder, excluding any additional overhead.
   // Calls to this method are assumed to be externally serialized.
   bool SendVideo(int payload_type,
-                 absl::optional<VideoCodecType> codec_type,
+                 std::optional<VideoCodecType> codec_type,
                  uint32_t rtp_timestamp,
                  Timestamp capture_time,
                  rtc::ArrayView<const uint8_t> payload,
@@ -108,7 +108,7 @@
                  std::vector<uint32_t> csrcs) override;
 
   bool SendEncodedImage(int payload_type,
-                        absl::optional<VideoCodecType> codec_type,
+                        std::optional<VideoCodecType> codec_type,
                         uint32_t rtp_timestamp,
                         const EncodedImage& encoded_image,
                         RTPVideoHeader video_header,
@@ -199,32 +199,32 @@
   rtc::RaceChecker send_checker_;
   int32_t retransmission_settings_ RTC_GUARDED_BY(send_checker_);
   VideoRotation last_rotation_ RTC_GUARDED_BY(send_checker_);
-  absl::optional<ColorSpace> last_color_space_ RTC_GUARDED_BY(send_checker_);
+  std::optional<ColorSpace> last_color_space_ RTC_GUARDED_BY(send_checker_);
   bool transmit_color_space_next_frame_ RTC_GUARDED_BY(send_checker_);
   std::unique_ptr<FrameDependencyStructure> video_structure_
       RTC_GUARDED_BY(send_checker_);
-  absl::optional<VideoLayersAllocation> allocation_
+  std::optional<VideoLayersAllocation> allocation_
       RTC_GUARDED_BY(send_checker_);
   // Flag indicating if we should send `allocation_`.
   SendVideoLayersAllocation send_allocation_ RTC_GUARDED_BY(send_checker_);
-  absl::optional<VideoLayersAllocation> last_full_sent_allocation_
+  std::optional<VideoLayersAllocation> last_full_sent_allocation_
       RTC_GUARDED_BY(send_checker_);
 
   // Current target playout delay.
-  absl::optional<VideoPlayoutDelay> current_playout_delay_
+  std::optional<VideoPlayoutDelay> current_playout_delay_
       RTC_GUARDED_BY(send_checker_);
   // Flag indicating if we need to send `current_playout_delay_` in order
   // to guarantee it gets delivered.
   bool playout_delay_pending_;
   // Set by the field trial WebRTC-ForceSendPlayoutDelay to override the playout
   // delay of outgoing video frames.
-  const absl::optional<VideoPlayoutDelay> forced_playout_delay_;
+  const std::optional<VideoPlayoutDelay> forced_playout_delay_;
 
   // Should never be held when calling out of this class.
   Mutex mutex_;
 
-  const absl::optional<int> red_payload_type_;
-  absl::optional<VideoFecGenerator::FecType> fec_type_;
+  const std::optional<int> red_payload_type_;
+  std::optional<VideoFecGenerator::FecType> fec_type_;
   const size_t fec_overhead_bytes_;  // Per packet max FEC overhead.
 
   mutable Mutex stats_mutex_;
diff --git a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc
index 8c24160..b49468b 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc
@@ -13,11 +13,11 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/frame_transformer_interface.h"
 #include "api/scoped_refptr.h"
@@ -51,7 +51,7 @@
   TransformableVideoSenderFrame(const EncodedImage& encoded_image,
                                 const RTPVideoHeader& video_header,
                                 int payload_type,
-                                absl::optional<VideoCodecType> codec_type,
+                                std::optional<VideoCodecType> codec_type,
                                 uint32_t rtp_timestamp,
                                 TimeDelta expected_retransmission_time,
                                 uint32_t ssrc,
@@ -112,9 +112,9 @@
 
   const RTPVideoHeader& GetHeader() const { return header_; }
   uint8_t GetPayloadType() const override { return payload_type_; }
-  absl::optional<VideoCodecType> GetCodecType() const { return codec_type_; }
+  std::optional<VideoCodecType> GetCodecType() const { return codec_type_; }
   Timestamp GetCaptureTime() const { return capture_time_; }
-  absl::optional<Timestamp> GetCaptureTimeIdentifier() const override {
+  std::optional<Timestamp> GetCaptureTimeIdentifier() const override {
     return capture_time_identifier_;
   }
 
@@ -137,10 +137,10 @@
   RTPVideoHeader header_;
   const VideoFrameType frame_type_;
   const uint8_t payload_type_;
-  const absl::optional<VideoCodecType> codec_type_ = absl::nullopt;
+  const std::optional<VideoCodecType> codec_type_ = std::nullopt;
   uint32_t timestamp_;
   const Timestamp capture_time_;
-  const absl::optional<Timestamp> capture_time_identifier_;
+  const std::optional<Timestamp> capture_time_identifier_;
   const TimeDelta expected_retransmission_time_;
 
   uint32_t ssrc_;
@@ -166,7 +166,7 @@
 
 bool RTPSenderVideoFrameTransformerDelegate::TransformFrame(
     int payload_type,
-    absl::optional<VideoCodecType> codec_type,
+    std::optional<VideoCodecType> codec_type,
     uint32_t rtp_timestamp,
     const EncodedImage& encoded_image,
     RTPVideoHeader video_header,
diff --git a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h
index a32c708..3580d84 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h
+++ b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h
@@ -33,7 +33,7 @@
 class RTPVideoFrameSenderInterface {
  public:
   virtual bool SendVideo(int payload_type,
-                         absl::optional<VideoCodecType> codec_type,
+                         std::optional<VideoCodecType> codec_type,
                          uint32_t rtp_timestamp,
                          Timestamp capture_time,
                          rtc::ArrayView<const uint8_t> payload,
@@ -66,7 +66,7 @@
 
   // Delegates the call to FrameTransformerInterface::TransformFrame.
   bool TransformFrame(int payload_type,
-                      absl::optional<VideoCodecType> codec_type,
+                      std::optional<VideoCodecType> codec_type,
                       uint32_t rtp_timestamp,
                       const EncodedImage& encoded_image,
                       RTPVideoHeader video_header,
diff --git a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc
index 586836a..4224b8c 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc
@@ -33,7 +33,7 @@
   MOCK_METHOD(bool,
               SendVideo,
               (int payload_type,
-               absl::optional<VideoCodecType> codec_type,
+               std::optional<VideoCodecType> codec_type,
                uint32_t rtp_timestamp,
                Timestamp capture_time,
                rtc::ArrayView<const uint8_t> payload,
@@ -258,7 +258,7 @@
   rtc::Event event;
   EXPECT_CALL(
       test_sender_,
-      SendVideo(payload_type, absl::make_optional(kVideoCodecVP8), timestamp,
+      SendVideo(payload_type, std::make_optional(kVideoCodecVP8), timestamp,
                 /*capture_time=*/Timestamp::MinusInfinity(), buffer, _, _,
                 /*expected_retransmission_time=*/TimeDelta::Millis(10),
                 frame_csrcs))
diff --git a/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc
index ee7d18b..8c8091f 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc
@@ -1268,7 +1268,7 @@
       kPayload, kType, kTimestamp, kAbsoluteCaptureTimestamp, kFrame,
       sizeof(kFrame), hdr, kDefaultExpectedRetransmissionTime, {});
 
-  absl::optional<AbsoluteCaptureTime> absolute_capture_time;
+  std::optional<AbsoluteCaptureTime> absolute_capture_time;
 
   // It is expected that one and only one of the packets sent on this video
   // frame has absolute capture time header extension.
@@ -1293,7 +1293,7 @@
 TEST_F(RtpSenderVideoTest, AbsoluteCaptureTimeWithExtensionProvided) {
   constexpr AbsoluteCaptureTime kAbsoluteCaptureTime = {
       123,
-      absl::optional<int64_t>(456),
+      std::optional<int64_t>(456),
   };
   uint8_t kFrame[kMaxPacketLength];
   rtp_module_.RegisterRtpHeaderExtension(AbsoluteCaptureTimeExtension::Uri(),
@@ -1307,7 +1307,7 @@
                                sizeof(kFrame), hdr,
                                kDefaultExpectedRetransmissionTime, {});
 
-  absl::optional<AbsoluteCaptureTime> absolute_capture_time;
+  std::optional<AbsoluteCaptureTime> absolute_capture_time;
 
   // It is expected that one and only one of the packets sent on this video
   // frame has absolute capture time header extension.
@@ -1360,7 +1360,7 @@
 
   // Set playout delay on a non-discardable frame, the extension should still
   // be populated since dilvery wasn't guaranteed on the last one.
-  hdr.playout_delay = absl::nullopt;  // Indicates "no change".
+  hdr.playout_delay = std::nullopt;  // Indicates "no change".
   vp8_header.temporalIdx = 0;
   rtp_sender_video_->SendVideo(
       kPayload, kType, kTimestamp, fake_clock_.CurrentTime(), kFrame,
@@ -1428,7 +1428,7 @@
   RTPVideoHeader video_header;
   video_header.frame_type = VideoFrameType::kVideoFrameKey;
   ASSERT_TRUE(rtp_sender_video_->SendVideo(
-      kPayloadType, absl::nullopt, 1234, fake_clock_.CurrentTime(), kPayload,
+      kPayloadType, std::nullopt, 1234, fake_clock_.CurrentTime(), kPayload,
       sizeof(kPayload), video_header, TimeDelta::PlusInfinity(), {}));
 
   rtc::ArrayView<const uint8_t> sent_payload =
diff --git a/modules/rtp_rtcp/source/rtp_sequence_number_map.cc b/modules/rtp_rtcp/source/rtp_sequence_number_map.cc
index 441429d..99824da 100644
--- a/modules/rtp_rtcp/source/rtp_sequence_number_map.cc
+++ b/modules/rtp_rtcp/source/rtp_sequence_number_map.cc
@@ -94,7 +94,7 @@
   }
 }
 
-absl::optional<RtpSequenceNumberMap::Info> RtpSequenceNumberMap::Get(
+std::optional<RtpSequenceNumberMap::Info> RtpSequenceNumberMap::Get(
     uint16_t sequence_number) const {
   // To make the binary search easier to understand, we use the fact that
   // adding a constant offset to all elements, as well as to the searched
@@ -105,7 +105,7 @@
   // element to 0 would serve this purpose.
 
   if (associations_.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   const uint16_t offset =
@@ -118,8 +118,8 @@
   const auto elem = absl::c_lower_bound(associations_, sequence_number, cmp);
 
   return elem != associations_.end() && elem->sequence_number == sequence_number
-             ? absl::optional<Info>(elem->info)
-             : absl::nullopt;
+             ? std::optional<Info>(elem->info)
+             : std::nullopt;
 }
 
 size_t RtpSequenceNumberMap::AssociationCountForTesting() const {
diff --git a/modules/rtp_rtcp/source/rtp_sequence_number_map.h b/modules/rtp_rtcp/source/rtp_sequence_number_map.h
index 8a036c2..d2bbd18 100644
--- a/modules/rtp_rtcp/source/rtp_sequence_number_map.h
+++ b/modules/rtp_rtcp/source/rtp_sequence_number_map.h
@@ -14,8 +14,7 @@
 #include <cstddef>
 #include <cstdint>
 #include <deque>
-
-#include "absl/types/optional.h"
+#include <optional>
 
 namespace webrtc {
 
@@ -57,7 +56,7 @@
                    size_t packet_count,
                    uint32_t timestamp);
 
-  absl::optional<Info> Get(uint16_t sequence_number) const;
+  std::optional<Info> Get(uint16_t sequence_number) const;
 
   size_t AssociationCountForTesting() const;
 
diff --git a/modules/rtp_rtcp/source/rtp_sequence_number_map_unittest.cc b/modules/rtp_rtcp/source/rtp_sequence_number_map_unittest.cc
index 78c9e4a..e90f45b 100644
--- a/modules/rtp_rtcp/source/rtp_sequence_number_map_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sequence_number_map_unittest.cc
@@ -14,11 +14,11 @@
 #include <iterator>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <tuple>
 #include <vector>
 
 #include "absl/memory/memory.h"
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/sequence_number_util.h"
 #include "rtc_base/random.h"
diff --git a/modules/rtp_rtcp/source/rtp_video_header.cc b/modules/rtp_rtcp/source/rtp_video_header.cc
index c4ab609..c37cc65 100644
--- a/modules/rtp_rtcp/source/rtp_video_header.cc
+++ b/modules/rtp_rtcp/source/rtp_video_header.cc
@@ -76,7 +76,7 @@
   rotation = metadata.GetRotation();
   content_type = metadata.GetContentType();
   if (!metadata.GetFrameId().has_value()) {
-    generic = absl::nullopt;
+    generic = std::nullopt;
   } else {
     generic.emplace();
     generic->frame_id = metadata.GetFrameId().value();
diff --git a/modules/rtp_rtcp/source/rtp_video_header.h b/modules/rtp_rtcp/source/rtp_video_header.h
index 3100d4d..20ad4b2 100644
--- a/modules/rtp_rtcp/source/rtp_video_header.h
+++ b/modules/rtp_rtcp/source/rtp_video_header.h
@@ -12,9 +12,9 @@
 
 #include <bitset>
 #include <cstdint>
+#include <optional>
 
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/rtp_headers.h"
 #include "api/transport/rtp/dependency_descriptor.h"
@@ -69,7 +69,7 @@
   VideoFrameMetadata GetAsMetadata() const;
   void SetFromMetadata(const VideoFrameMetadata& metadata);
 
-  absl::optional<GenericDescriptorInfo> generic;
+  std::optional<GenericDescriptorInfo> generic;
 
   VideoFrameType frame_type = VideoFrameType::kEmptyFrame;
   uint16_t width = 0;
@@ -82,18 +82,18 @@
   uint8_t simulcastIdx = 0;
   VideoCodecType codec = VideoCodecType::kVideoCodecGeneric;
 
-  absl::optional<VideoPlayoutDelay> playout_delay;
+  std::optional<VideoPlayoutDelay> playout_delay;
   VideoSendTiming video_timing;
-  absl::optional<ColorSpace> color_space;
+  std::optional<ColorSpace> color_space;
   // This field is meant for media quality testing purpose only. When enabled it
   // carries the webrtc::VideoFrame id field from the sender to the receiver.
-  absl::optional<uint16_t> video_frame_tracking_id;
+  std::optional<uint16_t> video_frame_tracking_id;
   RTPVideoTypeHeader video_type_header;
 
   // When provided, is sent as is as an RTP header extension according to
   // http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time.
   // Otherwise, it is derived from other relevant information.
-  absl::optional<AbsoluteCaptureTime> absolute_capture_time;
+  std::optional<AbsoluteCaptureTime> absolute_capture_time;
 };
 
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_video_header_unittest.cc b/modules/rtp_rtcp/source/rtp_video_header_unittest.cc
index 335fa1a..d87a2b5 100644
--- a/modules/rtp_rtcp/source/rtp_video_header_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_video_header_unittest.cc
@@ -117,7 +117,7 @@
 
 TEST(RTPVideoHeaderTest, FrameId_FromMetadataWhenFrameIdIsMissing) {
   VideoFrameMetadata metadata;
-  metadata.SetFrameId(absl::nullopt);
+  metadata.SetFrameId(std::nullopt);
   RTPVideoHeader video_header = RTPVideoHeader::FromMetadata(metadata);
   EXPECT_FALSE(video_header.generic.has_value());
 }
diff --git a/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc b/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc
index 192e239..6fd467e 100644
--- a/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc
@@ -50,7 +50,7 @@
       /*last_packet_received_time=*/5, /*rtp_timestamp=*/6, /*ntp_time_ms=*/7,
       VideoSendTiming(), /*payload_type=*/8, video_header.codec,
       kVideoRotation_0, VideoContentType::UNSPECIFIED, video_header,
-      absl::nullopt, RtpPacketInfos({packet_info}),
+      std::nullopt, RtpPacketInfos({packet_info}),
       EncodedImageBuffer::Create(0));
 }
 
@@ -222,8 +222,8 @@
   // Checks that the recieved RTPFrameObject has the new metadata.
   EXPECT_CALL(receiver, ManageFrame)
       .WillOnce([&](std::unique_ptr<RtpFrameObject> frame) {
-        const absl::optional<RTPVideoHeader::GenericDescriptorInfo>&
-            descriptor = frame->GetRtpVideoHeader().generic;
+        const std::optional<RTPVideoHeader::GenericDescriptorInfo>& descriptor =
+            frame->GetRtpVideoHeader().generic;
         if (!descriptor.has_value()) {
           ADD_FAILURE() << "GenericDescriptorInfo in RTPVideoHeader doesn't "
                            "have a value.";
diff --git a/modules/rtp_rtcp/source/source_tracker.h b/modules/rtp_rtcp/source/source_tracker.h
index 30a5b8a..9d39599 100644
--- a/modules/rtp_rtcp/source/source_tracker.h
+++ b/modules/rtp_rtcp/source/source_tracker.h
@@ -13,11 +13,11 @@
 
 #include <cstdint>
 #include <list>
+#include <optional>
 #include <unordered_map>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/rtp_packet_infos.h"
 #include "api/task_queue/pending_task_safety_flag.h"
 #include "api/task_queue/task_queue_base.h"
@@ -91,19 +91,19 @@
     // the most recent packet used to assemble the frame associated with
     // `timestamp`. May be absent. Only relevant for audio receivers. See the
     // specs for `RTCRtpContributingSource` for more info.
-    absl::optional<uint8_t> audio_level;
+    std::optional<uint8_t> audio_level;
 
     // Absolute capture time header extension received or interpolated from the
     // most recent packet used to assemble the frame. For more info see
     // https://webrtc.org/experiments/rtp-hdrext/abs-capture-time/
-    absl::optional<AbsoluteCaptureTime> absolute_capture_time;
+    std::optional<AbsoluteCaptureTime> absolute_capture_time;
 
     // Clock offset between the local clock and the capturer's clock.
     // Do not confuse with `AbsoluteCaptureTime::estimated_capture_clock_offset`
     // which instead represents the clock offset between a remote sender and the
     // capturer. The following holds:
     //   Capture's NTP Clock = Local NTP Clock + Local-Capture Clock Offset
-    absl::optional<TimeDelta> local_capture_clock_offset;
+    std::optional<TimeDelta> local_capture_clock_offset;
 
     // RTP timestamp of the most recent packet used to assemble the frame
     // associated with `timestamp`.
diff --git a/modules/rtp_rtcp/source/source_tracker_unittest.cc b/modules/rtp_rtcp/source/source_tracker_unittest.cc
index e14a389..32ac711 100644
--- a/modules/rtp_rtcp/source/source_tracker_unittest.cc
+++ b/modules/rtp_rtcp/source/source_tracker_unittest.cc
@@ -12,13 +12,13 @@
 
 #include <algorithm>
 #include <list>
+#include <optional>
 #include <random>
 #include <set>
 #include <tuple>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/rtp_headers.h"
 #include "api/rtp_packet_info.h"
 #include "api/rtp_packet_infos.h"
@@ -167,9 +167,9 @@
     return std::uniform_int_distribution<uint32_t>()(generator_);
   }
 
-  absl::optional<uint8_t> GenerateAudioLevel() {
+  std::optional<uint8_t> GenerateAudioLevel() {
     if (std::bernoulli_distribution(0.25)(generator_)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     // Workaround for std::uniform_int_distribution<uint8_t> not being allowed.
@@ -177,9 +177,9 @@
         std::uniform_int_distribution<uint16_t>()(generator_));
   }
 
-  absl::optional<AbsoluteCaptureTime> GenerateAbsoluteCaptureTime() {
+  std::optional<AbsoluteCaptureTime> GenerateAbsoluteCaptureTime() {
     if (std::bernoulli_distribution(0.25)(generator_)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     AbsoluteCaptureTime value;
@@ -188,7 +188,7 @@
         std::uniform_int_distribution<uint64_t>()(generator_);
 
     if (std::bernoulli_distribution(0.5)(generator_)) {
-      value.estimated_capture_clock_offset = absl::nullopt;
+      value.estimated_capture_clock_offset = std::nullopt;
     } else {
       value.estimated_capture_clock_offset =
           std::uniform_int_distribution<int64_t>()(generator_);
@@ -197,9 +197,9 @@
     return value;
   }
 
-  absl::optional<TimeDelta> GenerateLocalCaptureClockOffset() {
+  std::optional<TimeDelta> GenerateLocalCaptureClockOffset() {
     if (std::bernoulli_distribution(0.5)(generator_)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return TimeDelta::Millis(
         UQ32x32ToInt64Ms(std::uniform_int_distribution<int64_t>()(generator_)));
@@ -263,12 +263,12 @@
   constexpr uint32_t kCsrcs2 = 22;
   constexpr uint32_t kRtpTimestamp0 = 40;
   constexpr uint32_t kRtpTimestamp1 = 50;
-  constexpr absl::optional<uint8_t> kAudioLevel0 = 50;
-  constexpr absl::optional<uint8_t> kAudioLevel1 = 20;
-  constexpr absl::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime =
+  constexpr std::optional<uint8_t> kAudioLevel0 = 50;
+  constexpr std::optional<uint8_t> kAudioLevel1 = 20;
+  constexpr std::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime =
       AbsoluteCaptureTime{/*absolute_capture_timestamp=*/12,
-                          /*estimated_capture_clock_offset=*/absl::nullopt};
-  constexpr absl::optional<TimeDelta> kLocalCaptureClockOffset = absl::nullopt;
+                          /*estimated_capture_clock_offset=*/std::nullopt};
+  constexpr std::optional<TimeDelta> kLocalCaptureClockOffset = std::nullopt;
   constexpr Timestamp kReceiveTime0 = Timestamp::Millis(60);
   constexpr Timestamp kReceiveTime1 = Timestamp::Millis(70);
 
@@ -318,13 +318,13 @@
   constexpr uint32_t kRtpTimestamp0 = 40;
   constexpr uint32_t kRtpTimestamp1 = 45;
   constexpr uint32_t kRtpTimestamp2 = 50;
-  constexpr absl::optional<uint8_t> kAudioLevel0 = 50;
-  constexpr absl::optional<uint8_t> kAudioLevel1 = 20;
-  constexpr absl::optional<uint8_t> kAudioLevel2 = 10;
-  constexpr absl::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime =
+  constexpr std::optional<uint8_t> kAudioLevel0 = 50;
+  constexpr std::optional<uint8_t> kAudioLevel1 = 20;
+  constexpr std::optional<uint8_t> kAudioLevel2 = 10;
+  constexpr std::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime =
       AbsoluteCaptureTime{/*absolute_capture_timestamp=*/12,
-                          /*estimated_capture_clock_offset=*/absl::nullopt};
-  constexpr absl::optional<TimeDelta> kLocalCaptureClockOffset = absl::nullopt;
+                          /*estimated_capture_clock_offset=*/std::nullopt};
+  constexpr std::optional<TimeDelta> kLocalCaptureClockOffset = std::nullopt;
   constexpr Timestamp kReceiveTime0 = Timestamp::Millis(60);
   constexpr Timestamp kReceiveTime1 = Timestamp::Millis(70);
   constexpr Timestamp kReceiveTime2 = Timestamp::Millis(80);
@@ -382,20 +382,20 @@
   constexpr uint32_t kRtpTimestamp0 = 40;
   constexpr uint32_t kRtpTimestamp1 = 41;
   constexpr uint32_t kRtpTimestamp2 = 42;
-  constexpr absl::optional<uint8_t> kAudioLevel0 = 50;
-  constexpr absl::optional<uint8_t> kAudioLevel1 = absl::nullopt;
-  constexpr absl::optional<uint8_t> kAudioLevel2 = 10;
-  constexpr absl::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime0 =
+  constexpr std::optional<uint8_t> kAudioLevel0 = 50;
+  constexpr std::optional<uint8_t> kAudioLevel1 = std::nullopt;
+  constexpr std::optional<uint8_t> kAudioLevel2 = 10;
+  constexpr std::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime0 =
       AbsoluteCaptureTime{12, 34};
-  constexpr absl::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime1 =
+  constexpr std::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime1 =
       AbsoluteCaptureTime{56, 78};
-  constexpr absl::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime2 =
+  constexpr std::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime2 =
       AbsoluteCaptureTime{89, 90};
-  constexpr absl::optional<TimeDelta> kLocalCaptureClockOffset0 =
+  constexpr std::optional<TimeDelta> kLocalCaptureClockOffset0 =
       TimeDelta::Millis(123);
-  constexpr absl::optional<TimeDelta> kLocalCaptureClockOffset1 =
+  constexpr std::optional<TimeDelta> kLocalCaptureClockOffset1 =
       TimeDelta::Millis(456);
-  constexpr absl::optional<TimeDelta> kLocalCaptureClockOffset2 =
+  constexpr std::optional<TimeDelta> kLocalCaptureClockOffset2 =
       TimeDelta::Millis(789);
   constexpr Timestamp kReceiveTime0 = Timestamp::Millis(60);
   constexpr Timestamp kReceiveTime1 = Timestamp::Millis(61);
@@ -487,15 +487,15 @@
   constexpr uint32_t kCsrcs2 = 22;
   constexpr uint32_t kRtpTimestamp0 = 40;
   constexpr uint32_t kRtpTimestamp1 = 41;
-  constexpr absl::optional<uint8_t> kAudioLevel0 = 50;
-  constexpr absl::optional<uint8_t> kAudioLevel1 = absl::nullopt;
-  constexpr absl::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime0 =
+  constexpr std::optional<uint8_t> kAudioLevel0 = 50;
+  constexpr std::optional<uint8_t> kAudioLevel1 = std::nullopt;
+  constexpr std::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime0 =
       AbsoluteCaptureTime{12, 34};
-  constexpr absl::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime1 =
+  constexpr std::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime1 =
       AbsoluteCaptureTime{56, 78};
-  constexpr absl::optional<TimeDelta> kLocalCaptureClockOffset0 =
+  constexpr std::optional<TimeDelta> kLocalCaptureClockOffset0 =
       TimeDelta::Millis(123);
-  constexpr absl::optional<TimeDelta> kLocalCaptureClockOffset1 =
+  constexpr std::optional<TimeDelta> kLocalCaptureClockOffset1 =
       TimeDelta::Millis(456);
   constexpr Timestamp kReceiveTime0 = Timestamp::Millis(60);
   constexpr Timestamp kReceiveTime1 = Timestamp::Millis(61);
diff --git a/modules/rtp_rtcp/source/ulpfec_generator.h b/modules/rtp_rtcp/source/ulpfec_generator.h
index 64d5034..bf82878 100644
--- a/modules/rtp_rtcp/source/ulpfec_generator.h
+++ b/modules/rtp_rtcp/source/ulpfec_generator.h
@@ -42,7 +42,7 @@
   FecType GetFecType() const override {
     return VideoFecGenerator::FecType::kUlpFec;
   }
-  absl::optional<uint32_t> FecSsrc() override { return absl::nullopt; }
+  std::optional<uint32_t> FecSsrc() override { return std::nullopt; }
 
   void SetProtectionParameters(const FecProtectionParams& delta_params,
                                const FecProtectionParams& key_params) override;
@@ -60,7 +60,7 @@
   // Current rate of FEC packets generated, including all RTP-level headers.
   DataRate CurrentFecRate() const override;
 
-  absl::optional<RtpState> GetRtpState() override { return absl::nullopt; }
+  std::optional<RtpState> GetRtpState() override { return std::nullopt; }
 
   // Currently used protection params.
   const FecProtectionParams& CurrentParams() const;
@@ -108,7 +108,7 @@
       RTC_GUARDED_BY(race_checker_);
   ForwardErrorCorrection::PacketList media_packets_
       RTC_GUARDED_BY(race_checker_);
-  absl::optional<RtpPacketToSend> last_media_packet_
+  std::optional<RtpPacketToSend> last_media_packet_
       RTC_GUARDED_BY(race_checker_);
   std::list<ForwardErrorCorrection::Packet*> generated_fec_packets_
       RTC_GUARDED_BY(race_checker_);
@@ -118,7 +118,7 @@
   bool media_contains_keyframe_ RTC_GUARDED_BY(race_checker_);
 
   mutable Mutex mutex_;
-  absl::optional<Params> pending_params_ RTC_GUARDED_BY(mutex_);
+  std::optional<Params> pending_params_ RTC_GUARDED_BY(mutex_);
   BitrateTracker fec_bitrate_ RTC_GUARDED_BY(mutex_);
 };
 
diff --git a/modules/rtp_rtcp/source/video_fec_generator.h b/modules/rtp_rtcp/source/video_fec_generator.h
index 38e4103..aff0ae9 100644
--- a/modules/rtp_rtcp/source/video_fec_generator.h
+++ b/modules/rtp_rtcp/source/video_fec_generator.h
@@ -28,7 +28,7 @@
   enum class FecType { kFlexFec, kUlpFec };
   virtual FecType GetFecType() const = 0;
   // Returns the SSRC used for FEC packets (i.e. FlexFec SSRC).
-  virtual absl::optional<uint32_t> FecSsrc() = 0;
+  virtual std::optional<uint32_t> FecSsrc() = 0;
   // Returns the overhead, in bytes per packet, for FEC (and possibly RED).
   virtual size_t MaxPacketOverhead() const = 0;
   // Current rate of FEC packets generated, including all RTP-level headers.
@@ -47,7 +47,7 @@
   virtual std::vector<std::unique_ptr<RtpPacketToSend>> GetFecPackets() = 0;
   // Only called on the VideoSendStream queue, after operation has shut down,
   // and only populated if there is an RtpState (e.g. FlexFec).
-  virtual absl::optional<RtpState> GetRtpState() = 0;
+  virtual std::optional<RtpState> GetRtpState() = 0;
 };
 
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer.h b/modules/rtp_rtcp/source/video_rtp_depacketizer.h
index 2266120..adf6dc6 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer.h
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/array_view.h"
 #include "api/scoped_refptr.h"
 #include "api/video/encoded_image.h"
@@ -30,7 +31,7 @@
   };
 
   virtual ~VideoRtpDepacketizer() = default;
-  virtual absl::optional<ParsedRtpPayload> Parse(
+  virtual std::optional<ParsedRtpPayload> Parse(
       rtc::CopyOnWriteBuffer rtp_payload) = 0;
   virtual rtc::scoped_refptr<EncodedImageBuffer> AssembleFrame(
       rtc::ArrayView<const rtc::ArrayView<const uint8_t>> rtp_payloads);
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_av1.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_av1.cc
index 30bbbc5..6f70297 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_av1.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_av1.cc
@@ -355,19 +355,19 @@
   return bitstream;
 }
 
-absl::optional<VideoRtpDepacketizer::ParsedRtpPayload>
+std::optional<VideoRtpDepacketizer::ParsedRtpPayload>
 VideoRtpDepacketizerAv1::Parse(rtc::CopyOnWriteBuffer rtp_payload) {
   if (rtp_payload.size() == 0) {
     RTC_DLOG(LS_ERROR) << "Empty rtp payload.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   uint8_t aggregation_header = rtp_payload.cdata()[0];
   if (RtpStartsNewCodedVideoSequence(aggregation_header) &&
       RtpStartsWithFragment(aggregation_header)) {
     // new coded video sequence can't start from an OBU fragment.
-    return absl::nullopt;
+    return std::nullopt;
   }
-  absl::optional<ParsedRtpPayload> parsed(absl::in_place);
+  std::optional<ParsedRtpPayload> parsed(absl::in_place);
 
   // To assemble frame, all of the rtp payload is required, including
   // aggregation header.
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_av1.h b/modules/rtp_rtcp/source/video_rtp_depacketizer_av1.h
index ac8c7e6..ed998d6 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_av1.h
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_av1.h
@@ -14,7 +14,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/array_view.h"
 #include "api/scoped_refptr.h"
 #include "api/video/encoded_image.h"
@@ -34,7 +35,7 @@
       rtc::ArrayView<const rtc::ArrayView<const uint8_t>> rtp_payloads)
       override;
 
-  absl::optional<ParsedRtpPayload> Parse(
+  std::optional<ParsedRtpPayload> Parse(
       rtc::CopyOnWriteBuffer rtp_payload) override;
 };
 
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_av1_unittest.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_av1_unittest.cc
index e9ad1a1..94cbbe4 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_av1_unittest.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_av1_unittest.cc
@@ -30,7 +30,7 @@
   const uint8_t packet[] = {(uint8_t{1} << 7) | kObuCountOne, 1, 2, 3, 4};
   rtc::CopyOnWriteBuffer rtp_payload(packet);
   VideoRtpDepacketizerAv1 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_TRUE(parsed);
   EXPECT_EQ(parsed->video_payload.size(), sizeof(packet));
@@ -44,7 +44,7 @@
       kObuHeaderFrame};  // Value doesn't matter since it is a
                          // continuation of the OBU from previous packet.
   VideoRtpDepacketizerAv1 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtc::CopyOnWriteBuffer(packet));
   ASSERT_TRUE(parsed);
   EXPECT_FALSE(parsed->video_header.is_first_packet_in_frame);
@@ -54,7 +54,7 @@
      ParseTreatsNoContinuationFlagAsBeginningOfFrame) {
   const uint8_t packet[] = {(uint8_t{0} << 7) | kObuCountOne, kObuHeaderFrame};
   VideoRtpDepacketizerAv1 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtc::CopyOnWriteBuffer(packet));
   ASSERT_TRUE(parsed);
   EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
@@ -64,7 +64,7 @@
   const uint8_t packet[] = {(uint8_t{1} << 6) | kObuCountOne, kObuHeaderFrame};
   rtc::CopyOnWriteBuffer rtp_payload(packet);
   VideoRtpDepacketizerAv1 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_TRUE(parsed);
   EXPECT_FALSE(parsed->video_header.is_last_packet_in_frame);
@@ -73,7 +73,7 @@
 TEST(VideoRtpDepacketizerAv1Test, ParseTreatsNoWillContinueFlagAsEndOfFrame) {
   const uint8_t packet[] = {(uint8_t{0} << 6) | kObuCountOne, kObuHeaderFrame};
   VideoRtpDepacketizerAv1 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtc::CopyOnWriteBuffer(packet));
   ASSERT_TRUE(parsed);
   EXPECT_TRUE(parsed->video_header.is_last_packet_in_frame);
@@ -84,7 +84,7 @@
   const uint8_t packet[] = {(uint8_t{1} << 3) | kObuCountOne,
                             kObuHeaderSequenceHeader};
   VideoRtpDepacketizerAv1 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtc::CopyOnWriteBuffer(packet));
   ASSERT_TRUE(parsed);
   EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
@@ -97,7 +97,7 @@
   const uint8_t packet[] = {(uint8_t{0} << 3) | kObuCountOne,
                             kObuHeaderSequenceHeader};
   VideoRtpDepacketizerAv1 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtc::CopyOnWriteBuffer(packet));
   ASSERT_TRUE(parsed);
   EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_generic.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_generic.cc
index 6010771..ec8993b 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_generic.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_generic.cc
@@ -13,9 +13,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "modules/rtp_rtcp/source/rtp_video_header.h"
 #include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
 #include "rtc_base/copy_on_write_buffer.h"
@@ -33,13 +33,13 @@
 constexpr size_t kExtendedHeaderLength = 2;
 }  // namespace
 
-absl::optional<VideoRtpDepacketizer::ParsedRtpPayload>
+std::optional<VideoRtpDepacketizer::ParsedRtpPayload>
 VideoRtpDepacketizerGeneric::Parse(rtc::CopyOnWriteBuffer rtp_payload) {
   if (rtp_payload.size() == 0) {
     RTC_LOG(LS_WARNING) << "Empty payload.";
-    return absl::nullopt;
+    return std::nullopt;
   }
-  absl::optional<ParsedRtpPayload> parsed(absl::in_place);
+  std::optional<ParsedRtpPayload> parsed(absl::in_place);
   const uint8_t* payload_data = rtp_payload.cdata();
 
   uint8_t generic_header = payload_data[0];
@@ -57,7 +57,7 @@
   if (generic_header & kExtendedHeaderBit) {
     if (rtp_payload.size() < offset + kExtendedHeaderLength) {
       RTC_LOG(LS_WARNING) << "Too short payload for generic header.";
-      return absl::nullopt;
+      return std::nullopt;
     }
     parsed->video_header.video_type_header
         .emplace<RTPVideoHeaderLegacyGeneric>()
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_generic.h b/modules/rtp_rtcp/source/video_rtp_depacketizer_generic.h
index 27056da..a85bd43 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_generic.h
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_generic.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_GENERIC_H_
 #define MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_GENERIC_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
 #include "rtc_base/copy_on_write_buffer.h"
 
@@ -21,7 +22,7 @@
  public:
   ~VideoRtpDepacketizerGeneric() override = default;
 
-  absl::optional<ParsedRtpPayload> Parse(
+  std::optional<ParsedRtpPayload> Parse(
       rtc::CopyOnWriteBuffer rtp_payload) override;
 };
 
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_generic_unittest.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_generic_unittest.cc
index 860ddab..7f4b83a 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_generic_unittest.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_generic_unittest.cc
@@ -12,7 +12,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "rtc_base/copy_on_write_buffer.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
@@ -28,11 +29,11 @@
   rtc::CopyOnWriteBuffer rtp_payload(kPayload);
 
   VideoRtpDepacketizerGeneric depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
 
   ASSERT_TRUE(parsed);
-  EXPECT_EQ(parsed->video_header.generic, absl::nullopt);
+  EXPECT_EQ(parsed->video_header.generic, std::nullopt);
   EXPECT_THAT(parsed->video_payload, SizeIs(kRtpPayloadSize - 1));
 }
 
@@ -42,7 +43,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(kPayload);
 
   VideoRtpDepacketizerGeneric depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
 
   ASSERT_TRUE(parsed);
@@ -58,7 +59,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(kPayload);
 
   VideoRtpDepacketizerGeneric depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
 
   ASSERT_TRUE(parsed);
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.cc
index 084b6ac..e8fd911 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.cc
@@ -12,10 +12,10 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "common_video/h264/h264_common.h"
 #include "common_video/h264/pps_parser.h"
@@ -59,10 +59,10 @@
   return true;
 }
 
-absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> ProcessStapAOrSingleNalu(
+std::optional<VideoRtpDepacketizer::ParsedRtpPayload> ProcessStapAOrSingleNalu(
     rtc::CopyOnWriteBuffer rtp_payload) {
   const uint8_t* const payload_data = rtp_payload.cdata();
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload(
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload(
       absl::in_place);
   bool modified_buffer = false;
   parsed_payload->video_payload = rtp_payload;
@@ -82,12 +82,12 @@
     // Skip the StapA header (StapA NAL type + length).
     if (rtp_payload.size() <= kStapAHeaderSize) {
       RTC_LOG(LS_ERROR) << "StapA header truncated.";
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     if (!ParseStapAStartOffsets(nalu_start, nalu_length, &nalu_start_offsets)) {
       RTC_LOG(LS_ERROR) << "StapA packet with incorrect NALU packet lengths.";
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     h264_header.packetization_type = kH264StapA;
@@ -108,7 +108,7 @@
     size_t end_offset = nalu_start_offsets[i + 1] - kLengthFieldSize;
     if (end_offset - start_offset < H264::kNaluTypeSize) {
       RTC_LOG(LS_ERROR) << "STAP-A packet too short";
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     NaluInfo nalu;
@@ -128,7 +128,7 @@
         if (start_offset)
           output_buffer.AppendData(payload_data, start_offset);
 
-        absl::optional<SpsParser::SpsState> sps;
+        std::optional<SpsParser::SpsState> sps;
 
         SpsVuiRewriter::ParseResult result = SpsVuiRewriter::ParseAndRewriteSps(
             nalu_data, &sps, nullptr, &output_buffer,
@@ -136,7 +136,7 @@
         switch (result) {
           case SpsVuiRewriter::ParseResult::kFailure:
             RTC_LOG(LS_WARNING) << "Failed to parse SPS NAL unit.";
-            return absl::nullopt;
+            return std::nullopt;
           case SpsVuiRewriter::ParseResult::kVuiRewritten:
             if (modified_buffer) {
               RTC_LOG(LS_WARNING)
@@ -186,7 +186,7 @@
         } else {
           RTC_LOG(LS_WARNING)
               << "Failed to parse PPS id and SPS id from PPS slice.";
-          return absl::nullopt;
+          return std::nullopt;
         }
         break;
       }
@@ -195,7 +195,7 @@
             VideoFrameType::kVideoFrameKey;
         [[fallthrough]];
       case H264::NaluType::kSlice: {
-        absl::optional<PpsParser::SliceHeader> slice_header =
+        std::optional<PpsParser::SliceHeader> slice_header =
             PpsParser::ParseSliceHeader(nalu_data);
         if (slice_header) {
           nalu.pps_id = slice_header->pic_parameter_set_id;
@@ -205,7 +205,7 @@
         } else {
           RTC_LOG(LS_WARNING) << "Failed to parse PPS id from slice of type: "
                               << static_cast<int>(nalu.type);
-          return absl::nullopt;
+          return std::nullopt;
         }
         break;
       }
@@ -219,7 +219,7 @@
       case H264::NaluType::kStapA:
       case H264::NaluType::kFuA:
         RTC_LOG(LS_WARNING) << "Unexpected STAP-A or FU-A received.";
-        return absl::nullopt;
+        return std::nullopt;
     }
 
     h264_header.nalus.push_back(nalu);
@@ -228,13 +228,13 @@
   return parsed_payload;
 }
 
-absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> ParseFuaNalu(
+std::optional<VideoRtpDepacketizer::ParsedRtpPayload> ParseFuaNalu(
     rtc::CopyOnWriteBuffer rtp_payload) {
   if (rtp_payload.size() < kFuAHeaderSize) {
     RTC_LOG(LS_ERROR) << "FU-A NAL units truncated.";
-    return absl::nullopt;
+    return std::nullopt;
   }
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload(
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload(
       absl::in_place);
   uint8_t fnri = rtp_payload.cdata()[0] & (kH264FBit | kH264NriMask);
   uint8_t original_nal_type = rtp_payload.cdata()[1] & kH264TypeMask;
@@ -247,7 +247,7 @@
   if (first_fragment) {
     if (original_nal_type == H264::NaluType::kIdr ||
         original_nal_type == H264::NaluType::kSlice) {
-      absl::optional<PpsParser::SliceHeader> slice_header =
+      std::optional<PpsParser::SliceHeader> slice_header =
           PpsParser::ParseSliceHeader(rtc::ArrayView<const uint8_t>(rtp_payload)
                                           .subview(2 * kNalHeaderSize));
       if (slice_header) {
@@ -293,11 +293,11 @@
 
 }  // namespace
 
-absl::optional<VideoRtpDepacketizer::ParsedRtpPayload>
+std::optional<VideoRtpDepacketizer::ParsedRtpPayload>
 VideoRtpDepacketizerH264::Parse(rtc::CopyOnWriteBuffer rtp_payload) {
   if (rtp_payload.size() == 0) {
     RTC_LOG(LS_ERROR) << "Empty payload.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   uint8_t nal_type = rtp_payload.cdata()[0] & kH264TypeMask;
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h b/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h
index cbea860..0953a12 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_H264_H_
 #define MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_H264_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
 #include "rtc_base/copy_on_write_buffer.h"
 
@@ -20,7 +21,7 @@
  public:
   ~VideoRtpDepacketizerH264() override = default;
 
-  absl::optional<ParsedRtpPayload> Parse(
+  std::optional<ParsedRtpPayload> Parse(
       rtc::CopyOnWriteBuffer rtp_payload) override;
 };
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_h264_unittest.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_h264_unittest.cc
index d279d24..1e10ebc 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_h264_unittest.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_h264_unittest.cc
@@ -11,9 +11,9 @@
 #include "modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h"
 
 #include <cstdint>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "common_video/h264/h264_common.h"
 #include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
@@ -56,7 +56,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(packet);
 
   VideoRtpDepacketizerH264 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_TRUE(parsed);
 
@@ -77,7 +77,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(packet);
 
   VideoRtpDepacketizerH264 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_TRUE(parsed);
 
@@ -112,7 +112,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(packet);
 
   VideoRtpDepacketizerH264 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_TRUE(parsed);
 
@@ -139,7 +139,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(packet);
 
   VideoRtpDepacketizerH264 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_TRUE(parsed);
 
@@ -260,7 +260,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(packet);
 
   VideoRtpDepacketizerH264 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_TRUE(parsed);
 
@@ -303,7 +303,7 @@
   const uint8_t kExpected3[] = {0x03};
 
   VideoRtpDepacketizerH264 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed1 =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed1 =
       depacketizer.Parse(rtc::CopyOnWriteBuffer(packet1));
   ASSERT_TRUE(parsed1);
   // We expect that the first packet is one byte shorter since the FU-A header
@@ -476,7 +476,7 @@
   };
 
   VideoRtpDepacketizerH264 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload));
   ASSERT_TRUE(parsed);
   EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
@@ -497,7 +497,7 @@
   };
 
   VideoRtpDepacketizerH264 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload));
   ASSERT_TRUE(parsed);
   EXPECT_FALSE(parsed->video_header.is_first_packet_in_frame);
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.cc
index b415ae7..d16e638 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.cc
@@ -13,11 +13,11 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/base/macros.h"
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/video/video_codec_type.h"
 #include "common_video/h264/h264_common.h"
@@ -61,16 +61,16 @@
 // https://datatracker.ietf.org/doc/html/rfc7798#section-4.4.1
 // Aggregation Packet (AP) strcture
 // https://datatracker.ietf.org/doc/html/rfc7798#section-4.4.2
-absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> ProcessApOrSingleNalu(
+std::optional<VideoRtpDepacketizer::ParsedRtpPayload> ProcessApOrSingleNalu(
     rtc::CopyOnWriteBuffer rtp_payload) {
   // Skip the single NALU header (payload header), aggregated packet case will
   // be checked later.
   if (rtp_payload.size() <= kH265PayloadHeaderSizeBytes) {
     RTC_LOG(LS_ERROR) << "Single NALU header truncated.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   const uint8_t* const payload_data = rtp_payload.cdata();
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload(
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload(
       absl::in_place);
   parsed_payload->video_header.width = 0;
   parsed_payload->video_header.height = 0;
@@ -86,13 +86,13 @@
     // Skip the aggregated packet header (Aggregated packet NAL type + length).
     if (rtp_payload.size() <= kH265ApHeaderSizeBytes) {
       RTC_LOG(LS_ERROR) << "Aggregated packet header truncated.";
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     if (!ParseApStartOffsets(nalu_start, nalu_length, &nalu_start_offsets)) {
       RTC_LOG(LS_ERROR)
           << "Aggregated packet with incorrect NALU packet lengths.";
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     nal_type = (payload_data[kH265ApHeaderSizeBytes] & kH265TypeMask) >> 1;
@@ -110,7 +110,7 @@
     size_t end_offset = nalu_start_offsets[i + 1] - kH265LengthFieldSizeBytes;
     if (end_offset - start_offset < kH265NalHeaderSizeBytes) {
       RTC_LOG(LS_ERROR) << "Aggregated packet too short";
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     // Insert start code before each NALU in aggregated packet.
@@ -143,7 +143,7 @@
         if (start_offset)
           output_buffer->AppendData(payload_data, start_offset);
 
-        absl::optional<H265SpsParser::SpsState> sps =
+        std::optional<H265SpsParser::SpsState> sps =
             H265SpsParser::ParseSps(nalu_data);
 
         if (sps) {
@@ -175,7 +175,7 @@
       case H265::NaluType::kFu:
       case H265::NaluType::kPaci:
         RTC_LOG(LS_WARNING) << "Unexpected AP, FU or PACI received.";
-        return absl::nullopt;
+        return std::nullopt;
     }
   }
   parsed_payload->video_payload = video_payload;
@@ -184,13 +184,13 @@
 
 // Fragmentation Unit (FU) structure:
 // https://datatracker.ietf.org/doc/html/rfc7798#section-4.4.3
-absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> ParseFuNalu(
+std::optional<VideoRtpDepacketizer::ParsedRtpPayload> ParseFuNalu(
     rtc::CopyOnWriteBuffer rtp_payload) {
   if (rtp_payload.size() < kH265FuHeaderSizeBytes + kH265NalHeaderSizeBytes) {
     RTC_LOG(LS_ERROR) << "FU NAL units truncated.";
-    return absl::nullopt;
+    return std::nullopt;
   }
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload(
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload(
       absl::in_place);
 
   uint8_t f = rtp_payload.cdata()[0] & kH265FBit;
@@ -234,11 +234,11 @@
 
 }  // namespace
 
-absl::optional<VideoRtpDepacketizer::ParsedRtpPayload>
+std::optional<VideoRtpDepacketizer::ParsedRtpPayload>
 VideoRtpDepacketizerH265::Parse(rtc::CopyOnWriteBuffer rtp_payload) {
   if (rtp_payload.empty()) {
     RTC_LOG(LS_ERROR) << "Empty payload.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   uint8_t nal_type = (rtp_payload.cdata()[0] & kH265TypeMask) >> 1;
@@ -249,7 +249,7 @@
   } else if (nal_type == H265::NaluType::kPaci) {
     // TODO(bugs.webrtc.org/13485): Implement PACI parse for H265
     RTC_LOG(LS_ERROR) << "Not support type:" << nal_type;
-    return absl::nullopt;
+    return std::nullopt;
   } else {
     // Single NAL unit packet or Aggregated packets (AP).
     return ProcessApOrSingleNalu(std::move(rtp_payload));
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.h b/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.h
index ed5290d..27f3e53 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.h
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_H265_H_
 #define MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_H265_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
 #include "rtc_base/copy_on_write_buffer.h"
 
@@ -20,7 +21,7 @@
  public:
   ~VideoRtpDepacketizerH265() override = default;
 
-  absl::optional<ParsedRtpPayload> Parse(
+  std::optional<ParsedRtpPayload> Parse(
       rtc::CopyOnWriteBuffer rtp_payload) override;
 };
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_h265_unittest.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_h265_unittest.cc
index c94e0d5..8b7d080 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_h265_unittest.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_h265_unittest.cc
@@ -11,9 +11,9 @@
 #include "modules/rtp_rtcp/source/video_rtp_depacketizer_h265.h"
 
 #include <cstdint>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "common_video/h265/h265_common.h"
 #include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
@@ -40,7 +40,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(packet);
 
   VideoRtpDepacketizerH265 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_TRUE(parsed);
 
@@ -74,7 +74,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(packet);
 
   VideoRtpDepacketizerH265 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_TRUE(parsed);
 
@@ -92,7 +92,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(packet);
 
   VideoRtpDepacketizerH265 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_FALSE(parsed);
 }
@@ -160,7 +160,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(packet);
 
   VideoRtpDepacketizerH265 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_TRUE(parsed);
 
@@ -219,7 +219,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(packet);
 
   VideoRtpDepacketizerH265 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_TRUE(parsed);
 
@@ -270,7 +270,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(packet);
 
   VideoRtpDepacketizerH265 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_TRUE(parsed);
 
@@ -311,7 +311,7 @@
   const uint8_t kExpected3[] = {0x03};
 
   VideoRtpDepacketizerH265 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed1 =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed1 =
       depacketizer.Parse(rtc::CopyOnWriteBuffer(packet1));
   ASSERT_TRUE(parsed1);
   // We expect that the first packet is one byte shorter since the FU header
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_raw.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_raw.cc
index 81b4e4a..f4f4a79 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_raw.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_raw.cc
@@ -10,17 +10,17 @@
 
 #include "modules/rtp_rtcp/source/video_rtp_depacketizer_raw.h"
 
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
 #include "rtc_base/copy_on_write_buffer.h"
 
 namespace webrtc {
 
-absl::optional<VideoRtpDepacketizer::ParsedRtpPayload>
+std::optional<VideoRtpDepacketizer::ParsedRtpPayload>
 VideoRtpDepacketizerRaw::Parse(rtc::CopyOnWriteBuffer rtp_payload) {
-  absl::optional<ParsedRtpPayload> parsed(absl::in_place);
+  std::optional<ParsedRtpPayload> parsed(absl::in_place);
   parsed->video_payload = std::move(rtp_payload);
   return parsed;
 }
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_raw.h b/modules/rtp_rtcp/source/video_rtp_depacketizer_raw.h
index 59c8695..abd2d77 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_raw.h
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_raw.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_RAW_H_
 #define MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_RAW_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
 #include "rtc_base/copy_on_write_buffer.h"
 
@@ -21,7 +22,7 @@
  public:
   ~VideoRtpDepacketizerRaw() override = default;
 
-  absl::optional<ParsedRtpPayload> Parse(
+  std::optional<ParsedRtpPayload> Parse(
       rtc::CopyOnWriteBuffer rtp_payload) override;
 };
 
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_raw_unittest.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_raw_unittest.cc
index 36c826a..218ee09 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_raw_unittest.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_raw_unittest.cc
@@ -11,8 +11,8 @@
 #include "modules/rtp_rtcp/source/video_rtp_depacketizer_raw.h"
 
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "rtc_base/copy_on_write_buffer.h"
 #include "test/gtest.h"
 
@@ -24,7 +24,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(kPayload);
 
   VideoRtpDepacketizerRaw depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
 
   ASSERT_TRUE(parsed);
@@ -39,7 +39,7 @@
   rtc::CopyOnWriteBuffer rtp_payload(kPayload);
 
   VideoRtpDepacketizerRaw depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
 
   ASSERT_TRUE(parsed);
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_vp8.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_vp8.cc
index d6bd33c..157ad37 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_vp8.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_vp8.cc
@@ -13,7 +13,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/array_view.h"
 #include "modules/rtp_rtcp/source/rtp_video_header.h"
 #include "rtc_base/checks.h"
@@ -131,14 +132,14 @@
 
 }  // namespace
 
-absl::optional<VideoRtpDepacketizer::ParsedRtpPayload>
+std::optional<VideoRtpDepacketizer::ParsedRtpPayload>
 VideoRtpDepacketizerVp8::Parse(rtc::CopyOnWriteBuffer rtp_payload) {
   rtc::ArrayView<const uint8_t> payload(rtp_payload.cdata(),
                                         rtp_payload.size());
-  absl::optional<ParsedRtpPayload> result(absl::in_place);
+  std::optional<ParsedRtpPayload> result(absl::in_place);
   int offset = ParseRtpPayload(payload, &result->video_header);
   if (offset == kFailedToParse)
-    return absl::nullopt;
+    return std::nullopt;
   RTC_DCHECK_LT(offset, rtp_payload.size());
   result->video_payload =
       rtp_payload.Slice(offset, rtp_payload.size() - offset);
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_vp8.h b/modules/rtp_rtcp/source/video_rtp_depacketizer_vp8.h
index 3d7cb32..d303020 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_vp8.h
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_vp8.h
@@ -12,8 +12,8 @@
 #define MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_VP8_H_
 
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/rtp_rtcp/source/rtp_video_header.h"
 #include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
@@ -33,7 +33,7 @@
   static int ParseRtpPayload(rtc::ArrayView<const uint8_t> rtp_payload,
                              RTPVideoHeader* video_header);
 
-  absl::optional<ParsedRtpPayload> Parse(
+  std::optional<ParsedRtpPayload> Parse(
       rtc::CopyOnWriteBuffer rtp_payload) override;
 };
 
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_vp8_unittest.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_vp8_unittest.cc
index 77469cf..7bc9e97 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_vp8_unittest.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_vp8_unittest.cc
@@ -201,7 +201,7 @@
   ASSERT_TRUE(packetizer.NextPacket(&packet));
 
   VideoRtpDepacketizerVp8 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(packet.PayloadBuffer());
   ASSERT_TRUE(parsed);
 
@@ -225,7 +225,7 @@
 
   rtc::CopyOnWriteBuffer rtp_payload(packet);
   VideoRtpDepacketizerVp8 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_TRUE(parsed);
 
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.cc
index a8b04db..ebd27ff 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.cc
@@ -146,12 +146,12 @@
 }
 }  // namespace
 
-absl::optional<VideoRtpDepacketizer::ParsedRtpPayload>
+std::optional<VideoRtpDepacketizer::ParsedRtpPayload>
 VideoRtpDepacketizerVp9::Parse(rtc::CopyOnWriteBuffer rtp_payload) {
-  absl::optional<ParsedRtpPayload> result(absl::in_place);
+  std::optional<ParsedRtpPayload> result(absl::in_place);
   int offset = ParseRtpPayload(rtp_payload, &result->video_header);
   if (offset == 0)
-    return absl::nullopt;
+    return std::nullopt;
   RTC_DCHECK_LT(offset, rtp_payload.size());
   result->video_payload =
       rtp_payload.Slice(offset, rtp_payload.size() - offset);
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.h b/modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.h
index 4bb358a..fb0dd14 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.h
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.h
@@ -12,8 +12,8 @@
 #define MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_VP9_H_
 
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/rtp_rtcp/source/rtp_video_header.h"
 #include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
@@ -33,7 +33,7 @@
   static int ParseRtpPayload(rtc::ArrayView<const uint8_t> rtp_payload,
                              RTPVideoHeader* video_header);
 
-  absl::optional<ParsedRtpPayload> Parse(
+  std::optional<ParsedRtpPayload> Parse(
       rtc::CopyOnWriteBuffer rtp_payload) override;
 };
 
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_vp9_unittest.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_vp9_unittest.cc
index 7f89812..fb5fd27 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_vp9_unittest.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_vp9_unittest.cc
@@ -361,7 +361,7 @@
 
   rtc::CopyOnWriteBuffer rtp_payload(packet);
   VideoRtpDepacketizerVp9 depacketizer;
-  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+  std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
       depacketizer.Parse(rtp_payload);
   ASSERT_TRUE(parsed);
 
diff --git a/modules/video_capture/linux/pipewire_session.cc b/modules/video_capture/linux/pipewire_session.cc
index fd93b31..49421de 100644
--- a/modules/video_capture/linux/pipewire_session.cc
+++ b/modules/video_capture/linux/pipewire_session.cc
@@ -96,13 +96,13 @@
   if (info->change_mask & PW_NODE_CHANGE_MASK_PROPS) {
     const char* vid_str;
     const char* pid_str;
-    absl::optional<int> vid;
-    absl::optional<int> pid;
+    std::optional<int> vid;
+    std::optional<int> pid;
 
     vid_str = spa_dict_lookup(info->props, SPA_KEY_DEVICE_VENDOR_ID);
     pid_str = spa_dict_lookup(info->props, SPA_KEY_DEVICE_PRODUCT_ID);
-    vid = vid_str ? rtc::StringToNumber<int>(vid_str) : absl::nullopt;
-    pid = pid_str ? rtc::StringToNumber<int>(pid_str) : absl::nullopt;
+    vid = vid_str ? rtc::StringToNumber<int>(vid_str) : std::nullopt;
+    pid = pid_str ? rtc::StringToNumber<int>(pid_str) : std::nullopt;
 
     if (vid && pid) {
       char model_str[10];
diff --git a/modules/video_capture/linux/video_capture_pipewire.cc b/modules/video_capture/linux/video_capture_pipewire.cc
index 940db43..b21b55f 100644
--- a/modules/video_capture/linux/video_capture_pipewire.cc
+++ b/modules/video_capture/linux/video_capture_pipewire.cc
@@ -73,9 +73,9 @@
   RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
   RTC_DCHECK_RUN_ON(&api_checker_);
 
-  absl::optional<int> id;
+  std::optional<int> id;
   id = rtc::StringToNumber<int>(deviceUniqueId);
-  if (id == absl::nullopt)
+  if (id == std::nullopt)
     return -1;
 
   node_id_ = id.value();
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index 2e6b1c3..344f811 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -42,7 +42,6 @@
     "../../rtc_base:checks",
     "../../rtc_base:logging",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -59,7 +58,6 @@
     "../../rtc_base:logging",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -137,7 +135,6 @@
     "../rtp_rtcp:rtp_rtcp_format",
     "../rtp_rtcp:rtp_video_header",
     "//third_party/abseil-cpp/absl/base:core_headers",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -272,7 +269,6 @@
     "timing:timing_module",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -297,7 +293,6 @@
     "../../common_video",
     "../../common_video/generic_frame_descriptor",
     "../../rtc_base/system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -351,7 +346,6 @@
     "timing:inter_frame_delay_variation_calculator",
     "timing:jitter_estimator",
     "timing:timing_module",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -447,7 +441,6 @@
     "svc:scalability_mode_util",
     "//third_party/abseil-cpp/absl/numeric:bits",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -491,7 +484,6 @@
     "//third_party/abseil-cpp/absl/base:nullability",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/libyuv",
   ]
 
@@ -576,7 +568,6 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/base:nullability",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/libyuv",
   ]
   if (rtc_build_libvpx) {
@@ -617,7 +608,6 @@
     "../../rtc_base:rtc_numerics",
     "../../rtc_base:timeutils",
     "../../system_wrappers:metrics",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -697,7 +687,6 @@
     "//third_party/abseil-cpp/absl/container:inlined_vector",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/libyuv",
   ]
   if (rtc_build_libvpx) {
@@ -843,7 +832,6 @@
       "../../test:video_test_common",
       "../../test:video_test_support",
       "../rtp_rtcp:rtp_rtcp_format",
-      "//third_party/abseil-cpp/absl/types:optional",
       "//third_party/libyuv",
     ]
   }
@@ -934,7 +922,6 @@
       "../../video/config:streams_config",
       "//third_party/abseil-cpp/absl/strings",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -954,7 +941,6 @@
       "../../rtc_base:stringutils",
       "../../test:test_common",
       "../rtp_rtcp:rtp_rtcp_format",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -1070,7 +1056,6 @@
       "codecs/av1:dav1d_decoder",
       "svc:scalability_mode_util",
       "//third_party/abseil-cpp/absl/memory",
-      "//third_party/abseil-cpp/absl/types:optional",
       "//third_party/libyuv",
     ]
 
@@ -1252,7 +1237,6 @@
       "svc:svc_rate_allocator_tests",
       "timing:jitter_estimator",
       "timing:timing_module",
-      "//third_party/abseil-cpp/absl/types:optional",
       "//third_party/abseil-cpp/absl/types:variant",
     ]
     if (rtc_build_libvpx) {
diff --git a/modules/video_coding/chain_diff_calculator.cc b/modules/video_coding/chain_diff_calculator.cc
index 5f85271..d8ce44a 100644
--- a/modules/video_coding/chain_diff_calculator.cc
+++ b/modules/video_coding/chain_diff_calculator.cc
@@ -13,10 +13,10 @@
 #include <stdint.h>
 
 #include <algorithm>
+#include <optional>
 #include <vector>
 
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 #include "rtc_base/logging.h"
 
 namespace webrtc {
@@ -25,7 +25,7 @@
   last_frame_in_chain_.resize(chains.size());
   for (size_t i = 0; i < chains.size(); ++i) {
     if (chains[i]) {
-      last_frame_in_chain_[i] = absl::nullopt;
+      last_frame_in_chain_[i] = std::nullopt;
     }
   }
 }
diff --git a/modules/video_coding/chain_diff_calculator.h b/modules/video_coding/chain_diff_calculator.h
index bca7340..b757544 100644
--- a/modules/video_coding/chain_diff_calculator.h
+++ b/modules/video_coding/chain_diff_calculator.h
@@ -13,10 +13,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 
 namespace webrtc {
 
@@ -38,7 +38,7 @@
  private:
   absl::InlinedVector<int, 4> ChainDiffs(int64_t frame_id) const;
 
-  absl::InlinedVector<absl::optional<int64_t>, 4> last_frame_in_chain_;
+  absl::InlinedVector<std::optional<int64_t>, 4> last_frame_in_chain_;
 };
 
 }  // namespace webrtc
diff --git a/modules/video_coding/codecs/av1/BUILD.gn b/modules/video_coding/codecs/av1/BUILD.gn
index 197e1f3..8a2d490 100644
--- a/modules/video_coding/codecs/av1/BUILD.gn
+++ b/modules/video_coding/codecs/av1/BUILD.gn
@@ -71,7 +71,6 @@
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/base:nullability",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/libaom",
   ]
 }
@@ -110,7 +109,6 @@
         "../../svc:scalability_mode_util",
         "../../svc:scalability_structures",
         "../../svc:scalable_video_controller",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
   }
diff --git a/modules/video_coding/codecs/av1/av1_svc_config.cc b/modules/video_coding/codecs/av1/av1_svc_config.cc
index 09b840c..59b79dc 100644
--- a/modules/video_coding/codecs/av1/av1_svc_config.cc
+++ b/modules/video_coding/codecs/av1/av1_svc_config.cc
@@ -39,8 +39,8 @@
   return std::min(num_layers_fit_horz, num_layers_fit_vert);
 }
 
-absl::optional<ScalabilityMode> BuildScalabilityMode(int num_temporal_layers,
-                                                     int num_spatial_layers) {
+std::optional<ScalabilityMode> BuildScalabilityMode(int num_temporal_layers,
+                                                    int num_spatial_layers) {
   char name[20];
   rtc::SimpleStringBuilder ss(name);
   ss << "L" << num_spatial_layers << "T" << num_temporal_layers;
@@ -56,7 +56,7 @@
 LibaomAv1EncoderSupportedScalabilityModes() {
   absl::InlinedVector<ScalabilityMode, kScalabilityModeCount> scalability_modes;
   for (ScalabilityMode scalability_mode : kAllScalabilityModes) {
-    if (ScalabilityStructureConfig(scalability_mode) != absl::nullopt) {
+    if (ScalabilityStructureConfig(scalability_mode) != std::nullopt) {
       scalability_modes.push_back(scalability_mode);
     }
   }
@@ -66,7 +66,7 @@
 bool LibaomAv1EncoderSupportsScalabilityMode(ScalabilityMode scalability_mode) {
   // For libaom AV1, the scalability mode is supported if we can create the
   // scalability structure.
-  return ScalabilityStructureConfig(scalability_mode) != absl::nullopt;
+  return ScalabilityStructureConfig(scalability_mode) != std::nullopt;
 }
 
 bool SetAv1SvcConfig(VideoCodec& video_codec,
@@ -74,7 +74,7 @@
                      int num_spatial_layers) {
   RTC_DCHECK_EQ(video_codec.codecType, kVideoCodecAV1);
 
-  absl::optional<ScalabilityMode> scalability_mode =
+  std::optional<ScalabilityMode> scalability_mode =
       video_codec.GetScalabilityMode();
   if (!scalability_mode.has_value()) {
     scalability_mode =
diff --git a/modules/video_coding/codecs/av1/dav1d_decoder.cc b/modules/video_coding/codecs/av1/dav1d_decoder.cc
index 5a60c7f..1e93925 100644
--- a/modules/video_coding/codecs/av1/dav1d_decoder.cc
+++ b/modules/video_coding/codecs/av1/dav1d_decoder.cc
@@ -197,9 +197,9 @@
   // doi: 10.1109/JPROC.2021.3058584. keywords:
   // {Encoding;Codecs;Decoding;Streaming media;Video compression;Media;Alliance
   // of Open Media;AV1;video compression},
-  absl::optional<uint8_t> qp = dav1d_picture.frame_hdr->quant.yac;
+  std::optional<uint8_t> qp = dav1d_picture.frame_hdr->quant.yac;
   decode_complete_callback_->Decoded(decoded_frame,
-                                     /*decode_time_ms=*/absl::nullopt, qp);
+                                     /*decode_time_ms=*/std::nullopt, qp);
 
   return WEBRTC_VIDEO_CODEC_OK;
 }
diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
index c067922..6b71874 100644
--- a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
+++ b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
@@ -13,6 +13,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -20,7 +21,6 @@
 #include "absl/base/macros.h"
 #include "absl/base/nullability.h"
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/field_trials_view.h"
 #include "api/scoped_refptr.h"
@@ -120,10 +120,10 @@
   void MaybeRewrapImgWithFormat(const aom_img_fmt_t fmt);
 
   std::unique_ptr<ScalableVideoController> svc_controller_;
-  absl::optional<ScalabilityMode> scalability_mode_;
+  std::optional<ScalabilityMode> scalability_mode_;
   bool inited_;
   bool rates_configured_;
-  absl::optional<aom_svc_params_t> svc_params_;
+  std::optional<aom_svc_params_t> svc_params_;
   VideoCodec encoder_settings_;
   LibaomAv1EncoderSettings settings_;
   aom_image_t* frame_for_encode_;
@@ -434,7 +434,7 @@
   bool svc_enabled =
       svc_config.num_spatial_layers > 1 || svc_config.num_temporal_layers > 1;
   if (!svc_enabled) {
-    svc_params_ = absl::nullopt;
+    svc_params_ = std::nullopt;
     return true;
   }
   if (svc_config.num_spatial_layers < 1 || svc_config.num_spatial_layers > 4) {
@@ -652,7 +652,7 @@
     // The libaom AV1 encoder requires that `aom_codec_encode` is called for
     // every spatial layer, even if the configured bitrate for that layer is
     // zero. For zero bitrate spatial layers no frames will be produced.
-    absl::optional<ScalableVideoController::LayerFrameConfig>
+    std::optional<ScalableVideoController::LayerFrameConfig>
         non_encoded_layer_frame;
     ScalableVideoController::LayerFrameConfig* layer_frame;
     if (next_layer_frame != layer_frames.end() &&
diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc
index a00b03a..37477be 100644
--- a/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc
+++ b/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc
@@ -13,10 +13,10 @@
 #include <algorithm>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
 #include "api/test/create_frame_generator.h"
@@ -93,7 +93,7 @@
       EncodedVideoFrameProducer(*encoder).SetNumInputFrames(1).Encode();
   ASSERT_THAT(encoded_frames, SizeIs(1));
   ASSERT_NE(encoded_frames[0].codec_specific_info.generic_frame_info,
-            absl::nullopt);
+            std::nullopt);
   // Assuming L1T2 structure uses 1st decode target for T0 and 2nd decode target
   // for T0+T1 frames, expect only 1st decode target is active.
   EXPECT_EQ(encoded_frames[0]
@@ -477,7 +477,7 @@
   EXPECT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
             WEBRTC_VIDEO_CODEC_OK);
   EXPECT_EQ(encoder->GetEncoderInfo().scaling_settings.thresholds,
-            absl::nullopt);
+            std::nullopt);
 }
 
 }  // namespace
diff --git a/modules/video_coding/codecs/av1/libaom_av1_unittest.cc b/modules/video_coding/codecs/av1/libaom_av1_unittest.cc
index 763e399..6f71bd1 100644
--- a/modules/video_coding/codecs/av1/libaom_av1_unittest.cc
+++ b/modules/video_coding/codecs/av1/libaom_av1_unittest.cc
@@ -13,11 +13,11 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <ostream>
 #include <tuple>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
 #include "api/units/data_size.h"
@@ -121,8 +121,8 @@
       return 0;
     }
     void Decoded(VideoFrame& /*decoded_image*/,
-                 absl::optional<int32_t> /*decode_time_ms*/,
-                 absl::optional<uint8_t> /*qp*/) override {
+                 std::optional<int32_t> /*decode_time_ms*/,
+                 std::optional<uint8_t> /*qp*/) override {
       ++num_called_;
     }
 
@@ -182,7 +182,7 @@
 
 struct SvcTestParam {
   ScalabilityMode GetScalabilityMode() const {
-    absl::optional<ScalabilityMode> scalability_mode =
+    std::optional<ScalabilityMode> scalability_mode =
         ScalabilityModeFromString(name);
     RTC_CHECK(scalability_mode.has_value());
     return *scalability_mode;
diff --git a/modules/video_coding/codecs/h264/h264.cc b/modules/video_coding/codecs/h264/h264.cc
index 60142c8..d46503b 100644
--- a/modules/video_coding/codecs/h264/h264.cc
+++ b/modules/video_coding/codecs/h264/h264.cc
@@ -12,10 +12,10 @@
 #include "modules/video_coding/codecs/h264/include/h264.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 #include "api/video_codecs/sdp_video_format.h"
 #include "media/base/media_constants.h"
 #include "rtc_base/trace_event.h"
@@ -54,7 +54,7 @@
                                 H264Level level,
                                 const std::string& packetization_mode,
                                 bool add_scalability_modes) {
-  const absl::optional<std::string> profile_string =
+  const std::optional<std::string> profile_string =
       H264ProfileLevelIdToString(H264ProfileLevelId(profile, level));
   RTC_CHECK(profile_string);
   absl::InlinedVector<ScalabilityMode, kScalabilityModeCount> scalability_modes;
diff --git a/modules/video_coding/codecs/h264/h264_decoder_impl.cc b/modules/video_coding/codecs/h264/h264_decoder_impl.cc
index 7e01d6a..2ebb4cb 100644
--- a/modules/video_coding/codecs/h264/h264_decoder_impl.cc
+++ b/modules/video_coding/codecs/h264/h264_decoder_impl.cc
@@ -328,7 +328,7 @@
 
   av_frame_.reset(av_frame_alloc());
 
-  if (absl::optional<int> buffer_pool_size = settings.buffer_pool_size()) {
+  if (std::optional<int> buffer_pool_size = settings.buffer_pool_size()) {
     if (!ffmpeg_buffer_pool_.Resize(*buffer_pool_size)) {
       return false;
     }
@@ -399,7 +399,7 @@
 
   // TODO(sakal): Maybe it is possible to get QP directly from FFmpeg.
   h264_bitstream_parser_.ParseBitstream(input_image);
-  absl::optional<int> qp = h264_bitstream_parser_.GetLastSliceQp();
+  std::optional<int> qp = h264_bitstream_parser_.GetLastSliceQp();
 
   // Obtain the `video_frame` containing the decoded image.
   VideoFrame* input_frame =
@@ -617,7 +617,7 @@
   // Return decoded frame.
   // TODO(nisse): Timestamp and rotation are all zero here. Change decoder
   // interface to pass a VideoFrameBuffer instead of a VideoFrame?
-  decoded_image_callback_->Decoded(decoded_frame, absl::nullopt, qp);
+  decoded_image_callback_->Decoded(decoded_frame, std::nullopt, qp);
 
   // Stop referencing it, possibly freeing `input_frame`.
   av_frame_unref(av_frame_.get());
diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl.cc b/modules/video_coding/codecs/h264/h264_encoder_impl.cc
index cfd89d1..bc81005 100644
--- a/modules/video_coding/codecs/h264/h264_encoder_impl.cc
+++ b/modules/video_coding/codecs/h264/h264_encoder_impl.cc
@@ -18,10 +18,10 @@
 
 #include <algorithm>
 #include <limits>
+#include <optional>
 #include <string>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/video/video_codec_constants.h"
 #include "api/video_codecs/scalability_mode.h"
 #include "common_video/libyuv/include/webrtc_libyuv.h"
@@ -58,7 +58,7 @@
   kH264EncoderEventMax = 16,
 };
 
-int NumberOfThreads(absl::optional<int> encoder_thread_limit,
+int NumberOfThreads(std::optional<int> encoder_thread_limit,
                     int width,
                     int height,
                     int number_of_cores) {
@@ -102,7 +102,7 @@
   return VideoFrameType::kEmptyFrame;
 }
 
-absl::optional<ScalabilityMode> ScalabilityModeFromTemporalLayers(
+std::optional<ScalabilityMode> ScalabilityModeFromTemporalLayers(
     int num_temporal_layers) {
   switch (num_temporal_layers) {
     case 0:
@@ -116,7 +116,7 @@
     default:
       RTC_DCHECK_NOTREACHED();
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace
diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl.h b/modules/video_coding/codecs/h264/h264_encoder_impl.h
index 2818711..f04b649 100644
--- a/modules/video_coding/codecs/h264/h264_encoder_impl.h
+++ b/modules/video_coding/codecs/h264/h264_encoder_impl.h
@@ -103,7 +103,7 @@
   std::vector<LayerConfig> configurations_;
   std::vector<EncodedImage> encoded_images_;
   std::vector<std::unique_ptr<ScalableVideoController>> svc_controllers_;
-  absl::InlinedVector<absl::optional<ScalabilityMode>, kMaxSimulcastStreams>
+  absl::InlinedVector<std::optional<ScalabilityMode>, kMaxSimulcastStreams>
       scalability_modes_;
 
   const Environment env_;
@@ -111,7 +111,7 @@
   H264PacketizationMode packetization_mode_;
   size_t max_payload_size_;
   int32_t number_of_cores_;
-  absl::optional<int> encoder_thread_limit_;
+  std::optional<int> encoder_thread_limit_;
   EncodedImageCallback* encoded_image_callback_;
 
   bool has_reported_init_;
diff --git a/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc b/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc
index 9bc72b2..985224d 100644
--- a/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc
+++ b/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc
@@ -11,8 +11,8 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/video/color_space.h"
 #include "api/video/encoded_image.h"
 #include "api/video/video_frame.h"
@@ -64,7 +64,7 @@
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
-  absl::optional<uint8_t> decoded_qp;
+  std::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
   ASSERT_TRUE(decoded_frame);
   EXPECT_GT(I420PSNR(&input_frame, decoded_frame.get()), 36);
@@ -89,7 +89,7 @@
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
-  absl::optional<uint8_t> decoded_qp;
+  std::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
   ASSERT_TRUE(decoded_frame);
   ASSERT_TRUE(decoded_qp);
diff --git a/modules/video_coding/codecs/test/encoded_video_frame_producer.cc b/modules/video_coding/codecs/test/encoded_video_frame_producer.cc
index 1087963..cd77052 100644
--- a/modules/video_coding/codecs/test/encoded_video_frame_producer.cc
+++ b/modules/video_coding/codecs/test/encoded_video_frame_producer.cc
@@ -49,7 +49,7 @@
   std::unique_ptr<test::FrameGeneratorInterface> frame_buffer_generator =
       test::CreateSquareFrameGenerator(
           resolution_.Width(), resolution_.Height(),
-          test::FrameGeneratorInterface::OutputType::kI420, absl::nullopt);
+          test::FrameGeneratorInterface::OutputType::kI420, std::nullopt);
 
   std::vector<EncodedFrame> encoded_frames;
   EncoderCallback encoder_callback(encoded_frames);
diff --git a/modules/video_coding/codecs/test/video_codec_test.cc b/modules/video_coding/codecs/test/video_codec_test.cc
index 2b144ac..48d6bec 100644
--- a/modules/video_coding/codecs/test/video_codec_test.cc
+++ b/modules/video_coding/codecs/test/video_codec_test.cc
@@ -53,16 +53,16 @@
           "Decoder: dav1d, libvpx-vp9, libvpx-vp8, ffmpeg-h264, hw-vp8, "
           "hw-vp9, hw-av1, hw-h264, hw-h265");
 ABSL_FLAG(std::string, scalability_mode, "L1T1", "Scalability mode.");
-ABSL_FLAG(absl::optional<int>, width, absl::nullopt, "Encode width.");
-ABSL_FLAG(absl::optional<int>, height, absl::nullopt, "Encode height.");
+ABSL_FLAG(std::optional<int>, width, std::nullopt, "Encode width.");
+ABSL_FLAG(std::optional<int>, height, std::nullopt, "Encode height.");
 ABSL_FLAG(std::vector<std::string>,
           bitrate_kbps,
           {"1024"},
           "Encode target bitrate per layer (l0t0,l0t1,...l1t0,l1t1 and so on) "
           "in kbps.");
-ABSL_FLAG(absl::optional<double>,
+ABSL_FLAG(std::optional<double>,
           framerate_fps,
-          absl::nullopt,
+          std::nullopt,
           "Encode target frame rate of the top temporal layer in fps.");
 ABSL_FLAG(bool, screencast, false, "Enable screen encoding mode.");
 ABSL_FLAG(bool, frame_drop, true, "Enable frame dropping.");
@@ -193,7 +193,7 @@
       CreateEncoderFactory(encoder_impl);
   if (!encoder_factory
            ->QueryCodecSupport(sdp_video_format,
-                               /*scalability_mode=*/absl::nullopt)
+                               /*scalability_mode=*/std::nullopt)
            .is_supported) {
     RTC_LOG(LS_WARNING) << "No " << encoder_impl << " encoder for video format "
                         << sdp_video_format.ToString();
@@ -262,7 +262,7 @@
       CreateEncoderFactory(encoder_impl);
   if (!encoder_factory
            ->QueryCodecSupport(sdp_video_format,
-                               /*scalability_mode=*/absl::nullopt)
+                               /*scalability_mode=*/std::nullopt)
            .is_supported) {
     RTC_LOG(LS_WARNING) << "No encoder for video format "
                         << sdp_video_format.ToString();
diff --git a/modules/video_coding/codecs/test/video_codec_unittest.cc b/modules/video_coding/codecs/test/video_codec_unittest.cc
index 556a167..f367469 100644
--- a/modules/video_coding/codecs/test/video_codec_unittest.cc
+++ b/modules/video_coding/codecs/test/video_codec_unittest.cc
@@ -57,8 +57,8 @@
 
 void VideoCodecUnitTest::FakeDecodeCompleteCallback::Decoded(
     VideoFrame& frame,
-    absl::optional<int32_t> decode_time_ms,
-    absl::optional<uint8_t> qp) {
+    std::optional<int32_t> decode_time_ms,
+    std::optional<uint8_t> qp) {
   MutexLock lock(&test_->decoded_frame_section_);
   test_->decoded_frame_.emplace(frame);
   test_->decoded_qp_ = qp;
@@ -77,7 +77,7 @@
 
   input_frame_generator_ = test::CreateSquareFrameGenerator(
       codec_settings_.width, codec_settings_.height,
-      test::FrameGeneratorInterface::OutputType::kI420, absl::optional<int>());
+      test::FrameGeneratorInterface::OutputType::kI420, std::optional<int>());
 
   encoder_ = CreateEncoder();
   decoder_ = CreateDecoder();
@@ -159,7 +159,7 @@
 }
 
 bool VideoCodecUnitTest::WaitForDecodedFrame(std::unique_ptr<VideoFrame>* frame,
-                                             absl::optional<uint8_t>* qp) {
+                                             std::optional<uint8_t>* qp) {
   bool ret = decoded_frame_event_.Wait(kDecodeTimeout);
   EXPECT_TRUE(ret) << "Timed out while waiting for a decoded frame.";
   // This becomes unsafe if there are multiple threads waiting for frames.
diff --git a/modules/video_coding/codecs/test/video_codec_unittest.h b/modules/video_coding/codecs/test/video_codec_unittest.h
index 6ad46ba..b154a4b 100644
--- a/modules/video_coding/codecs/test/video_codec_unittest.h
+++ b/modules/video_coding/codecs/test/video_codec_unittest.h
@@ -65,8 +65,8 @@
       return -1;
     }
     void Decoded(VideoFrame& frame,
-                 absl::optional<int32_t> decode_time_ms,
-                 absl::optional<uint8_t> qp) override;
+                 std::optional<int32_t> decode_time_ms,
+                 std::optional<uint8_t> qp) override;
 
    private:
     VideoCodecUnitTest* const test_;
@@ -95,7 +95,7 @@
 
   // Helper method for waiting a single decoded frame.
   bool WaitForDecodedFrame(std::unique_ptr<VideoFrame>* frame,
-                           absl::optional<uint8_t>* qp);
+                           std::optional<uint8_t>* qp);
 
   size_t GetNumEncodedFrames();
 
@@ -120,9 +120,9 @@
 
   rtc::Event decoded_frame_event_;
   Mutex decoded_frame_section_;
-  absl::optional<VideoFrame> decoded_frame_
+  std::optional<VideoFrame> decoded_frame_
       RTC_GUARDED_BY(decoded_frame_section_);
-  absl::optional<uint8_t> decoded_qp_ RTC_GUARDED_BY(decoded_frame_section_);
+  std::optional<uint8_t> decoded_qp_ RTC_GUARDED_BY(decoded_frame_section_);
 
   uint32_t last_input_frame_timestamp_;
 };
diff --git a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
index 4056959..414f22d 100644
--- a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
@@ -16,6 +16,7 @@
 #include <algorithm>
 #include <cmath>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -23,7 +24,6 @@
 #include "absl/strings/match.h"
 #include "absl/strings/str_replace.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
diff --git a/modules/video_coding/codecs/test/videocodec_test_stats_impl.cc b/modules/video_coding/codecs/test/videocodec_test_stats_impl.cc
index 390348b..9e1a61f 100644
--- a/modules/video_coding/codecs/test/videocodec_test_stats_impl.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_stats_impl.cc
@@ -106,7 +106,7 @@
          ++temporal_idx) {
       VideoStatistics layer_stat = SliceAndCalcVideoStatistic(
           first_frame_num, last_frame_num, spatial_idx, temporal_idx, false,
-          /*target_bitrate=*/absl::nullopt, /*target_framerate=*/absl::nullopt);
+          /*target_bitrate=*/std::nullopt, /*target_framerate=*/std::nullopt);
       layer_stats.push_back(layer_stat);
     }
   }
@@ -126,8 +126,8 @@
 
   return SliceAndCalcVideoStatistic(
       first_frame_num, last_frame_num, num_spatial_layers - 1,
-      num_temporal_layers - 1, true, /*target_bitrate=*/absl::nullopt,
-      /*target_framerate=*/absl::nullopt);
+      num_temporal_layers - 1, true, /*target_bitrate=*/std::nullopt,
+      /*target_framerate=*/std::nullopt);
 }
 
 VideoStatistics VideoCodecTestStatsImpl::CalcVideoStatistic(
@@ -205,8 +205,8 @@
     size_t spatial_idx,
     size_t temporal_idx,
     bool aggregate_independent_layers,
-    absl::optional<DataRate> target_bitrate,
-    absl::optional<Frequency> target_framerate) {
+    std::optional<DataRate> target_bitrate,
+    std::optional<Frequency> target_framerate) {
   VideoStatistics video_stat;
 
   float buffer_level_bits = 0.0f;
diff --git a/modules/video_coding/codecs/test/videocodec_test_stats_impl.h b/modules/video_coding/codecs/test/videocodec_test_stats_impl.h
index 4212cfa..7040efb 100644
--- a/modules/video_coding/codecs/test/videocodec_test_stats_impl.h
+++ b/modules/video_coding/codecs/test/videocodec_test_stats_impl.h
@@ -14,10 +14,10 @@
 #include <stddef.h>
 
 #include <map>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/test/videocodec_test_stats.h"  // NOLINT(build/include)
 
 namespace webrtc {
@@ -76,8 +76,8 @@
       size_t spatial_idx,
       size_t temporal_idx,
       bool aggregate_independent_layers,
-      absl::optional<DataRate> target_bitrate,
-      absl::optional<Frequency> target_framerate);
+      std::optional<DataRate> target_bitrate,
+      std::optional<Frequency> target_framerate);
 
   void GetNumberOfEncodedLayers(size_t first_frame_num,
                                 size_t last_frame_num,
diff --git a/modules/video_coding/codecs/test/videoprocessor.h b/modules/video_coding/codecs/test/videoprocessor.h
index e6ecdff..35a925b 100644
--- a/modules/video_coding/codecs/test/videoprocessor.h
+++ b/modules/video_coding/codecs/test/videoprocessor.h
@@ -16,10 +16,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/sequence_checker.h"
 #include "api/task_queue/task_queue_base.h"
@@ -146,8 +146,8 @@
     }
 
     void Decoded(webrtc::VideoFrame& image,
-                 absl::optional<int32_t> decode_time_ms,
-                 absl::optional<uint8_t> qp) override {
+                 std::optional<int32_t> decode_time_ms,
+                 std::optional<uint8_t> qp) override {
       Decoded(image);
     }
 
diff --git a/modules/video_coding/codecs/vp8/default_temporal_layers.h b/modules/video_coding/codecs/vp8/default_temporal_layers.h
index bc6574c..d6b2491 100644
--- a/modules/video_coding/codecs/vp8/default_temporal_layers.h
+++ b/modules/video_coding/codecs/vp8/default_temporal_layers.h
@@ -19,11 +19,11 @@
 #include <deque>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <set>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/video_codecs/vp8_frame_config.h"
 #include "api/video_codecs/vp8_temporal_layers.h"
 #include "modules/video_coding/codecs/vp8/include/temporal_layers_checker.h"
@@ -124,7 +124,7 @@
 
   uint8_t pattern_idx_;
   // Updated cumulative bitrates, per temporal layer.
-  absl::optional<std::vector<uint32_t>> new_bitrates_bps_;
+  std::optional<std::vector<uint32_t>> new_bitrates_bps_;
 
   // Status for each pending frame, in
   std::deque<PendingFrame> pending_frames_;
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc
index 9a7a6f1..fc6cad6 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc
@@ -15,9 +15,9 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/field_trials_view.h"
 #include "api/scoped_refptr.h"
@@ -53,13 +53,13 @@
 constexpr bool kIsArm = false;
 #endif
 
-absl::optional<LibvpxVp8Decoder::DeblockParams> DefaultDeblockParams() {
+std::optional<LibvpxVp8Decoder::DeblockParams> DefaultDeblockParams() {
   return LibvpxVp8Decoder::DeblockParams(/*max_level=*/8,
                                          /*degrade_qp=*/60,
                                          /*min_qp=*/30);
 }
 
-absl::optional<LibvpxVp8Decoder::DeblockParams>
+std::optional<LibvpxVp8Decoder::DeblockParams>
 GetPostProcParamsFromFieldTrialGroup(const FieldTrialsView& field_trials) {
   std::string group = field_trials.Lookup(kIsArm ? kVp8PostProcArmFieldTrial
                                                  : kVp8PostProcFieldTrial);
@@ -127,7 +127,7 @@
       key_frame_required_(true),
       deblock_params_(use_postproc_ ? GetPostProcParamsFromFieldTrialGroup(
                                           env.field_trials())
-                                    : absl::nullopt),
+                                    : std::nullopt),
       qp_smoother_(use_postproc_ ? new QpSmoother() : nullptr) {}
 
 LibvpxVp8Decoder::~LibvpxVp8Decoder() {
@@ -160,7 +160,7 @@
 
   // Always start with a complete key frame.
   key_frame_required_ = true;
-  if (absl::optional<int> buffer_pool_size = settings.buffer_pool_size()) {
+  if (std::optional<int> buffer_pool_size = settings.buffer_pool_size()) {
     if (!buffer_pool_.Resize(*buffer_pool_size)) {
       return false;
     }
@@ -305,7 +305,7 @@
                                  .set_rtp_timestamp(timestamp)
                                  .set_color_space(explicit_color_space)
                                  .build();
-  decode_complete_callback_->Decoded(decoded_image, absl::nullopt, qp);
+  decode_complete_callback_->Decoded(decoded_image, std::nullopt, qp);
 
   return WEBRTC_VIDEO_CODEC_OK;
 }
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h
index c14a2b7..725ad71 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h
@@ -12,8 +12,8 @@
 #define MODULES_VIDEO_CODING_CODECS_VP8_LIBVPX_VP8_DECODER_H_
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/field_trials_view.h"
 #include "api/video/encoded_image.h"
@@ -72,7 +72,7 @@
   int last_frame_width_;
   int last_frame_height_;
   bool key_frame_required_;
-  const absl::optional<DeblockParams> deblock_params_;
+  const std::optional<DeblockParams> deblock_params_;
   const std::unique_ptr<QpSmoother> qp_smoother_;
 };
 
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
index 7b83e93..7edd3fe 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
@@ -117,8 +117,8 @@
 // Allow a newer value to override a current value only if the new value
 // is set.
 template <typename T>
-bool MaybeSetNewValue(const absl::optional<T>& new_value,
-                      absl::optional<T>* base_value) {
+bool MaybeSetNewValue(const std::optional<T>& new_value,
+                      std::optional<T>* base_value) {
   if (new_value.has_value() && new_value != *base_value) {
     *base_value = new_value;
     return true;
@@ -254,7 +254,7 @@
   const uint32_t original_frame_drop_threshold_;
 };
 
-absl::optional<TimeDelta> ParseFrameDropInterval(
+std::optional<TimeDelta> ParseFrameDropInterval(
     const FieldTrialsView& field_trials) {
   FieldTrialFlag disabled = FieldTrialFlag("Disabled");
   FieldTrialParameter<TimeDelta> interval("interval",
@@ -263,7 +263,7 @@
                   field_trials.Lookup("WebRTC-VP8-MaxFrameInterval"));
   if (disabled.Get()) {
     // Kill switch set, don't use any max frame interval.
-    return absl::nullopt;
+    return std::nullopt;
   }
   return interval.Get();
 }
@@ -494,7 +494,7 @@
     return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
   }
 
-  if (absl::optional<ScalabilityMode> scalability_mode =
+  if (std::optional<ScalabilityMode> scalability_mode =
           inst->GetScalabilityMode();
       scalability_mode.has_value() &&
       !VP8SupportsScalabilityMode(*scalability_mode)) {
@@ -1155,7 +1155,7 @@
   frame_buffer_controller_->OnEncodeDone(stream_idx, timestamp,
                                          encoded_images_[encoder_idx].size(),
                                          is_keyframe, qp, codec_specific);
-  if (is_keyframe && codec_specific->template_structure != absl::nullopt) {
+  if (is_keyframe && codec_specific->template_structure != std::nullopt) {
     // Number of resolutions must match number of spatial layers, VP8 structures
     // expected to use single spatial layer. Templates must be ordered by
     // spatial_id, so assumption there is exactly one spatial layer is same as
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
index 1800741..3f26efc 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
@@ -145,7 +145,7 @@
 
   const LibvpxVp8EncoderInfoSettings encoder_info_override_;
 
-  absl::optional<TimeDelta> max_frame_drop_interval_;
+  std::optional<TimeDelta> max_frame_drop_interval_;
 
   bool android_specific_threading_settings_;
 };
diff --git a/modules/video_coding/codecs/vp8/screenshare_layers.cc b/modules/video_coding/codecs/vp8/screenshare_layers.cc
index 71db0b2..ccec4b4 100644
--- a/modules/video_coding/codecs/vp8/screenshare_layers.cc
+++ b/modules/video_coding/codecs/vp8/screenshare_layers.cc
@@ -302,7 +302,7 @@
     return;
   }
 
-  absl::optional<DependencyInfo> dependency_info;
+  std::optional<DependencyInfo> dependency_info;
   auto it = pending_frame_configs_.find(rtp_timestamp);
   if (it != pending_frame_configs_.end()) {
     dependency_info = it->second;
@@ -510,9 +510,8 @@
         static_cast<float>(*capture_framerate_) / *target_framerate_;
   }
 
-  if (bitrate_updated_ ||
-      encoder_config_.rc_target_bitrate !=
-          absl::make_optional(encoder_config_bitrate_kbps)) {
+  if (bitrate_updated_ || encoder_config_.rc_target_bitrate !=
+                              std::make_optional(encoder_config_bitrate_kbps)) {
     encoder_config_.rc_target_bitrate = encoder_config_bitrate_kbps;
 
     // Don't reconfigure qp limits during quality boost frames.
diff --git a/modules/video_coding/codecs/vp8/screenshare_layers.h b/modules/video_coding/codecs/vp8/screenshare_layers.h
index 47d6b40..7f721ab 100644
--- a/modules/video_coding/codecs/vp8/screenshare_layers.h
+++ b/modules/video_coding/codecs/vp8/screenshare_layers.h
@@ -91,8 +91,8 @@
   const int number_of_temporal_layers_;
 
   // TODO(eladalon/sprang): These should be made into const-int set in the ctor.
-  absl::optional<int> min_qp_;
-  absl::optional<int> max_qp_;
+  std::optional<int> min_qp_;
+  std::optional<int> max_qp_;
 
   int active_layer_;
   int64_t last_timestamp_;
@@ -105,9 +105,9 @@
   std::map<uint32_t, DependencyInfo> pending_frame_configs_;
 
   // Configured max framerate.
-  absl::optional<uint32_t> target_framerate_;
+  std::optional<uint32_t> target_framerate_;
   // Incoming framerate from capturer.
-  absl::optional<uint32_t> capture_framerate_;
+  std::optional<uint32_t> capture_framerate_;
 
   // Tracks what framerate we actually encode, and drops frames on overshoot.
   RateStatistics encode_framerate_;
diff --git a/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc b/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc
index e5b3bd4..4fb599f 100644
--- a/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc
+++ b/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc
@@ -161,12 +161,10 @@
   // Adds frames until we get one in the specified temporal layer. The last
   // FrameEncoded() call will be omitted and needs to be done by the caller.
   // Returns the flags for the last frame.
-  int SkipUntilTl(int layer) {
-    return SkipUntilTlAndSync(layer, absl::nullopt);
-  }
+  int SkipUntilTl(int layer) { return SkipUntilTlAndSync(layer, std::nullopt); }
 
   // Same as SkipUntilTl, but also waits until the sync bit condition is met.
-  int SkipUntilTlAndSync(int layer, absl::optional<bool> sync) {
+  int SkipUntilTlAndSync(int layer, std::optional<bool> sync) {
     int flags = 0;
     const int kMaxFramesToSkip =
         1 + (sync.value_or(false) ? kMaxSyncPeriodSeconds : 1) * kFrameRate;
diff --git a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
index 8c03148..cb1b918 100644
--- a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
@@ -214,7 +214,7 @@
   CodecSpecificInfo codec_specific_info;
   input_frame_generator_ = test::CreateSquareFrameGenerator(
       kWidth, kHeight, test::FrameGeneratorInterface::OutputType::kNV12,
-      absl::nullopt);
+      std::nullopt);
   EncodeAndWaitForFrame(NextInputFrame(), &encoded_frame, &codec_specific_info);
 
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
@@ -231,11 +231,11 @@
   CodecSpecificInfo codec_specific_info;
   input_frame_generator_ = test::CreateSquareFrameGenerator(
       kWidth, kHeight, test::FrameGeneratorInterface::OutputType::kNV12,
-      absl::nullopt);
+      std::nullopt);
   EncodeAndWaitForFrame(NextInputFrame(), &encoded_frame, &codec_specific_info);
   input_frame_generator_ = test::CreateSquareFrameGenerator(
       kWidth, kHeight, test::FrameGeneratorInterface::OutputType::kI420,
-      absl::nullopt);
+      std::nullopt);
   EncodeAndWaitForFrame(NextInputFrame(), &encoded_frame, &codec_specific_info);
 
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
@@ -288,7 +288,7 @@
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, -1));
   std::unique_ptr<VideoFrame> decoded_frame;
-  absl::optional<uint8_t> decoded_qp;
+  std::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
   ASSERT_TRUE(decoded_frame);
   ASSERT_TRUE(decoded_qp);
@@ -504,7 +504,7 @@
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, -1));
 
   std::unique_ptr<VideoFrame> decoded_frame;
-  absl::optional<uint8_t> decoded_qp;
+  std::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
   ASSERT_TRUE(decoded_frame);
   // Compute PSNR on all planes (faster than SSIM).
@@ -574,7 +574,7 @@
   input_frame_generator_ = test::CreateSquareFrameGenerator(
       codec_settings_.width, codec_settings_.height,
       test::FrameGeneratorInterface::OutputType::kI420,
-      /* num_squares = */ absl::optional<int>(300));
+      /* num_squares = */ std::optional<int>(300));
 
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
             encoder_->InitEncode(&codec_settings_, kSettings));
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.cc
index c83f929..8be1757 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.cc
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.cc
@@ -169,7 +169,7 @@
   inited_ = true;
   // Always start with a complete key frame.
   key_frame_required_ = true;
-  if (absl::optional<int> buffer_pool_size = settings.buffer_pool_size()) {
+  if (std::optional<int> buffer_pool_size = settings.buffer_pool_size()) {
     if (!libvpx_buffer_pool_.Resize(*buffer_pool_size)) {
       return false;
     }
@@ -196,7 +196,7 @@
   }
 
   if (input_image._frameType == VideoFrameType::kVideoFrameKey) {
-    absl::optional<Vp9UncompressedHeader> frame_info =
+    std::optional<Vp9UncompressedHeader> frame_info =
         ParseUncompressedVp9Header(
             rtc::MakeArrayView(input_image.data(), input_image.size()));
     if (frame_info) {
@@ -353,7 +353,7 @@
   }
   VideoFrame decoded_image = builder.build();
 
-  decode_complete_callback_->Decoded(decoded_image, absl::nullopt, qp);
+  decode_complete_callback_->Decoded(decoded_image, std::nullopt, qp);
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
index 7a2b494..c9129ca 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
@@ -15,13 +15,13 @@
 
 #include <algorithm>
 #include <limits>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "absl/memory/memory.h"
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/video/color_space.h"
 #include "api/video/i010_buffer.h"
 #include "api/video_codecs/scalability_mode.h"
@@ -158,7 +158,7 @@
     }
   }
 
-  absl::optional<ScalabilityMode> scalability_mode =
+  std::optional<ScalabilityMode> scalability_mode =
       ScalabilityModeFromString(name);
   if (!scalability_mode.has_value()) {
     RTC_LOG(LS_WARNING) << "Invalid scalability mode " << name;
@@ -504,8 +504,8 @@
     return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
   }
 
-  absl::optional<vpx_img_fmt_t> previous_img_fmt =
-      raw_ ? absl::make_optional<vpx_img_fmt_t>(raw_->fmt) : absl::nullopt;
+  std::optional<vpx_img_fmt_t> previous_img_fmt =
+      raw_ ? std::make_optional<vpx_img_fmt_t>(raw_->fmt) : std::nullopt;
 
   int ret_val = Release();
   if (ret_val < 0) {
@@ -1214,8 +1214,8 @@
 }
 
 bool LibvpxVp9Encoder::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
-                                             absl::optional<int>* spatial_idx,
-                                             absl::optional<int>* temporal_idx,
+                                             std::optional<int>* spatial_idx,
+                                             std::optional<int>* temporal_idx,
                                              const vpx_codec_cx_pkt& pkt) {
   RTC_CHECK(codec_specific != nullptr);
   codec_specific->codecType = kVideoCodecVP9;
@@ -1241,14 +1241,14 @@
   if (num_temporal_layers_ == 1) {
     RTC_CHECK_EQ(layer_id.temporal_layer_id, 0);
     vp9_info->temporal_idx = kNoTemporalIdx;
-    *temporal_idx = absl::nullopt;
+    *temporal_idx = std::nullopt;
   } else {
     vp9_info->temporal_idx = layer_id.temporal_layer_id;
     *temporal_idx = layer_id.temporal_layer_id;
   }
   if (num_active_spatial_layers_ == 1) {
     RTC_CHECK_EQ(layer_id.spatial_layer_id, 0);
-    *spatial_idx = absl::nullopt;
+    *spatial_idx = std::nullopt;
   } else {
     *spatial_idx = layer_id.spatial_layer_id;
   }
@@ -1395,8 +1395,8 @@
     codec_specific_.scalability_mode = MakeScalabilityMode(
         num_active_spatial_layers_, num_temporal_layers_, inter_layer_pred_,
         num_active_spatial_layers_ > 1
-            ? absl::make_optional(ScalabilityModeResolutionRatio::kTwoToOne)
-            : absl::nullopt,
+            ? std::make_optional(ScalabilityModeResolutionRatio::kTwoToOne)
+            : std::nullopt,
         /*shift=*/false);
   }
 
@@ -1564,7 +1564,7 @@
   const bool is_inter_layer_pred_allowed =
       inter_layer_pred_ == InterLayerPredMode::kOn ||
       (inter_layer_pred_ == InterLayerPredMode::kOnKeyPic && is_key_pic);
-  absl::optional<int> last_updated_buf_idx;
+  std::optional<int> last_updated_buf_idx;
 
   // Put temporal reference to LAST and spatial reference to GOLDEN. Update
   // frame buffer (i.e. store encoded frame) if current frame is a temporal
@@ -1660,8 +1660,8 @@
       static_cast<const uint8_t*>(pkt->data.frame.buf), pkt->data.frame.sz));
 
   codec_specific_ = {};
-  absl::optional<int> spatial_index;
-  absl::optional<int> temporal_index;
+  std::optional<int> spatial_index;
+  std::optional<int> temporal_index;
   if (!PopulateCodecSpecific(&codec_specific_, &spatial_index, &temporal_index,
                              *pkt)) {
     // Drop the frame.
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
index f83fe2d..6454c98 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
@@ -69,8 +69,8 @@
   int InitAndSetControlSettings(const VideoCodec* inst);
 
   bool PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
-                             absl::optional<int>* spatial_idx,
-                             absl::optional<int>* temporal_idx,
+                             std::optional<int>* spatial_idx,
+                             std::optional<int>* temporal_idx,
                              const vpx_codec_cx_pkt& pkt);
   void FillReferenceIndices(const vpx_codec_cx_pkt& pkt,
                             size_t pic_num,
@@ -152,7 +152,7 @@
   bool force_all_active_layers_;
 
   std::unique_ptr<ScalableVideoController> svc_controller_;
-  absl::optional<ScalabilityMode> scalability_mode_;
+  std::optional<ScalabilityMode> scalability_mode_;
   std::vector<FramerateControllerDeprecated> framerate_controller_;
 
   // Used for flexible mode.
diff --git a/modules/video_coding/codecs/vp9/svc_config.cc b/modules/video_coding/codecs/vp9/svc_config.cc
index 555af83..cd3990d 100644
--- a/modules/video_coding/codecs/vp9/svc_config.cc
+++ b/modules/video_coding/codecs/vp9/svc_config.cc
@@ -83,7 +83,7 @@
     size_t first_active_layer,
     size_t num_spatial_layers,
     size_t num_temporal_layers,
-    absl::optional<ScalableVideoController::StreamLayersConfig> config) {
+    std::optional<ScalableVideoController::StreamLayersConfig> config) {
   RTC_DCHECK_LT(first_active_layer, num_spatial_layers);
 
   // Limit number of layers for given resolution.
@@ -169,7 +169,7 @@
 std::vector<SpatialLayer> GetVp9SvcConfig(VideoCodec& codec) {
   RTC_DCHECK_EQ(codec.codecType, kVideoCodecVP9);
 
-  absl::optional<ScalabilityMode> scalability_mode = codec.GetScalabilityMode();
+  std::optional<ScalabilityMode> scalability_mode = codec.GetScalabilityMode();
   RTC_DCHECK(scalability_mode.has_value());
 
   bool requested_single_spatial_layer =
@@ -193,7 +193,7 @@
   codec.VP9()->interLayerPred =
       ScalabilityModeToInterLayerPredMode(*scalability_mode);
 
-  absl::optional<ScalableVideoController::StreamLayersConfig> info =
+  std::optional<ScalableVideoController::StreamLayersConfig> info =
       ScalabilityStructureConfig(*scalability_mode);
   if (!info.has_value()) {
     RTC_LOG(LS_WARNING) << "Failed to create structure "
@@ -206,7 +206,7 @@
       GetSvcConfig(codec.width, codec.height, codec.maxFramerate,
                    /*first_active_layer=*/0, info->num_spatial_layers,
                    info->num_temporal_layers, /*is_screen_sharing=*/false,
-                   codec.GetScalabilityMode() ? info : absl::nullopt);
+                   codec.GetScalabilityMode() ? info : std::nullopt);
   RTC_DCHECK(!spatial_layers.empty());
 
   spatial_layers[0].minBitrate = kMinVp9SvcBitrateKbps;
@@ -230,7 +230,7 @@
     size_t num_spatial_layers,
     size_t num_temporal_layers,
     bool is_screen_sharing,
-    absl::optional<ScalableVideoController::StreamLayersConfig> config) {
+    std::optional<ScalableVideoController::StreamLayersConfig> config) {
   RTC_DCHECK_GT(input_width, 0);
   RTC_DCHECK_GT(input_height, 0);
   RTC_DCHECK_GT(num_spatial_layers, 0);
diff --git a/modules/video_coding/codecs/vp9/svc_config.h b/modules/video_coding/codecs/vp9/svc_config.h
index adeaf0f..eaf316b 100644
--- a/modules/video_coding/codecs/vp9/svc_config.h
+++ b/modules/video_coding/codecs/vp9/svc_config.h
@@ -31,8 +31,8 @@
     size_t num_spatial_layers,
     size_t num_temporal_layers,
     bool is_screen_sharing,
-    absl::optional<ScalableVideoController::StreamLayersConfig> config =
-        absl::nullopt);
+    std::optional<ScalableVideoController::StreamLayersConfig> config =
+        std::nullopt);
 
 }  // namespace webrtc
 
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 2632610..3a1f351 100644
--- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
@@ -125,7 +125,7 @@
  protected:
   void SetUp() override {
     input_frame_generator_ = test::CreateSquareFrameGenerator(
-        kWidth, kHeight, GetParam(), absl::optional<int>());
+        kWidth, kHeight, GetParam(), std::optional<int>());
     TestVp9Impl::SetUp();
   }
 };
@@ -145,7 +145,7 @@
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
-  absl::optional<uint8_t> decoded_qp;
+  std::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
   ASSERT_TRUE(decoded_frame);
   EXPECT_GT(I420PSNR(&input_frame, decoded_frame.get()), 36);
@@ -195,7 +195,7 @@
   // Encoded frame without explicit color space information.
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
-  absl::optional<uint8_t> decoded_qp;
+  std::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
   ASSERT_TRUE(decoded_frame);
   // Color space present from encoded bitstream.
@@ -213,7 +213,7 @@
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
-  absl::optional<uint8_t> decoded_qp;
+  std::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
   ASSERT_TRUE(decoded_frame);
   ASSERT_TRUE(decoded_qp);
@@ -242,14 +242,14 @@
   // Change the input frame type from I420 to NV12, encoding should still work.
   input_frame_generator_ = test::CreateSquareFrameGenerator(
       kWidth, kHeight, test::FrameGeneratorInterface::OutputType::kNV12,
-      absl::optional<int>());
+      std::optional<int>());
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
 
   // Flipping back to I420, encoding should still work.
   input_frame_generator_ = test::CreateSquareFrameGenerator(
       kWidth, kHeight, test::FrameGeneratorInterface::OutputType::kI420,
-      absl::optional<int>());
+      std::optional<int>());
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
 }
@@ -531,7 +531,7 @@
 }
 
 MATCHER_P2(GenericLayerIs, spatial_id, temporal_id, "") {
-  if (arg.codec_specific_info.generic_frame_info == absl::nullopt) {
+  if (arg.codec_specific_info.generic_frame_info == std::nullopt) {
     *result_listener << " miss generic_frame_info";
     return false;
   }
@@ -1861,8 +1861,8 @@
         frame.codec_specific_info.codecSpecific.VP9;
     EXPECT_EQ(frame.encoded_image.SpatialIndex(),
               num_spatial_layers_ == 1
-                  ? absl::nullopt
-                  : absl::optional<int>(i % num_spatial_layers_))
+                  ? std::nullopt
+                  : std::optional<int>(i % num_spatial_layers_))
         << "Frame " << i;
     EXPECT_EQ(vp9.temporal_idx, num_temporal_layers_ == 1
                                     ? kNoTemporalIdx
@@ -2009,8 +2009,7 @@
     TestVp9Impl::SetUp();
     input_frame_generator_ = test::CreateSquareFrameGenerator(
         codec_settings_.width, codec_settings_.height,
-        test::FrameGeneratorInterface::OutputType::kI010,
-        absl::optional<int>());
+        test::FrameGeneratorInterface::OutputType::kI010, std::optional<int>());
   }
 
   std::unique_ptr<VideoEncoder> CreateEncoder() override {
@@ -2035,7 +2034,7 @@
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
-  absl::optional<uint8_t> decoded_qp;
+  std::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
   ASSERT_TRUE(decoded_frame);
 
@@ -2431,7 +2430,7 @@
 
 struct SvcFrameDropConfigTestParameters {
   bool flexible_mode;
-  absl::optional<ScalabilityMode> scalability_mode;
+  std::optional<ScalabilityMode> scalability_mode;
   std::string field_trial;
   int expected_framedrop_mode;
   int expected_max_consec_drop;
@@ -2508,7 +2507,7 @@
         // controller is not enabled). Layer drop is not allowed.
         SvcFrameDropConfigTestParameters{
             .flexible_mode = true,
-            .scalability_mode = absl::nullopt,
+            .scalability_mode = std::nullopt,
             .expected_framedrop_mode = FULL_SUPERFRAME_DROP,
             .expected_max_consec_drop = 2}));
 
diff --git a/modules/video_coding/decoder_database.cc b/modules/video_coding/decoder_database.cc
index dabef41..4dba5c3 100644
--- a/modules/video_coding/decoder_database.cc
+++ b/modules/video_coding/decoder_database.cc
@@ -34,7 +34,7 @@
   // frame after RegisterReceiveCodec).
   if (current_decoder_ && current_decoder_->IsSameDecoder(it->second.get())) {
     // Release it if it was registered and in use.
-    current_decoder_ = absl::nullopt;
+    current_decoder_ = std::nullopt;
   }
   decoders_.erase(it);
 }
@@ -64,7 +64,7 @@
     const VideoDecoder::Settings& settings) {
   // If payload value already exists, erase old and insert new.
   if (payload_type == current_payload_type_) {
-    current_payload_type_ = absl::nullopt;
+    current_payload_type_ = std::nullopt;
   }
   decoder_settings_[payload_type] = settings;
 }
@@ -75,13 +75,13 @@
   }
   if (payload_type == current_payload_type_) {
     // This codec is currently in use.
-    current_payload_type_ = absl::nullopt;
+    current_payload_type_ = std::nullopt;
   }
   return true;
 }
 
 void VCMDecoderDatabase::DeregisterReceiveCodecs() {
-  current_payload_type_ = absl::nullopt;
+  current_payload_type_ = std::nullopt;
   decoder_settings_.clear();
 }
 
@@ -96,12 +96,12 @@
   }
   // If decoder exists - delete.
   if (current_decoder_.has_value()) {
-    current_decoder_ = absl::nullopt;
-    current_payload_type_ = absl::nullopt;
+    current_decoder_ = std::nullopt;
+    current_payload_type_ = std::nullopt;
   }
 
   CreateAndInitDecoder(frame);
-  if (current_decoder_ == absl::nullopt) {
+  if (current_decoder_ == std::nullopt) {
     return nullptr;
   }
 
@@ -109,7 +109,7 @@
   callback->OnIncomingPayloadType(payload_type);
   if (current_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) <
       0) {
-    current_decoder_ = absl::nullopt;
+    current_decoder_ = std::nullopt;
     return nullptr;
   }
 
@@ -144,7 +144,7 @@
     decoder_item->second.set_max_render_resolution(frame_resolution);
   }
   if (!current_decoder_->Configure(decoder_item->second)) {
-    current_decoder_ = absl::nullopt;
+    current_decoder_ = std::nullopt;
     RTC_LOG(LS_ERROR) << "Failed to initialize decoder.";
   }
 }
diff --git a/modules/video_coding/decoder_database.h b/modules/video_coding/decoder_database.h
index 87edcd0..951be7d 100644
--- a/modules/video_coding/decoder_database.h
+++ b/modules/video_coding/decoder_database.h
@@ -15,8 +15,8 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/sequence_checker.h"
 #include "api/video/encoded_frame.h"
 #include "api/video_codecs/video_decoder.h"
@@ -58,8 +58,8 @@
 
   SequenceChecker decoder_sequence_checker_;
 
-  absl::optional<uint8_t> current_payload_type_;
-  absl::optional<VCMGenericDecoder> current_decoder_
+  std::optional<uint8_t> current_payload_type_;
+  std::optional<VCMGenericDecoder> current_decoder_
       RTC_GUARDED_BY(decoder_sequence_checker_);
   // Initialization paramaters for decoders keyed by payload type.
   std::map<uint8_t, VideoDecoder::Settings> decoder_settings_;
diff --git a/modules/video_coding/deprecated/BUILD.gn b/modules/video_coding/deprecated/BUILD.gn
index dacde52..43c05fa 100644
--- a/modules/video_coding/deprecated/BUILD.gn
+++ b/modules/video_coding/deprecated/BUILD.gn
@@ -98,7 +98,6 @@
     "../../../api/video:video_frame_type",
     "../../../modules/rtp_rtcp:rtp_rtcp_format",
     "../../../modules/rtp_rtcp:rtp_video_header",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/modules/video_coding/deprecated/jitter_buffer.cc b/modules/video_coding/deprecated/jitter_buffer.cc
index 66f4cea..eff9edd 100644
--- a/modules/video_coding/deprecated/jitter_buffer.cc
+++ b/modules/video_coding/deprecated/jitter_buffer.cc
@@ -575,7 +575,7 @@
 uint32_t VCMJitterBuffer::EstimatedJitterMs() {
   MutexLock lock(&mutex_);
   const double rtt_mult = 1.0f;
-  return jitter_estimate_.GetJitterEstimate(rtt_mult, absl::nullopt).ms();
+  return jitter_estimate_.GetJitterEstimate(rtt_mult, std::nullopt).ms();
 }
 
 void VCMJitterBuffer::SetNackSettings(size_t max_nack_list_size,
diff --git a/modules/video_coding/deprecated/packet.cc b/modules/video_coding/deprecated/packet.cc
index 110f38e..d89933e 100644
--- a/modules/video_coding/deprecated/packet.cc
+++ b/modules/video_coding/deprecated/packet.cc
@@ -59,7 +59,7 @@
 
   // Playout decisions are made entirely based on first packet in a frame.
   if (!is_first_packet_in_frame()) {
-    video_header.playout_delay = absl::nullopt;
+    video_header.playout_delay = std::nullopt;
   }
 }
 
diff --git a/modules/video_coding/deprecated/packet.h b/modules/video_coding/deprecated/packet.h
index de69ff4..9a0e5ca 100644
--- a/modules/video_coding/deprecated/packet.h
+++ b/modules/video_coding/deprecated/packet.h
@@ -14,7 +14,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/rtp_headers.h"
 #include "api/rtp_packet_info.h"
 #include "api/units/timestamp.h"
@@ -71,7 +72,7 @@
   bool insertStartCode;  // True if a start code should be inserted before this
                          // packet.
   RTPVideoHeader video_header;
-  absl::optional<RtpGenericFrameDescriptor> generic_descriptor;
+  std::optional<RtpGenericFrameDescriptor> generic_descriptor;
 
   RtpPacketInfo packet_info;
 };
diff --git a/modules/video_coding/deprecated/receiver.cc b/modules/video_coding/deprecated/receiver.cc
index a048f84..524b1cb 100644
--- a/modules/video_coding/deprecated/receiver.cc
+++ b/modules/video_coding/deprecated/receiver.cc
@@ -90,7 +90,7 @@
   }
   uint32_t frame_timestamp = found_frame->RtpTimestamp();
 
-  if (absl::optional<VideoPlayoutDelay> playout_delay =
+  if (std::optional<VideoPlayoutDelay> playout_delay =
           found_frame->EncodedImage().PlayoutDelay()) {
     timing_->set_min_playout_delay(playout_delay->min());
     timing_->set_max_playout_delay(playout_delay->max());
diff --git a/modules/video_coding/encoded_frame.cc b/modules/video_coding/encoded_frame.cc
index dbac39c..6bbd218 100644
--- a/modules/video_coding/encoded_frame.cc
+++ b/modules/video_coding/encoded_frame.cc
@@ -37,7 +37,7 @@
 
 void VCMEncodedFrame::Reset() {
   SetRtpTimestamp(0);
-  SetSpatialIndex(absl::nullopt);
+  SetSpatialIndex(std::nullopt);
   _renderTimeMs = -1;
   _payloadType = 0;
   _frameType = VideoFrameType::kVideoFrameDelta;
diff --git a/modules/video_coding/frame_dependencies_calculator.cc b/modules/video_coding/frame_dependencies_calculator.cc
index 7ca59f7..39793db 100644
--- a/modules/video_coding/frame_dependencies_calculator.cc
+++ b/modules/video_coding/frame_dependencies_calculator.cc
@@ -41,7 +41,7 @@
       continue;
     }
     const BufferUsage& buffer = buffers_[buffer_usage.id];
-    if (buffer.frame_id == absl::nullopt) {
+    if (buffer.frame_id == std::nullopt) {
       RTC_LOG(LS_ERROR) << "Odd configuration: frame " << frame_id
                         << " references buffer #" << buffer_usage.id
                         << " that was never updated.";
diff --git a/modules/video_coding/frame_dependencies_calculator.h b/modules/video_coding/frame_dependencies_calculator.h
index 2c4a850..a296f21 100644
--- a/modules/video_coding/frame_dependencies_calculator.h
+++ b/modules/video_coding/frame_dependencies_calculator.h
@@ -13,10 +13,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
 #include "absl/container/inlined_vector.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "common_video/generic_frame_descriptor/generic_frame_info.h"
 
@@ -37,7 +37,7 @@
 
  private:
   struct BufferUsage {
-    absl::optional<int64_t> frame_id;
+    std::optional<int64_t> frame_id;
     absl::InlinedVector<int64_t, 4> dependencies;
   };
 
diff --git a/modules/video_coding/generic_decoder.cc b/modules/video_coding/generic_decoder.cc
index 0bfc628..1f2c600 100644
--- a/modules/video_coding/generic_decoder.cc
+++ b/modules/video_coding/generic_decoder.cc
@@ -15,10 +15,10 @@
 #include <algorithm>
 #include <cmath>
 #include <iterator>
+#include <optional>
 #include <utility>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/video/video_timing.h"
 #include "api/video_codecs/video_decoder.h"
 #include "modules/include/module_common_types_public.h"
@@ -73,15 +73,15 @@
 int32_t VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage,
                                          int64_t decode_time_ms) {
   Decoded(decodedImage,
-          decode_time_ms >= 0 ? absl::optional<int32_t>(decode_time_ms)
-                              : absl::nullopt,
-          absl::nullopt);
+          decode_time_ms >= 0 ? std::optional<int32_t>(decode_time_ms)
+                              : std::nullopt,
+          std::nullopt);
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
-std::pair<absl::optional<FrameInfo>, size_t>
+std::pair<std::optional<FrameInfo>, size_t>
 VCMDecodedFrameCallback::FindFrameInfo(uint32_t rtp_timestamp) {
-  absl::optional<FrameInfo> frame_info;
+  std::optional<FrameInfo> frame_info;
 
   auto it = absl::c_find_if(frame_infos_, [rtp_timestamp](const auto& entry) {
     return entry.rtp_timestamp == rtp_timestamp ||
@@ -100,15 +100,15 @@
 }
 
 void VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage,
-                                      absl::optional<int32_t> decode_time_ms,
-                                      absl::optional<uint8_t> qp) {
+                                      std::optional<int32_t> decode_time_ms,
+                                      std::optional<uint8_t> qp) {
   RTC_DCHECK(_receiveCallback) << "Callback must not be null at this point";
   TRACE_EVENT(
       "webrtc", "VCMDecodedFrameCallback::Decoded",
       perfetto::TerminatingFlow::ProcessScoped(decodedImage.rtp_timestamp()));
   // TODO(holmer): We should improve this so that we can handle multiple
   // callbacks from one call to Decode().
-  absl::optional<FrameInfo> frame_info;
+  std::optional<FrameInfo> frame_info;
   int timestamp_map_size = 0;
   int dropped_frames = 0;
   {
@@ -300,8 +300,8 @@
   frame_info.decode_start = now;
   frame_info.render_time =
       render_time_ms >= 0
-          ? absl::make_optional(Timestamp::Millis(render_time_ms))
-          : absl::nullopt;
+          ? std::make_optional(Timestamp::Millis(render_time_ms))
+          : std::nullopt;
   frame_info.rotation = frame.rotation();
   frame_info.timing = frame.video_timing();
   frame_info.ntp_time_ms = frame.ntp_time_ms_;
diff --git a/modules/video_coding/generic_decoder.h b/modules/video_coding/generic_decoder.h
index b1fb1f3..4859031 100644
--- a/modules/video_coding/generic_decoder.h
+++ b/modules/video_coding/generic_decoder.h
@@ -39,8 +39,8 @@
   // This is likely not optional, but some inputs seem to sometimes be negative.
   // TODO(bugs.webrtc.org/13756): See if this can be replaced with Timestamp
   // once all inputs to this field use Timestamp instead of an integer.
-  absl::optional<Timestamp> render_time;
-  absl::optional<Timestamp> decode_start;
+  std::optional<Timestamp> render_time;
+  std::optional<Timestamp> decode_start;
   VideoRotation rotation;
   VideoContentType content_type;
   EncodedImage::Timing timing;
@@ -62,8 +62,8 @@
   int32_t Decoded(VideoFrame& decodedImage) override;
   int32_t Decoded(VideoFrame& decodedImage, int64_t decode_time_ms) override;
   void Decoded(VideoFrame& decodedImage,
-               absl::optional<int32_t> decode_time_ms,
-               absl::optional<uint8_t> qp) override;
+               std::optional<int32_t> decode_time_ms,
+               std::optional<uint8_t> qp) override;
 
   void OnDecoderInfoChanged(const VideoDecoder::DecoderInfo& decoder_info);
 
@@ -71,7 +71,7 @@
   void ClearTimestampMap();
 
  private:
-  std::pair<absl::optional<FrameInfo>, size_t> FindFrameInfo(
+  std::pair<std::optional<FrameInfo>, size_t> FindFrameInfo(
       uint32_t rtp_timestamp) RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
   SequenceChecker construction_thread_;
diff --git a/modules/video_coding/generic_decoder_unittest.cc b/modules/video_coding/generic_decoder_unittest.cc
index 1142304..7edc961 100644
--- a/modules/video_coding/generic_decoder_unittest.cc
+++ b/modules/video_coding/generic_decoder_unittest.cc
@@ -12,9 +12,9 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/rtp_packet_infos.h"
 #include "api/video_codecs/video_decoder.h"
@@ -33,7 +33,7 @@
 class ReceiveCallback : public VCMReceiveCallback {
  public:
   int32_t FrameToRender(VideoFrame& frame,
-                        absl::optional<uint8_t> qp,
+                        std::optional<uint8_t> qp,
                         TimeDelta decode_time,
                         VideoContentType content_type,
                         VideoFrameType frame_type) override {
@@ -41,9 +41,9 @@
     return 0;
   }
 
-  absl::optional<VideoFrame> PopLastFrame() {
+  std::optional<VideoFrame> PopLastFrame() {
     if (frames_.empty())
-      return absl::nullopt;
+      return std::nullopt;
     auto ret = frames_.front();
     frames_.pop_back();
     return ret;
@@ -98,7 +98,7 @@
   encoded_frame.SetPacketInfos(packet_infos);
   generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
   time_controller_.AdvanceTime(TimeDelta::Millis(10));
-  absl::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
+  std::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
   ASSERT_TRUE(decoded_frame.has_value());
   EXPECT_EQ(decoded_frame->packet_infos().size(), 3U);
 }
@@ -134,7 +134,7 @@
   }
 
   time_controller_.AdvanceTime(TimeDelta::Millis(200));
-  absl::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
+  std::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
   ASSERT_TRUE(decoded_frame.has_value());
   EXPECT_EQ(decoded_frame->packet_infos().size(), 3U);
 }
@@ -143,11 +143,11 @@
   EncodedFrame encoded_frame;
   generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
   time_controller_.AdvanceTime(TimeDelta::Millis(10));
-  absl::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
+  std::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
   ASSERT_TRUE(decoded_frame.has_value());
   EXPECT_THAT(
       decoded_frame->render_parameters().max_composition_delay_in_frames,
-      testing::Eq(absl::nullopt));
+      testing::Eq(std::nullopt));
 }
 
 TEST_F(GenericDecoderTest, MaxCompositionDelayActivatedByPlayoutDelay) {
@@ -156,10 +156,10 @@
   // is specified as X,Y, where X=0, Y>0.
   constexpr int kMaxCompositionDelayInFrames = 3;  // ~50 ms at 60 fps.
   timing_.SetMaxCompositionDelayInFrames(
-      absl::make_optional(kMaxCompositionDelayInFrames));
+      std::make_optional(kMaxCompositionDelayInFrames));
   generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
   time_controller_.AdvanceTime(TimeDelta::Millis(10));
-  absl::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
+  std::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
   ASSERT_TRUE(decoded_frame.has_value());
   EXPECT_THAT(
       decoded_frame->render_parameters().max_composition_delay_in_frames,
@@ -170,7 +170,7 @@
   EncodedFrame encoded_frame;
   generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
   time_controller_.AdvanceTime(TimeDelta::Millis(10));
-  absl::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
+  std::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
   ASSERT_TRUE(decoded_frame.has_value());
   EXPECT_FALSE(decoded_frame->render_parameters().use_low_latency_rendering);
 }
@@ -183,7 +183,7 @@
   timing_.set_max_playout_delay(kPlayoutDelay.max());
   generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
   time_controller_.AdvanceTime(TimeDelta::Millis(10));
-  absl::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
+  std::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
   ASSERT_TRUE(decoded_frame.has_value());
   EXPECT_TRUE(decoded_frame->render_parameters().use_low_latency_rendering);
 }
diff --git a/modules/video_coding/h264_sps_pps_tracker.cc b/modules/video_coding/h264_sps_pps_tracker.cc
index 834a36d..0d7931c 100644
--- a/modules/video_coding/h264_sps_pps_tracker.cc
+++ b/modules/video_coding/h264_sps_pps_tracker.cc
@@ -216,9 +216,9 @@
     RTC_LOG(LS_WARNING) << "SPS Nalu header missing";
     return;
   }
-  absl::optional<SpsParser::SpsState> parsed_sps = SpsParser::ParseSps(
+  std::optional<SpsParser::SpsState> parsed_sps = SpsParser::ParseSps(
       rtc::ArrayView<const uint8_t>(sps).subview(kNaluHeaderOffset));
-  absl::optional<PpsParser::PpsState> parsed_pps = PpsParser::ParsePps(
+  std::optional<PpsParser::PpsState> parsed_pps = PpsParser::ParsePps(
       rtc::ArrayView<const uint8_t>(pps).subview(kNaluHeaderOffset));
 
   if (!parsed_sps) {
diff --git a/modules/video_coding/h26x_packet_buffer.cc b/modules/video_coding/h26x_packet_buffer.cc
index e9f6353..9020bb7 100644
--- a/modules/video_coding/h26x_packet_buffer.cc
+++ b/modules/video_coding/h26x_packet_buffer.cc
@@ -338,9 +338,9 @@
     RTC_LOG(LS_WARNING) << "SPS Nalu header missing";
     return;
   }
-  absl::optional<SpsParser::SpsState> parsed_sps = SpsParser::ParseSps(
+  std::optional<SpsParser::SpsState> parsed_sps = SpsParser::ParseSps(
       rtc::ArrayView<const uint8_t>(sps).subview(kNaluHeaderOffset));
-  absl::optional<PpsParser::PpsState> parsed_pps = PpsParser::ParsePps(
+  std::optional<PpsParser::PpsState> parsed_pps = PpsParser::ParsePps(
       rtc::ArrayView<const uint8_t>(pps).subview(kNaluHeaderOffset));
 
   if (!parsed_sps) {
diff --git a/modules/video_coding/h26x_packet_buffer.h b/modules/video_coding/h26x_packet_buffer.h
index f199341..62b97d3 100644
--- a/modules/video_coding/h26x_packet_buffer.h
+++ b/modules/video_coding/h26x_packet_buffer.h
@@ -14,11 +14,11 @@
 #include <array>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/base/attributes.h"
-#include "absl/types/optional.h"
 #include "modules/video_coding/packet_buffer.h"
 #include "rtc_base/numerics/sequence_number_unwrapper.h"
 
diff --git a/modules/video_coding/include/video_codec_interface.h b/modules/video_coding/include/video_codec_interface.h
index 987e1b6..243ac07 100644
--- a/modules/video_coding/include/video_codec_interface.h
+++ b/modules/video_coding/include/video_codec_interface.h
@@ -11,9 +11,9 @@
 #ifndef MODULES_VIDEO_CODING_INCLUDE_VIDEO_CODEC_INTERFACE_H_
 #define MODULES_VIDEO_CODING_INCLUDE_VIDEO_CODEC_INTERFACE_H_
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/video/video_frame.h"
 #include "api/video_codecs/scalability_mode.h"
 #include "api/video_codecs/video_decoder.h"
@@ -116,9 +116,9 @@
   VideoCodecType codecType;
   CodecSpecificInfoUnion codecSpecific;
   bool end_of_picture = true;
-  absl::optional<GenericFrameInfo> generic_frame_info;
-  absl::optional<FrameDependencyStructure> template_structure;
-  absl::optional<ScalabilityMode> scalability_mode;
+  std::optional<GenericFrameInfo> generic_frame_info;
+  std::optional<FrameDependencyStructure> template_structure;
+  std::optional<ScalabilityMode> scalability_mode;
 };
 
 }  // namespace webrtc
diff --git a/modules/video_coding/include/video_coding_defines.h b/modules/video_coding/include/video_coding_defines.h
index cbd4207..4821d5e 100644
--- a/modules/video_coding/include/video_coding_defines.h
+++ b/modules/video_coding/include/video_coding_defines.h
@@ -14,7 +14,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/video/video_content_type.h"
 #include "api/video/video_frame.h"
 #include "api/video/video_timing.h"
@@ -51,7 +52,7 @@
 class VCMReceiveCallback {
  public:
   virtual int32_t FrameToRender(VideoFrame& videoFrame,  // NOLINT
-                                absl::optional<uint8_t> qp,
+                                std::optional<uint8_t> qp,
                                 TimeDelta decode_time,
                                 VideoContentType content_type,
                                 VideoFrameType frame_type) = 0;
diff --git a/modules/video_coding/loss_notification_controller.h b/modules/video_coding/loss_notification_controller.h
index ecba412..d777884 100644
--- a/modules/video_coding/loss_notification_controller.h
+++ b/modules/video_coding/loss_notification_controller.h
@@ -13,9 +13,9 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <set>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/sequence_checker.h"
 #include "modules/include/module_common_types.h"
@@ -75,11 +75,11 @@
       RTC_GUARDED_BY(sequence_checker_);
 
   // Tracked to avoid processing repeated frames (buggy/malicious remote).
-  absl::optional<int64_t> last_received_frame_id_
+  std::optional<int64_t> last_received_frame_id_
       RTC_GUARDED_BY(sequence_checker_);
 
   // Tracked to avoid processing repeated packets.
-  absl::optional<uint16_t> last_received_seq_num_
+  std::optional<uint16_t> last_received_seq_num_
       RTC_GUARDED_BY(sequence_checker_);
 
   // Tracked in order to correctly report the potential-decodability of
@@ -95,7 +95,7 @@
     explicit FrameInfo(uint16_t first_seq_num) : first_seq_num(first_seq_num) {}
     uint16_t first_seq_num;
   };
-  absl::optional<FrameInfo> last_decodable_non_discardable_
+  std::optional<FrameInfo> last_decodable_non_discardable_
       RTC_GUARDED_BY(sequence_checker_);
 
   // Track which frames are decodable. Later frames are also decodable if
diff --git a/modules/video_coding/loss_notification_controller_unittest.cc b/modules/video_coding/loss_notification_controller_unittest.cc
index 9c4e715..83beb63 100644
--- a/modules/video_coding/loss_notification_controller_unittest.cc
+++ b/modules/video_coding/loss_notification_controller_unittest.cc
@@ -13,12 +13,12 @@
 #include <stdint.h>
 
 #include <limits>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "test/gtest.h"
 
 namespace webrtc {
@@ -138,7 +138,7 @@
   }
 
   void ExpectKeyFrameRequest() {
-    EXPECT_EQ(LastLossNotification(), absl::nullopt);
+    EXPECT_EQ(LastLossNotification(), std::nullopt);
     EXPECT_TRUE(LastKeyFrameRequest());
   }
 
@@ -188,9 +188,9 @@
     return result;
   }
 
-  absl::optional<LossNotification> LastLossNotification() {
-    const absl::optional<LossNotification> result = last_loss_notification_;
-    last_loss_notification_ = absl::nullopt;
+  std::optional<LossNotification> LastLossNotification() {
+    const std::optional<LossNotification> result = last_loss_notification_;
+    last_loss_notification_ = std::nullopt;
     return result;
   }
 
@@ -198,13 +198,13 @@
 
   bool key_frame_requested_;
 
-  absl::optional<LossNotification> last_loss_notification_;
+  std::optional<LossNotification> last_loss_notification_;
 
   // First packet of last frame. (Note that if a test skips the first packet
   // of a subsequent frame, OnAssembledFrame is not called, and so this is
   // note read. Therefore, it's not a problem if it is not cleared when
   // the frame changes.)
-  absl::optional<Packet> previous_first_packet_in_frame_;
+  std::optional<Packet> previous_first_packet_in_frame_;
 };
 
 class LossNotificationControllerTest
diff --git a/modules/video_coding/packet_buffer.h b/modules/video_coding/packet_buffer.h
index 9e143b8..495f64b 100644
--- a/modules/video_coding/packet_buffer.h
+++ b/modules/video_coding/packet_buffer.h
@@ -117,7 +117,7 @@
   // determine continuity between them.
   std::vector<std::unique_ptr<Packet>> buffer_;
 
-  absl::optional<uint16_t> newest_inserted_seq_num_;
+  std::optional<uint16_t> newest_inserted_seq_num_;
   std::set<uint16_t, DescendingSeqNumComp<uint16_t>> missing_packets_;
 
   std::set<uint16_t, DescendingSeqNumComp<uint16_t>> received_padding_;
diff --git a/modules/video_coding/rtp_frame_reference_finder_unittest.cc b/modules/video_coding/rtp_frame_reference_finder_unittest.cc
index 0ca2cf0..8ade214 100644
--- a/modules/video_coding/rtp_frame_reference_finder_unittest.cc
+++ b/modules/video_coding/rtp_frame_reference_finder_unittest.cc
@@ -54,7 +54,7 @@
       kVideoRotation_0,
       VideoContentType::UNSPECIFIED,
       video_header,
-      /*color_space=*/absl::nullopt,
+      /*color_space=*/std::nullopt,
       RtpPacketInfos(),
       EncodedImageBuffer::Create(/*size=*/0));
   // clang-format on
diff --git a/modules/video_coding/rtp_vp8_ref_finder_unittest.cc b/modules/video_coding/rtp_vp8_ref_finder_unittest.cc
index a27085e..01ff233 100644
--- a/modules/video_coding/rtp_vp8_ref_finder_unittest.cc
+++ b/modules/video_coding/rtp_vp8_ref_finder_unittest.cc
@@ -92,7 +92,7 @@
         kVideoRotation_0,
         VideoContentType::UNSPECIFIED,
         video_header,
-        /*color_space=*/absl::nullopt,
+        /*color_space=*/std::nullopt,
         RtpPacketInfos(),
         EncodedImageBuffer::Create(/*size=*/0));
     // clang-format on
@@ -100,9 +100,9 @@
 
  private:
   bool is_keyframe_ = false;
-  absl::optional<int> picture_id_;
-  absl::optional<int> temporal_id_;
-  absl::optional<int> tl0_idx_;
+  std::optional<int> picture_id_;
+  std::optional<int> temporal_id_;
+  std::optional<int> tl0_idx_;
   bool sync = false;
 };
 
diff --git a/modules/video_coding/rtp_vp9_ref_finder_unittest.cc b/modules/video_coding/rtp_vp9_ref_finder_unittest.cc
index 23b6cfc..35d30ad 100644
--- a/modules/video_coding/rtp_vp9_ref_finder_unittest.cc
+++ b/modules/video_coding/rtp_vp9_ref_finder_unittest.cc
@@ -128,7 +128,7 @@
         kVideoRotation_0,
         VideoContentType::UNSPECIFIED,
         video_header,
-        /*color_space=*/absl::nullopt,
+        /*color_space=*/std::nullopt,
         RtpPacketInfos(),
         EncodedImageBuffer::Create(/*size=*/0));
     // clang-format on
@@ -138,10 +138,10 @@
   uint16_t seq_num_start = 0;
   uint16_t seq_num_end = 0;
   bool keyframe = false;
-  absl::optional<int> picture_id;
-  absl::optional<int> spatial_id;
-  absl::optional<int> temporal_id;
-  absl::optional<int> tl0_idx;
+  std::optional<int> picture_id;
+  std::optional<int> spatial_id;
+  std::optional<int> temporal_id;
+  std::optional<int> tl0_idx;
   bool up_switch = false;
   bool inter_layer = false;
   bool inter_pic = true;
diff --git a/modules/video_coding/svc/BUILD.gn b/modules/video_coding/svc/BUILD.gn
index b80a5e4..79ebec7 100644
--- a/modules/video_coding/svc/BUILD.gn
+++ b/modules/video_coding/svc/BUILD.gn
@@ -19,7 +19,6 @@
     "../../../rtc_base:checks",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -61,7 +60,6 @@
     "../../../rtc_base:logging",
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -109,7 +107,6 @@
       "../../../rtc_base:stringutils",
       "../../../test:test_support",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
diff --git a/modules/video_coding/svc/create_scalability_structure.cc b/modules/video_coding/svc/create_scalability_structure.cc
index fbcd27b..33370c7 100644
--- a/modules/video_coding/svc/create_scalability_structure.cc
+++ b/modules/video_coding/svc/create_scalability_structure.cc
@@ -282,14 +282,14 @@
   return nullptr;
 }
 
-absl::optional<ScalableVideoController::StreamLayersConfig>
+std::optional<ScalableVideoController::StreamLayersConfig>
 ScalabilityStructureConfig(ScalabilityMode name) {
   for (const auto& entry : kFactories) {
     if (entry.name == name) {
       return entry.config;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace webrtc
diff --git a/modules/video_coding/svc/create_scalability_structure.h b/modules/video_coding/svc/create_scalability_structure.h
index 3b67443..2544b66 100644
--- a/modules/video_coding/svc/create_scalability_structure.h
+++ b/modules/video_coding/svc/create_scalability_structure.h
@@ -11,9 +11,9 @@
 #define MODULES_VIDEO_CODING_SVC_CREATE_SCALABILITY_STRUCTURE_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/video_codecs/scalability_mode.h"
 #include "modules/video_coding/svc/scalable_video_controller.h"
 
@@ -27,7 +27,7 @@
 
 // Returns description of the scalability structure identified by 'name',
 // Return nullopt for unknown name.
-absl::optional<ScalableVideoController::StreamLayersConfig>
+std::optional<ScalableVideoController::StreamLayersConfig>
 ScalabilityStructureConfig(ScalabilityMode name);
 
 }  // namespace webrtc
diff --git a/modules/video_coding/svc/scalability_mode_util.cc b/modules/video_coding/svc/scalability_mode_util.cc
index 580500f..9ee30f4 100644
--- a/modules/video_coding/svc/scalability_mode_util.cc
+++ b/modules/video_coding/svc/scalability_mode_util.cc
@@ -12,11 +12,11 @@
 
 #include <array>
 #include <cstddef>
+#include <optional>
 #include <type_traits>
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/video_codecs/scalability_mode.h"
 #include "api/video_codecs/video_codec.h"
 #include "rtc_base/checks.h"
@@ -31,7 +31,7 @@
   const int num_spatial_layers;
   const int num_temporal_layers;
   const InterLayerPredMode inter_layer_pred;
-  const absl::optional<ScalabilityModeResolutionRatio> ratio =
+  const std::optional<ScalabilityModeResolutionRatio> ratio =
       ScalabilityModeResolutionRatio::kTwoToOne;
   const bool shift = false;
 };
@@ -45,19 +45,19 @@
                               .num_spatial_layers = 1,
                               .num_temporal_layers = 1,
                               .inter_layer_pred = InterLayerPredMode::kOff,
-                              .ratio = absl::nullopt},
+                              .ratio = std::nullopt},
     ScalabilityModeParameters{.scalability_mode = ScalabilityMode::kL1T2,
                               .name = "L1T2",
                               .num_spatial_layers = 1,
                               .num_temporal_layers = 2,
                               .inter_layer_pred = InterLayerPredMode::kOff,
-                              .ratio = absl::nullopt},
+                              .ratio = std::nullopt},
     ScalabilityModeParameters{.scalability_mode = ScalabilityMode::kL1T3,
                               .name = "L1T3",
                               .num_spatial_layers = 1,
                               .num_temporal_layers = 3,
                               .inter_layer_pred = InterLayerPredMode::kOff,
-                              .ratio = absl::nullopt},
+                              .ratio = std::nullopt},
     ScalabilityModeParameters{
         .scalability_mode = ScalabilityMode::kL2T1,
         .name = "L2T1",
@@ -312,11 +312,11 @@
 
 }  // namespace
 
-absl::optional<ScalabilityMode> MakeScalabilityMode(
+std::optional<ScalabilityMode> MakeScalabilityMode(
     int num_spatial_layers,
     int num_temporal_layers,
     InterLayerPredMode inter_layer_pred,
-    absl::optional<ScalabilityModeResolutionRatio> ratio,
+    std::optional<ScalabilityModeResolutionRatio> ratio,
     bool shift) {
   for (const auto& candidate_mode : kScalabilityModeParams) {
     if (candidate_mode.num_spatial_layers == num_spatial_layers &&
@@ -328,10 +328,10 @@
       }
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<ScalabilityMode> ScalabilityModeFromString(
+std::optional<ScalabilityMode> ScalabilityModeFromString(
     absl::string_view mode_string) {
   const auto it =
       absl::c_find_if(kScalabilityModeParams,
@@ -341,7 +341,7 @@
   if (it != std::end(kScalabilityModeParams)) {
     return it->scalability_mode;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 InterLayerPredMode ScalabilityModeToInterLayerPredMode(
@@ -357,7 +357,7 @@
   return kScalabilityModeParams[Idx(scalability_mode)].num_temporal_layers;
 }
 
-absl::optional<ScalabilityModeResolutionRatio> ScalabilityModeToResolutionRatio(
+std::optional<ScalabilityModeResolutionRatio> ScalabilityModeToResolutionRatio(
     ScalabilityMode scalability_mode) {
   return kScalabilityModeParams[Idx(scalability_mode)].ratio;
 }
diff --git a/modules/video_coding/svc/scalability_mode_util.h b/modules/video_coding/svc/scalability_mode_util.h
index cfc247b..4e80796 100644
--- a/modules/video_coding/svc/scalability_mode_util.h
+++ b/modules/video_coding/svc/scalability_mode_util.h
@@ -11,8 +11,9 @@
 #ifndef MODULES_VIDEO_CODING_SVC_SCALABILITY_MODE_UTIL_H_
 #define MODULES_VIDEO_CODING_SVC_SCALABILITY_MODE_UTIL_H_
 
+#include <optional>
+
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/video_codecs/scalability_mode.h"
 #include "api/video_codecs/video_codec.h"
 
@@ -25,14 +26,14 @@
 
 static constexpr char kDefaultScalabilityModeStr[] = "L1T2";
 
-RTC_EXPORT absl::optional<ScalabilityMode> MakeScalabilityMode(
+RTC_EXPORT std::optional<ScalabilityMode> MakeScalabilityMode(
     int num_spatial_layers,
     int num_temporal_layers,
     InterLayerPredMode inter_layer_pred,
-    absl::optional<ScalabilityModeResolutionRatio> ratio,
+    std::optional<ScalabilityModeResolutionRatio> ratio,
     bool shift);
 
-absl::optional<ScalabilityMode> ScalabilityModeFromString(
+std::optional<ScalabilityMode> ScalabilityModeFromString(
     absl::string_view scalability_mode_string);
 
 InterLayerPredMode ScalabilityModeToInterLayerPredMode(
@@ -42,7 +43,7 @@
 
 int ScalabilityModeToNumTemporalLayers(ScalabilityMode scalability_mode);
 
-absl::optional<ScalabilityModeResolutionRatio> ScalabilityModeToResolutionRatio(
+std::optional<ScalabilityModeResolutionRatio> ScalabilityModeToResolutionRatio(
     ScalabilityMode scalability_mode);
 
 bool ScalabilityModeIsShiftMode(ScalabilityMode scalability_mode);
diff --git a/modules/video_coding/svc/scalability_mode_util_unittest.cc b/modules/video_coding/svc/scalability_mode_util_unittest.cc
index b023a12..346944c 100644
--- a/modules/video_coding/svc/scalability_mode_util_unittest.cc
+++ b/modules/video_coding/svc/scalability_mode_util_unittest.cc
@@ -10,12 +10,12 @@
 
 #include "modules/video_coding/svc/scalability_mode_util.h"
 
+#include <optional>
 #include <string>
 #include <tuple>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/video_codecs/scalability_mode.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
@@ -30,8 +30,8 @@
 }
 
 TEST(ScalabilityModeUtil, RejectsUnknownString) {
-  EXPECT_EQ(ScalabilityModeFromString(""), absl::nullopt);
-  EXPECT_EQ(ScalabilityModeFromString("not-a-mode"), absl::nullopt);
+  EXPECT_EQ(ScalabilityModeFromString(""), std::nullopt);
+  EXPECT_EQ(ScalabilityModeFromString("not-a-mode"), std::nullopt);
 }
 
 TEST(ScalabilityModeUtil, MakeScalabilityModeRoundTrip) {
@@ -40,7 +40,7 @@
        numerical_enum++) {
     ScalabilityMode scalability_mode =
         static_cast<ScalabilityMode>(numerical_enum);
-    absl::optional<ScalabilityMode> created_mode = MakeScalabilityMode(
+    std::optional<ScalabilityMode> created_mode = MakeScalabilityMode(
         ScalabilityModeToNumSpatialLayers(scalability_mode),
         ScalabilityModeToNumTemporalLayers(scalability_mode),
         ScalabilityModeToInterLayerPredMode(scalability_mode),
diff --git a/modules/video_coding/svc/scalability_structure_full_svc.cc b/modules/video_coding/svc/scalability_structure_full_svc.cc
index a262317..d440b23 100644
--- a/modules/video_coding/svc/scalability_structure_full_svc.cc
+++ b/modules/video_coding/svc/scalability_structure_full_svc.cc
@@ -9,11 +9,11 @@
  */
 #include "modules/video_coding/svc/scalability_structure_full_svc.h"
 
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/transport/rtp/dependency_descriptor.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
@@ -142,7 +142,7 @@
   }
   FramePattern current_pattern = NextPattern();
 
-  absl::optional<int> spatial_dependency_buffer_id;
+  std::optional<int> spatial_dependency_buffer_id;
   switch (current_pattern) {
     case kDeltaT0:
     case kKey:
diff --git a/modules/video_coding/svc/scalability_structure_key_svc.cc b/modules/video_coding/svc/scalability_structure_key_svc.cc
index 0e6fecf..4e771bb 100644
--- a/modules/video_coding/svc/scalability_structure_key_svc.cc
+++ b/modules/video_coding/svc/scalability_structure_key_svc.cc
@@ -10,10 +10,10 @@
 #include "modules/video_coding/svc/scalability_structure_key_svc.h"
 
 #include <bitset>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/transport/rtp/dependency_descriptor.h"
 #include "api/video/video_bitrate_allocation.h"
 #include "common_video/generic_frame_descriptor/generic_frame_info.h"
@@ -90,7 +90,7 @@
 ScalabilityStructureKeySvc::KeyframeConfig() {
   std::vector<LayerFrameConfig> configs;
   configs.reserve(num_spatial_layers_);
-  absl::optional<int> spatial_dependency_buffer_id;
+  std::optional<int> spatial_dependency_buffer_id;
   spatial_id_is_enabled_.reset();
   // Disallow temporal references cross T0 on higher temporal layers.
   can_reference_t1_frame_for_spatial_id_.reset();
diff --git a/modules/video_coding/svc/scalability_structure_unittest.cc b/modules/video_coding/svc/scalability_structure_unittest.cc
index 2d517c5..9c350ed 100644
--- a/modules/video_coding/svc/scalability_structure_unittest.cc
+++ b/modules/video_coding/svc/scalability_structure_unittest.cc
@@ -12,10 +12,10 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <ostream>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/transport/rtp/dependency_descriptor.h"
 #include "modules/video_coding/svc/create_scalability_structure.h"
@@ -85,7 +85,7 @@
   }
 
   ScalabilityMode GetScalabilityMode() const {
-    absl::optional<ScalabilityMode> scalability_mode =
+    std::optional<ScalabilityMode> scalability_mode =
         ScalabilityModeFromString(name);
     RTC_CHECK(scalability_mode.has_value());
     return *scalability_mode;
@@ -101,10 +101,10 @@
        StaticConfigMatchesConfigReturnedByController) {
   std::unique_ptr<ScalableVideoController> controller =
       CreateScalabilityStructure(GetParam().GetScalabilityMode());
-  absl::optional<ScalableVideoController::StreamLayersConfig> static_config =
+  std::optional<ScalableVideoController::StreamLayersConfig> static_config =
       ScalabilityStructureConfig(GetParam().GetScalabilityMode());
   ASSERT_THAT(controller, NotNull());
-  ASSERT_NE(static_config, absl::nullopt);
+  ASSERT_NE(static_config, std::nullopt);
   ScalableVideoController::StreamLayersConfig config =
       controller->StreamConfig();
   EXPECT_EQ(config.num_spatial_layers, static_config->num_spatial_layers);
diff --git a/modules/video_coding/svc/svc_rate_allocator.cc b/modules/video_coding/svc/svc_rate_allocator.cc
index f3514a1..0f29fca 100644
--- a/modules/video_coding/svc/svc_rate_allocator.cc
+++ b/modules/video_coding/svc/svc_rate_allocator.cc
@@ -174,7 +174,7 @@
 SvcRateAllocator::NumLayers SvcRateAllocator::GetNumLayers(
     const VideoCodec& codec) {
   NumLayers layers;
-  if (absl::optional<ScalabilityMode> scalability_mode =
+  if (std::optional<ScalabilityMode> scalability_mode =
           codec.GetScalabilityMode();
       scalability_mode.has_value()) {
     if (auto structure = CreateScalabilityStructure(*scalability_mode)) {
diff --git a/modules/video_coding/timing/BUILD.gn b/modules/video_coding/timing/BUILD.gn
index 2cace29..f6fdc54 100644
--- a/modules/video_coding/timing/BUILD.gn
+++ b/modules/video_coding/timing/BUILD.gn
@@ -27,7 +27,6 @@
     "../../../api/units:time_delta",
     "../../../api/units:timestamp",
     "../../../rtc_base:rtc_numerics",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -67,7 +66,6 @@
     "../../../rtc_base/experiments:field_trial_parser",
     "../../../system_wrappers",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -92,7 +90,6 @@
     "../../../api/units:timestamp",
     "../../../modules:module_api_public",
     "../../../rtc_base:rtc_numerics",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -114,7 +111,6 @@
     "../../../rtc_base/experiments:field_trial_parser",
     "../../../rtc_base/synchronization:mutex",
     "../../../system_wrappers",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -146,6 +142,5 @@
     "../../../system_wrappers:system_wrappers",
     "../../../test:scoped_key_value_config",
     "../../../test:test_support",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
diff --git a/modules/video_coding/timing/inter_frame_delay_variation_calculator.cc b/modules/video_coding/timing/inter_frame_delay_variation_calculator.cc
index 69bc916..3b464ee 100644
--- a/modules/video_coding/timing/inter_frame_delay_variation_calculator.cc
+++ b/modules/video_coding/timing/inter_frame_delay_variation_calculator.cc
@@ -10,7 +10,8 @@
 
 #include "modules/video_coding/timing/inter_frame_delay_variation_calculator.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/frequency.h"
 #include "api/units/time_delta.h"
 #include "modules/include/module_common_types_public.h"
@@ -26,11 +27,11 @@
 }
 
 void InterFrameDelayVariationCalculator::Reset() {
-  prev_wall_clock_ = absl::nullopt;
+  prev_wall_clock_ = std::nullopt;
   prev_rtp_timestamp_unwrapped_ = 0;
 }
 
-absl::optional<TimeDelta> InterFrameDelayVariationCalculator::Calculate(
+std::optional<TimeDelta> InterFrameDelayVariationCalculator::Calculate(
     uint32_t rtp_timestamp,
     Timestamp now) {
   int64_t rtp_timestamp_unwrapped = unwrapper_.Unwrap(rtp_timestamp);
@@ -39,7 +40,7 @@
     prev_wall_clock_ = now;
     prev_rtp_timestamp_unwrapped_ = rtp_timestamp_unwrapped;
     // Inter-frame delay variation is undefined for a single frame.
-    // TODO(brandtr): Should this return absl::nullopt instead?
+    // TODO(brandtr): Should this return std::nullopt instead?
     return TimeDelta::Zero();
   }
 
@@ -49,7 +50,7 @@
   uint32_t cropped_prev = static_cast<uint32_t>(prev_rtp_timestamp_unwrapped_);
   if (rtp_timestamp_unwrapped < prev_rtp_timestamp_unwrapped_ ||
       !IsNewerTimestamp(rtp_timestamp, cropped_prev)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Compute the compensated timestamp difference.
diff --git a/modules/video_coding/timing/inter_frame_delay_variation_calculator.h b/modules/video_coding/timing/inter_frame_delay_variation_calculator.h
index c1d3d20..d8a8c83 100644
--- a/modules/video_coding/timing/inter_frame_delay_variation_calculator.h
+++ b/modules/video_coding/timing/inter_frame_delay_variation_calculator.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
 #include "rtc_base/numerics/sequence_number_unwrapper.h"
@@ -32,11 +33,11 @@
 
   // Calculates the inter-frame delay variation of a frame with the given
   // RTP timestamp. This method is called when the frame is complete.
-  absl::optional<TimeDelta> Calculate(uint32_t rtp_timestamp, Timestamp now);
+  std::optional<TimeDelta> Calculate(uint32_t rtp_timestamp, Timestamp now);
 
  private:
   // The previous wall clock timestamp used in the calculation.
-  absl::optional<Timestamp> prev_wall_clock_;
+  std::optional<Timestamp> prev_wall_clock_;
   // The previous RTP timestamp used in the calculation.
   int64_t prev_rtp_timestamp_unwrapped_;
 
diff --git a/modules/video_coding/timing/inter_frame_delay_variation_calculator_unittest.cc b/modules/video_coding/timing/inter_frame_delay_variation_calculator_unittest.cc
index ea719b6..d193318 100644
--- a/modules/video_coding/timing/inter_frame_delay_variation_calculator_unittest.cc
+++ b/modules/video_coding/timing/inter_frame_delay_variation_calculator_unittest.cc
@@ -11,8 +11,8 @@
 #include "modules/video_coding/timing/inter_frame_delay_variation_calculator.h"
 
 #include <limits>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/units/frequency.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -40,7 +40,7 @@
   InterFrameDelayVariationCalculator ifdv_calculator;
   EXPECT_THAT(ifdv_calculator.Calculate(180000, kStartTime),
               Optional(TimeDelta::Zero()));
-  EXPECT_THAT(ifdv_calculator.Calculate(90000, kStartTime), Eq(absl::nullopt));
+  EXPECT_THAT(ifdv_calculator.Calculate(90000, kStartTime), Eq(std::nullopt));
 }
 
 TEST(InterFrameDelayVariationCalculatorTest,
@@ -51,7 +51,7 @@
               Optional(TimeDelta::Zero()));
   // RTP has wrapped around backwards.
   rtp -= 3000;
-  EXPECT_THAT(ifdv_calculator.Calculate(rtp, kStartTime), Eq(absl::nullopt));
+  EXPECT_THAT(ifdv_calculator.Calculate(rtp, kStartTime), Eq(std::nullopt));
 }
 
 TEST(InterFrameDelayVariationCalculatorTest, CorrectDelayForFrames) {
@@ -184,7 +184,7 @@
   // Frame delay should be as normal, in this case simulated as 1ms late.
   clock.AdvanceTime(kFrameDelay);
   EXPECT_THAT(ifdv_calculator.Calculate(rtp, clock.CurrentTime()),
-              Eq(absl::nullopt));
+              Eq(std::nullopt));
 }
 
 }  // namespace webrtc
diff --git a/modules/video_coding/timing/jitter_estimator.cc b/modules/video_coding/timing/jitter_estimator.cc
index 6275778..b10048d 100644
--- a/modules/video_coding/timing/jitter_estimator.cc
+++ b/modules/video_coding/timing/jitter_estimator.cc
@@ -15,8 +15,8 @@
 
 #include <algorithm>
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/units/data_size.h"
 #include "api/units/frequency.h"
@@ -155,9 +155,9 @@
   var_frame_size_bytes2_ = 100;
   avg_frame_size_median_bytes_.Reset();
   max_frame_size_bytes_percentile_.Reset();
-  last_update_time_ = absl::nullopt;
-  prev_estimate_ = absl::nullopt;
-  prev_frame_size_ = absl::nullopt;
+  last_update_time_ = std::nullopt;
+  prev_estimate_ = std::nullopt;
+  prev_frame_size_ = std::nullopt;
   avg_noise_ms_ = 0.0;
   var_noise_ms2_ = 4.0;
   alpha_count_ = 1;
@@ -424,7 +424,7 @@
 // otherwise tries to calculate an estimate.
 TimeDelta JitterEstimator::GetJitterEstimate(
     double rtt_multiplier,
-    absl::optional<TimeDelta> rtt_mult_add_cap) {
+    std::optional<TimeDelta> rtt_mult_add_cap) {
   TimeDelta jitter = CalculateEstimate() + OPERATING_SYSTEM_JITTER;
   Timestamp now = clock_->CurrentTime();
 
diff --git a/modules/video_coding/timing/jitter_estimator.h b/modules/video_coding/timing/jitter_estimator.h
index 89dc649..44a95be 100644
--- a/modules/video_coding/timing/jitter_estimator.h
+++ b/modules/video_coding/timing/jitter_estimator.h
@@ -13,10 +13,10 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <queue>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/units/data_size.h"
 #include "api/units/frequency.h"
@@ -66,37 +66,37 @@
 
     // If set, the "max" frame size is calculated as this percentile over a
     // window of recent frame sizes.
-    absl::optional<double> max_frame_size_percentile = absl::nullopt;
+    std::optional<double> max_frame_size_percentile = std::nullopt;
 
     // The length of the percentile filters' window, in number of frames.
-    absl::optional<int> frame_size_window = absl::nullopt;
+    std::optional<int> frame_size_window = std::nullopt;
 
     // The incoming frame delay variation samples are clamped to be at most
     // this number of standard deviations away from zero.
     //
     // Increasing this value clamps fewer samples.
-    absl::optional<double> num_stddev_delay_clamp = absl::nullopt;
+    std::optional<double> num_stddev_delay_clamp = std::nullopt;
 
     // A (relative) frame delay variation sample is an outlier if its absolute
     // deviation from the Kalman filter model falls outside this number of
     // sample standard deviations.
     //
     // Increasing this value rejects fewer samples.
-    absl::optional<double> num_stddev_delay_outlier = absl::nullopt;
+    std::optional<double> num_stddev_delay_outlier = std::nullopt;
 
     // An (absolute) frame size sample is an outlier if its positive deviation
     // from the estimated average frame size falls outside this number of sample
     // standard deviations.
     //
     // Increasing this value rejects fewer samples.
-    absl::optional<double> num_stddev_size_outlier = absl::nullopt;
+    std::optional<double> num_stddev_size_outlier = std::nullopt;
 
     // A (relative) frame size variation sample is deemed "congested", and is
     // thus rejected, if its value is less than this factor times the estimated
     // max frame size.
     //
     // Decreasing this value rejects fewer samples.
-    absl::optional<double> congestion_rejection_factor = absl::nullopt;
+    std::optional<double> congestion_rejection_factor = std::nullopt;
 
     // If true, the noise estimate will be updated for congestion rejected
     // frames. This is currently enabled by default, but that may not be optimal
@@ -128,7 +128,7 @@
   //
   // Return value              : Jitter estimate.
   TimeDelta GetJitterEstimate(double rtt_multiplier,
-                              absl::optional<TimeDelta> rtt_mult_add_cap);
+                              std::optional<TimeDelta> rtt_mult_add_cap);
 
   // Updates the nack counter.
   void FrameNacked();
@@ -187,11 +187,11 @@
   double startup_frame_size_sum_bytes_;
   size_t startup_frame_size_count_;
 
-  absl::optional<Timestamp> last_update_time_;
+  std::optional<Timestamp> last_update_time_;
   // The previously returned jitter estimate
-  absl::optional<TimeDelta> prev_estimate_;
+  std::optional<TimeDelta> prev_estimate_;
   // Frame size of the previous frame
-  absl::optional<DataSize> prev_frame_size_;
+  std::optional<DataSize> prev_frame_size_;
   // Average of the random jitter. Unit is milliseconds.
   double avg_noise_ms_;
   // Variance of the time-deviation from the line. Unit is milliseconds^2.
diff --git a/modules/video_coding/timing/jitter_estimator_unittest.cc b/modules/video_coding/timing/jitter_estimator_unittest.cc
index 8e0c015..d8f89d2 100644
--- a/modules/video_coding/timing/jitter_estimator_unittest.cc
+++ b/modules/video_coding/timing/jitter_estimator_unittest.cc
@@ -12,11 +12,11 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/field_trials.h"
 #include "api/units/data_size.h"
@@ -79,7 +79,7 @@
 TEST_F(JitterEstimatorTest, SteadyStateConvergence) {
   ValueGenerator gen(10);
   Run(/*duration_s=*/60, /*framerate_fps=*/30, gen);
-  EXPECT_EQ(estimator_.GetJitterEstimate(0, absl::nullopt).ms(), 54);
+  EXPECT_EQ(estimator_.GetJitterEstimate(0, std::nullopt).ms(), 54);
 }
 
 TEST_F(JitterEstimatorTest,
@@ -88,12 +88,11 @@
 
   // Steady state.
   Run(/*duration_s=*/60, /*framerate_fps=*/30, gen);
-  TimeDelta steady_state_jitter =
-      estimator_.GetJitterEstimate(0, absl::nullopt);
+  TimeDelta steady_state_jitter = estimator_.GetJitterEstimate(0, std::nullopt);
 
   // A single outlier frame size...
   estimator_.UpdateEstimate(gen.Delay(), 10 * gen.FrameSize());
-  TimeDelta outlier_jitter = estimator_.GetJitterEstimate(0, absl::nullopt);
+  TimeDelta outlier_jitter = estimator_.GetJitterEstimate(0, std::nullopt);
 
   // ...changes the estimate.
   EXPECT_GT(outlier_jitter.ms(), 1.25 * steady_state_jitter.ms());
@@ -107,7 +106,7 @@
     estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
     fake_clock_.AdvanceTime(time_delta);
     if (i > 2)
-      EXPECT_EQ(estimator_.GetJitterEstimate(0, absl::nullopt),
+      EXPECT_EQ(estimator_.GetJitterEstimate(0, std::nullopt),
                 TimeDelta::Zero());
     gen.Advance();
   }
@@ -150,12 +149,11 @@
 
   // Steady state.
   Run(/*duration_s=*/60, /*framerate_fps=*/30, gen);
-  TimeDelta steady_state_jitter =
-      estimator_.GetJitterEstimate(0, absl::nullopt);
+  TimeDelta steady_state_jitter = estimator_.GetJitterEstimate(0, std::nullopt);
 
   // A single outlier frame size...
   estimator_.UpdateEstimate(gen.Delay(), 2 * gen.FrameSize());
-  TimeDelta outlier_jitter = estimator_.GetJitterEstimate(0, absl::nullopt);
+  TimeDelta outlier_jitter = estimator_.GetJitterEstimate(0, std::nullopt);
 
   // ...impacts the estimate.
   EXPECT_GT(outlier_jitter.ms(), steady_state_jitter.ms());
@@ -168,12 +166,11 @@
 
   // Steady state.
   Run(/*duration_s=*/10, /*framerate_fps=*/30, gen);
-  TimeDelta steady_state_jitter =
-      estimator_.GetJitterEstimate(0, absl::nullopt);
+  TimeDelta steady_state_jitter = estimator_.GetJitterEstimate(0, std::nullopt);
 
   // Congested frame...
   estimator_.UpdateEstimate(-10 * gen.Delay(), 0.1 * gen.FrameSize());
-  TimeDelta outlier_jitter = estimator_.GetJitterEstimate(0, absl::nullopt);
+  TimeDelta outlier_jitter = estimator_.GetJitterEstimate(0, std::nullopt);
 
   // ...impacts the estimate.
   EXPECT_GT(outlier_jitter.ms(), steady_state_jitter.ms());
@@ -225,12 +222,11 @@
 
   // Steady state.
   Run(/*duration_s=*/60, /*framerate_fps=*/30, gen);
-  TimeDelta steady_state_jitter =
-      estimator_.GetJitterEstimate(0, absl::nullopt);
+  TimeDelta steady_state_jitter = estimator_.GetJitterEstimate(0, std::nullopt);
 
   // A single outlier frame size...
   estimator_.UpdateEstimate(10 * gen.Delay(), gen.FrameSize());
-  TimeDelta outlier_jitter = estimator_.GetJitterEstimate(0, absl::nullopt);
+  TimeDelta outlier_jitter = estimator_.GetJitterEstimate(0, std::nullopt);
 
   // ...does not change the estimate.
   EXPECT_EQ(outlier_jitter.ms(), steady_state_jitter.ms());
@@ -244,19 +240,18 @@
 
   // Steady state.
   Run(/*duration_s=*/60, /*framerate_fps=*/30, gen);
-  TimeDelta steady_state_jitter =
-      estimator_.GetJitterEstimate(0, absl::nullopt);
+  TimeDelta steady_state_jitter = estimator_.GetJitterEstimate(0, std::nullopt);
 
   // Three outlier frames do not impact the jitter estimate.
   for (int i = 0; i < 3; ++i) {
     estimator_.UpdateEstimate(gen.Delay(), 2 * gen.FrameSize());
   }
-  TimeDelta outlier_jitter_3x = estimator_.GetJitterEstimate(0, absl::nullopt);
+  TimeDelta outlier_jitter_3x = estimator_.GetJitterEstimate(0, std::nullopt);
   EXPECT_EQ(outlier_jitter_3x.ms(), steady_state_jitter.ms());
 
   // Four outlier frames do impact the jitter estimate.
   estimator_.UpdateEstimate(gen.Delay(), 2 * gen.FrameSize());
-  TimeDelta outlier_jitter_4x = estimator_.GetJitterEstimate(0, absl::nullopt);
+  TimeDelta outlier_jitter_4x = estimator_.GetJitterEstimate(0, std::nullopt);
   EXPECT_GT(outlier_jitter_4x.ms(), outlier_jitter_3x.ms());
 }
 
@@ -268,12 +263,11 @@
 
   // Steady state.
   Run(/*duration_s=*/10, /*framerate_fps=*/30, gen);
-  TimeDelta steady_state_jitter =
-      estimator_.GetJitterEstimate(0, absl::nullopt);
+  TimeDelta steady_state_jitter = estimator_.GetJitterEstimate(0, std::nullopt);
 
   // Congested frame...
   estimator_.UpdateEstimate(-10 * gen.Delay(), 0.1 * gen.FrameSize());
-  TimeDelta outlier_jitter = estimator_.GetJitterEstimate(0, absl::nullopt);
+  TimeDelta outlier_jitter = estimator_.GetJitterEstimate(0, std::nullopt);
 
   // ...does not impact the estimate.
   EXPECT_EQ(outlier_jitter.ms(), steady_state_jitter.ms());
diff --git a/modules/video_coding/timing/timestamp_extrapolator.cc b/modules/video_coding/timing/timestamp_extrapolator.cc
index cc7eff9..e87a46a 100644
--- a/modules/video_coding/timing/timestamp_extrapolator.cc
+++ b/modules/video_coding/timing/timestamp_extrapolator.cc
@@ -11,8 +11,8 @@
 #include "modules/video_coding/timing/timestamp_extrapolator.h"
 
 #include <algorithm>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "rtc_base/numerics/sequence_number_unwrapper.h"
 
 namespace webrtc {
@@ -41,8 +41,8 @@
 void TimestampExtrapolator::Reset(Timestamp start) {
   start_ = start;
   prev_ = start_;
-  first_unwrapped_timestamp_ = absl::nullopt;
-  prev_unwrapped_timestamp_ = absl::nullopt;
+  first_unwrapped_timestamp_ = std::nullopt;
+  prev_unwrapped_timestamp_ = std::nullopt;
   w_[0] = 90.0;
   w_[1] = 0;
   p_[0][0] = 1;
@@ -123,12 +123,12 @@
   }
 }
 
-absl::optional<Timestamp> TimestampExtrapolator::ExtrapolateLocalTime(
+std::optional<Timestamp> TimestampExtrapolator::ExtrapolateLocalTime(
     uint32_t timestamp90khz) const {
   int64_t unwrapped_ts90khz = unwrapper_.PeekUnwrap(timestamp90khz);
 
   if (!first_unwrapped_timestamp_) {
-    return absl::nullopt;
+    return std::nullopt;
   } else if (packet_count_ < kStartUpFilterDelayInPackets) {
     constexpr double kRtpTicksPerMs = 90;
     TimeDelta diff = TimeDelta::Millis(
@@ -136,7 +136,7 @@
     if (prev_.us() + diff.us() < 0) {
       // Prevent the construction of a negative Timestamp.
       // This scenario can occur when the RTP timestamp wraps around.
-      return absl::nullopt;
+      return std::nullopt;
     }
     return prev_ + diff;
   } else if (w_[0] < 1e-3) {
@@ -148,7 +148,7 @@
     if (start_.us() + diff.us() < 0) {
       // Prevent the construction of a negative Timestamp.
       // This scenario can occur when the RTP timestamp wraps around.
-      return absl::nullopt;
+      return std::nullopt;
     }
     return start_ + diff;
   }
diff --git a/modules/video_coding/timing/timestamp_extrapolator.h b/modules/video_coding/timing/timestamp_extrapolator.h
index 6a97639..f3072fa 100644
--- a/modules/video_coding/timing/timestamp_extrapolator.h
+++ b/modules/video_coding/timing/timestamp_extrapolator.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/timestamp.h"
 #include "rtc_base/numerics/sequence_number_unwrapper.h"
 
@@ -24,7 +25,7 @@
  public:
   explicit TimestampExtrapolator(Timestamp start);
   void Update(Timestamp now, uint32_t ts90khz);
-  absl::optional<Timestamp> ExtrapolateLocalTime(uint32_t timestamp90khz) const;
+  std::optional<Timestamp> ExtrapolateLocalTime(uint32_t timestamp90khz) const;
   void Reset(Timestamp start);
 
  private:
@@ -35,9 +36,9 @@
   double p_[2][2];
   Timestamp start_;
   Timestamp prev_;
-  absl::optional<int64_t> first_unwrapped_timestamp_;
+  std::optional<int64_t> first_unwrapped_timestamp_;
   RtpTimestampUnwrapper unwrapper_;
-  absl::optional<int64_t> prev_unwrapped_timestamp_;
+  std::optional<int64_t> prev_unwrapped_timestamp_;
   uint32_t packet_count_;
   double detector_accumulator_pos_;
   double detector_accumulator_neg_;
diff --git a/modules/video_coding/timing/timestamp_extrapolator_unittest.cc b/modules/video_coding/timing/timestamp_extrapolator_unittest.cc
index fa1e23a..bf0c78a 100644
--- a/modules/video_coding/timing/timestamp_extrapolator_unittest.cc
+++ b/modules/video_coding/timing/timestamp_extrapolator_unittest.cc
@@ -13,8 +13,8 @@
 #include <stdint.h>
 
 #include <limits>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/units/frequency.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -40,7 +40,7 @@
   TimestampExtrapolator ts_extrapolator(clock.CurrentTime());
 
   // No packets so no timestamp.
-  EXPECT_THAT(ts_extrapolator.ExtrapolateLocalTime(90000), Eq(absl::nullopt));
+  EXPECT_THAT(ts_extrapolator.ExtrapolateLocalTime(90000), Eq(std::nullopt));
 
   uint32_t rtp = 90000;
   clock.AdvanceTime(k25FpsDelay);
@@ -143,7 +143,7 @@
   // Go backwards! Static cast to avoid undefined behaviour with -=.
   rtp -= static_cast<uint32_t>(kRtpHz * TimeDelta::Seconds(10));
   ts_extrapolator.Update(clock.CurrentTime(), rtp);
-  EXPECT_THAT(ts_extrapolator.ExtrapolateLocalTime(rtp), absl::nullopt);
+  EXPECT_THAT(ts_extrapolator.ExtrapolateLocalTime(rtp), std::nullopt);
 }
 
 TEST(TimestampExtrapolatorTest, Slow90KHzClock) {
diff --git a/modules/video_coding/timing/timing.cc b/modules/video_coding/timing/timing.cc
index 735f632..e791612 100644
--- a/modules/video_coding/timing/timing.cc
+++ b/modules/video_coding/timing/timing.cc
@@ -292,13 +292,13 @@
   timing_frame_info_.emplace(info);
 }
 
-absl::optional<TimingFrameInfo> VCMTiming::GetTimingFrameInfo() {
+std::optional<TimingFrameInfo> VCMTiming::GetTimingFrameInfo() {
   MutexLock lock(&mutex_);
   return timing_frame_info_;
 }
 
 void VCMTiming::SetMaxCompositionDelayInFrames(
-    absl::optional<int> max_composition_delay_in_frames) {
+    std::optional<int> max_composition_delay_in_frames) {
   MutexLock lock(&mutex_);
   max_composition_delay_in_frames_ = max_composition_delay_in_frames;
 }
diff --git a/modules/video_coding/timing/timing.h b/modules/video_coding/timing/timing.h
index 9e7fb87..2b2a05e 100644
--- a/modules/video_coding/timing/timing.h
+++ b/modules/video_coding/timing/timing.h
@@ -12,8 +12,8 @@
 #define MODULES_VIDEO_CODING_TIMING_TIMING_H_
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/units/time_delta.h"
 #include "api/video/video_frame.h"
@@ -120,10 +120,10 @@
   VideoDelayTimings GetTimings() const;
 
   void SetTimingFrameInfo(const TimingFrameInfo& info);
-  absl::optional<TimingFrameInfo> GetTimingFrameInfo();
+  std::optional<TimingFrameInfo> GetTimingFrameInfo();
 
   void SetMaxCompositionDelayInFrames(
-      absl::optional<int> max_composition_delay_in_frames);
+      std::optional<int> max_composition_delay_in_frames);
 
   VideoFrame::RenderParameters RenderParameters() const;
 
@@ -156,9 +156,9 @@
   TimeDelta jitter_delay_ RTC_GUARDED_BY(mutex_);
   TimeDelta current_delay_ RTC_GUARDED_BY(mutex_);
   uint32_t prev_frame_timestamp_ RTC_GUARDED_BY(mutex_);
-  absl::optional<TimingFrameInfo> timing_frame_info_ RTC_GUARDED_BY(mutex_);
+  std::optional<TimingFrameInfo> timing_frame_info_ RTC_GUARDED_BY(mutex_);
   size_t num_decoded_frames_ RTC_GUARDED_BY(mutex_);
-  absl::optional<int> max_composition_delay_in_frames_ RTC_GUARDED_BY(mutex_);
+  std::optional<int> max_composition_delay_in_frames_ RTC_GUARDED_BY(mutex_);
   // Set by the field trial WebRTC-ZeroPlayoutDelay. The parameter min_pacing
   // determines the minimum delay between frames scheduled for decoding that is
   // used when min playout delay=0 and max playout delay>=0.
diff --git a/modules/video_coding/utility/bandwidth_quality_scaler.cc b/modules/video_coding/utility/bandwidth_quality_scaler.cc
index f81ae3b..054a157 100644
--- a/modules/video_coding/utility/bandwidth_quality_scaler.cc
+++ b/modules/video_coding/utility/bandwidth_quality_scaler.cc
@@ -109,13 +109,13 @@
     return BandwidthQualityScaler::CheckBitrateResult::kInsufficientSamples;
   }
 
-  absl::optional<int64_t> current_bitrate_bps =
+  std::optional<int64_t> current_bitrate_bps =
       encoded_bitrate_.Rate(last_time_sent_in_ms_.value());
   if (!current_bitrate_bps.has_value()) {
     // We can't get a valid bitrate due to not enough data points.
     return BandwidthQualityScaler::CheckBitrateResult::kInsufficientSamples;
   }
-  absl::optional<VideoEncoder::ResolutionBitrateLimits> suitable_bitrate_limit =
+  std::optional<VideoEncoder::ResolutionBitrateLimits> suitable_bitrate_limit =
       EncoderInfoSettings::
           GetSinglecastBitrateLimitForResolutionWhenQpIsUntrusted(
               last_frame_size_pixels_, resolution_bitrate_limits_);
diff --git a/modules/video_coding/utility/bandwidth_quality_scaler.h b/modules/video_coding/utility/bandwidth_quality_scaler.h
index 89e171c..17eafb0 100644
--- a/modules/video_coding/utility/bandwidth_quality_scaler.h
+++ b/modules/video_coding/utility/bandwidth_quality_scaler.h
@@ -15,9 +15,9 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
 #include "api/sequence_checker.h"
 #include "api/video_codecs/video_encoder.h"
@@ -82,9 +82,9 @@
   BandwidthQualityScalerUsageHandlerInterface* const handler_
       RTC_GUARDED_BY(&task_checker_);
 
-  absl::optional<int64_t> last_time_sent_in_ms_ RTC_GUARDED_BY(&task_checker_);
+  std::optional<int64_t> last_time_sent_in_ms_ RTC_GUARDED_BY(&task_checker_);
   RateStatistics encoded_bitrate_ RTC_GUARDED_BY(&task_checker_);
-  absl::optional<int> last_frame_size_pixels_ RTC_GUARDED_BY(&task_checker_);
+  std::optional<int> last_frame_size_pixels_ RTC_GUARDED_BY(&task_checker_);
   rtc::WeakPtrFactory<BandwidthQualityScaler> weak_ptr_factory_;
 
   std::vector<VideoEncoder::ResolutionBitrateLimits> resolution_bitrate_limits_;
diff --git a/modules/video_coding/utility/bandwidth_quality_scaler_unittest.cc b/modules/video_coding/utility/bandwidth_quality_scaler_unittest.cc
index 67620e4..9c5fe31 100644
--- a/modules/video_coding/utility/bandwidth_quality_scaler_unittest.cc
+++ b/modules/video_coding/utility/bandwidth_quality_scaler_unittest.cc
@@ -125,7 +125,7 @@
     return -1;
   }
 
-  absl::optional<VideoEncoder::ResolutionBitrateLimits>
+  std::optional<VideoEncoder::ResolutionBitrateLimits>
   GetDefaultSuitableBitrateLimit(int frame_size_pixels) {
     return EncoderInfoSettings::
         GetSinglecastBitrateLimitForResolutionWhenQpIsUntrusted(
@@ -150,7 +150,7 @@
     TimeDelta delay = TimeDelta::Zero();
     int num_delayed_tasks = 0;
     for (const FrameConfig& config : frame_configs) {
-      absl::optional<VideoEncoder::ResolutionBitrateLimits> suitable_bitrate =
+      std::optional<VideoEncoder::ResolutionBitrateLimits> suitable_bitrate =
           GetDefaultSuitableBitrateLimit(config.actual_width *
                                          config.actual_height);
       EXPECT_TRUE(suitable_bitrate);
diff --git a/modules/video_coding/utility/decoded_frames_history.cc b/modules/video_coding/utility/decoded_frames_history.cc
index 1138aa8..6b48d89 100644
--- a/modules/video_coding/utility/decoded_frames_history.cc
+++ b/modules/video_coding/utility/decoded_frames_history.cc
@@ -74,11 +74,11 @@
   last_frame_id_.reset();
 }
 
-absl::optional<int64_t> DecodedFramesHistory::GetLastDecodedFrameId() const {
+std::optional<int64_t> DecodedFramesHistory::GetLastDecodedFrameId() const {
   return last_decoded_frame_;
 }
 
-absl::optional<uint32_t> DecodedFramesHistory::GetLastDecodedFrameTimestamp()
+std::optional<uint32_t> DecodedFramesHistory::GetLastDecodedFrameTimestamp()
     const {
   return last_decoded_frame_timestamp_;
 }
diff --git a/modules/video_coding/utility/decoded_frames_history.h b/modules/video_coding/utility/decoded_frames_history.h
index 9b8bf65..39337c0 100644
--- a/modules/video_coding/utility/decoded_frames_history.h
+++ b/modules/video_coding/utility/decoded_frames_history.h
@@ -14,9 +14,9 @@
 #include <stdint.h>
 
 #include <bitset>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/video/encoded_frame.h"
 
 namespace webrtc {
@@ -35,16 +35,16 @@
 
   void Clear();
 
-  absl::optional<int64_t> GetLastDecodedFrameId() const;
-  absl::optional<uint32_t> GetLastDecodedFrameTimestamp() const;
+  std::optional<int64_t> GetLastDecodedFrameId() const;
+  std::optional<uint32_t> GetLastDecodedFrameTimestamp() const;
 
  private:
   int FrameIdToIndex(int64_t frame_id) const;
 
   std::vector<bool> buffer_;
-  absl::optional<int64_t> last_frame_id_;
-  absl::optional<int64_t> last_decoded_frame_;
-  absl::optional<uint32_t> last_decoded_frame_timestamp_;
+  std::optional<int64_t> last_frame_id_;
+  std::optional<int64_t> last_decoded_frame_;
+  std::optional<uint32_t> last_decoded_frame_timestamp_;
 };
 
 }  // namespace video_coding
diff --git a/modules/video_coding/utility/decoded_frames_history_unittest.cc b/modules/video_coding/utility/decoded_frames_history_unittest.cc
index ac09a42..bfe5467 100644
--- a/modules/video_coding/utility/decoded_frames_history_unittest.cc
+++ b/modules/video_coding/utility/decoded_frames_history_unittest.cc
@@ -48,8 +48,8 @@
   history.InsertDecoded(1234, 0);
   history.Clear();
   EXPECT_EQ(history.WasDecoded(1234), false);
-  EXPECT_EQ(history.GetLastDecodedFrameId(), absl::nullopt);
-  EXPECT_EQ(history.GetLastDecodedFrameTimestamp(), absl::nullopt);
+  EXPECT_EQ(history.GetLastDecodedFrameId(), std::nullopt);
+  EXPECT_EQ(history.GetLastDecodedFrameTimestamp(), std::nullopt);
 }
 
 TEST(DecodedFramesHistory, HandlesBigJumpInPictureId) {
@@ -74,7 +74,7 @@
 
 TEST(DecodedFramesHistory, ReturnsLastDecodedFrameId) {
   DecodedFramesHistory history(kHistorySize);
-  EXPECT_EQ(history.GetLastDecodedFrameId(), absl::nullopt);
+  EXPECT_EQ(history.GetLastDecodedFrameId(), std::nullopt);
   history.InsertDecoded(1234, 0);
   EXPECT_EQ(history.GetLastDecodedFrameId(), 1234);
   history.InsertDecoded(1235, 0);
@@ -83,7 +83,7 @@
 
 TEST(DecodedFramesHistory, ReturnsLastDecodedFrameTimestamp) {
   DecodedFramesHistory history(kHistorySize);
-  EXPECT_EQ(history.GetLastDecodedFrameTimestamp(), absl::nullopt);
+  EXPECT_EQ(history.GetLastDecodedFrameTimestamp(), std::nullopt);
   history.InsertDecoded(1234, 12345);
   EXPECT_EQ(history.GetLastDecodedFrameTimestamp(), 12345u);
   history.InsertDecoded(1235, 12366);
diff --git a/modules/video_coding/utility/framerate_controller_deprecated.cc b/modules/video_coding/utility/framerate_controller_deprecated.cc
index 5978adc..0f31030 100644
--- a/modules/video_coding/utility/framerate_controller_deprecated.cc
+++ b/modules/video_coding/utility/framerate_controller_deprecated.cc
@@ -77,7 +77,7 @@
   last_timestamp_ms_ = timestamp_ms;
 }
 
-absl::optional<float> FramerateControllerDeprecated::Rate(
+std::optional<float> FramerateControllerDeprecated::Rate(
     uint32_t timestamp_ms) const {
   return framerate_estimator_.Rate(timestamp_ms);
 }
diff --git a/modules/video_coding/utility/framerate_controller_deprecated.h b/modules/video_coding/utility/framerate_controller_deprecated.h
index ca0cbea..6fcda3d 100644
--- a/modules/video_coding/utility/framerate_controller_deprecated.h
+++ b/modules/video_coding/utility/framerate_controller_deprecated.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "rtc_base/rate_statistics.h"
 
 namespace webrtc {
@@ -34,10 +35,10 @@
   void Reset();
 
  private:
-  absl::optional<float> Rate(uint32_t timestamp_ms) const;
+  std::optional<float> Rate(uint32_t timestamp_ms) const;
 
-  absl::optional<float> target_framerate_fps_;
-  absl::optional<uint32_t> last_timestamp_ms_;
+  std::optional<float> target_framerate_fps_;
+  std::optional<uint32_t> last_timestamp_ms_;
   uint32_t min_frame_interval_ms_;
   RateStatistics framerate_estimator_;
 };
diff --git a/modules/video_coding/utility/ivf_file_reader.cc b/modules/video_coding/utility/ivf_file_reader.cc
index 4c08ca6..958cc84 100644
--- a/modules/video_coding/utility/ivf_file_reader.cc
+++ b/modules/video_coding/utility/ivf_file_reader.cc
@@ -68,7 +68,7 @@
     return false;
   }
 
-  absl::optional<VideoCodecType> codec_type = ParseCodecType(ivf_header, 8);
+  std::optional<VideoCodecType> codec_type = ParseCodecType(ivf_header, 8);
   if (!codec_type) {
     return false;
   }
@@ -111,9 +111,9 @@
   return true;
 }
 
-absl::optional<EncodedImage> IvfFileReader::NextFrame() {
+std::optional<EncodedImage> IvfFileReader::NextFrame() {
   if (has_error_ || !HasMoreFrames()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   rtc::scoped_refptr<EncodedImageBuffer> payload = EncodedImageBuffer::Create();
@@ -139,7 +139,7 @@
       RTC_LOG(LS_ERROR) << "Frame #" << num_read_frames_
                         << ": failed to read frame payload";
       has_error_ = true;
-      return absl::nullopt;
+      return std::nullopt;
     }
     num_read_frames_++;
 
@@ -151,7 +151,7 @@
     if (!has_error_ && num_read_frames_ != num_frames_) {
       RTC_LOG(LS_ERROR) << "Unexpected EOF";
       has_error_ = true;
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
@@ -179,8 +179,8 @@
   return true;
 }
 
-absl::optional<VideoCodecType> IvfFileReader::ParseCodecType(uint8_t* buffer,
-                                                             size_t start_pos) {
+std::optional<VideoCodecType> IvfFileReader::ParseCodecType(uint8_t* buffer,
+                                                            size_t start_pos) {
   if (memcmp(&buffer[start_pos], kVp8Header, kCodecTypeBytesCount) == 0) {
     return VideoCodecType::kVideoCodecVP8;
   }
@@ -201,11 +201,10 @@
                     << std::string(
                            reinterpret_cast<char const*>(&buffer[start_pos]),
                            kCodecTypeBytesCount);
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<IvfFileReader::FrameHeader>
-IvfFileReader::ReadNextFrameHeader() {
+std::optional<IvfFileReader::FrameHeader> IvfFileReader::ReadNextFrameHeader() {
   uint8_t ivf_frame_header[kIvfFrameHeaderSize] = {0};
   size_t read = file_.Read(&ivf_frame_header, kIvfFrameHeaderSize);
   if (read != kIvfFrameHeaderSize) {
@@ -214,7 +213,7 @@
       RTC_LOG(LS_ERROR) << "Frame #" << num_read_frames_
                         << ": failed to read IVF frame header";
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
   FrameHeader header;
   header.frame_size = static_cast<size_t>(
@@ -226,14 +225,14 @@
     has_error_ = true;
     RTC_LOG(LS_ERROR) << "Frame #" << num_read_frames_
                       << ": invalid frame size";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (header.timestamp < 0) {
     has_error_ = true;
     RTC_LOG(LS_ERROR) << "Frame #" << num_read_frames_
                       << ": negative timestamp";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return header;
diff --git a/modules/video_coding/utility/ivf_file_reader.h b/modules/video_coding/utility/ivf_file_reader.h
index db4fc25..901751a 100644
--- a/modules/video_coding/utility/ivf_file_reader.h
+++ b/modules/video_coding/utility/ivf_file_reader.h
@@ -12,9 +12,9 @@
 #define MODULES_VIDEO_CODING_UTILITY_IVF_FILE_READER_H_
 
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/video/encoded_image.h"
 #include "api/video_codecs/video_codec.h"
 #include "rtc_base/system/file_wrapper.h"
@@ -39,9 +39,9 @@
   // Returns count of frames in this file.
   size_t GetFramesCount() const { return num_frames_; }
 
-  // Returns next frame or absl::nullopt if any error acquired. Always returns
-  // absl::nullopt after first error was spotted.
-  absl::optional<EncodedImage> NextFrame();
+  // Returns next frame or std::nullopt if any error acquired. Always returns
+  // std::nullopt after first error was spotted.
+  std::optional<EncodedImage> NextFrame();
   bool HasMoreFrames() const { return num_read_frames_ < num_frames_; }
   bool HasError() const { return has_error_; }
 
@@ -61,9 +61,9 @@
   // Parses codec type from specified position of the buffer. Codec type
   // contains kCodecTypeBytesCount bytes and caller has to ensure that buffer
   // won't overflow.
-  absl::optional<VideoCodecType> ParseCodecType(uint8_t* buffer,
-                                                size_t start_pos);
-  absl::optional<FrameHeader> ReadNextFrameHeader();
+  std::optional<VideoCodecType> ParseCodecType(uint8_t* buffer,
+                                               size_t start_pos);
+  std::optional<FrameHeader> ReadNextFrameHeader();
 
   VideoCodecType codec_type_;
   size_t num_frames_;
@@ -73,7 +73,7 @@
   uint32_t time_scale_;
   FileWrapper file_;
 
-  absl::optional<FrameHeader> next_frame_header_;
+  std::optional<FrameHeader> next_frame_header_;
   bool has_error_;
 };
 
diff --git a/modules/video_coding/utility/ivf_file_reader_unittest.cc b/modules/video_coding/utility/ivf_file_reader_unittest.cc
index 14bfdca..cf615c5 100644
--- a/modules/video_coding/utility/ivf_file_reader_unittest.cc
+++ b/modules/video_coding/utility/ivf_file_reader_unittest.cc
@@ -78,7 +78,7 @@
     ASSERT_TRUE(file_writer->Close());
   }
 
-  void ValidateFrame(absl::optional<EncodedImage> frame,
+  void ValidateFrame(std::optional<EncodedImage> frame,
                      int frame_index,
                      bool use_capture_tims_ms,
                      int spatial_layers_count) {
diff --git a/modules/video_coding/utility/qp_parser.cc b/modules/video_coding/utility/qp_parser.cc
index a531b54..fe9193d 100644
--- a/modules/video_coding/utility/qp_parser.cc
+++ b/modules/video_coding/utility/qp_parser.cc
@@ -15,13 +15,13 @@
 
 namespace webrtc {
 
-absl::optional<uint32_t> QpParser::Parse(VideoCodecType codec_type,
-                                         size_t spatial_idx,
-                                         const uint8_t* frame_data,
-                                         size_t frame_size) {
+std::optional<uint32_t> QpParser::Parse(VideoCodecType codec_type,
+                                        size_t spatial_idx,
+                                        const uint8_t* frame_data,
+                                        size_t frame_size) {
   if (frame_data == nullptr || frame_size == 0 ||
       spatial_idx >= kMaxSimulcastStreams) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (codec_type == kVideoCodecVP8) {
@@ -43,12 +43,11 @@
 #endif
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<uint32_t> QpParser::H264QpParser::Parse(
-    const uint8_t* frame_data,
-    size_t frame_size) {
+std::optional<uint32_t> QpParser::H264QpParser::Parse(const uint8_t* frame_data,
+                                                      size_t frame_size) {
   MutexLock lock(&mutex_);
   bitstream_parser_.ParseBitstream(
       rtc::ArrayView<const uint8_t>(frame_data, frame_size));
@@ -56,9 +55,8 @@
 }
 
 #ifdef RTC_ENABLE_H265
-absl::optional<uint32_t> QpParser::H265QpParser::Parse(
-    const uint8_t* frame_data,
-    size_t frame_size) {
+std::optional<uint32_t> QpParser::H265QpParser::Parse(const uint8_t* frame_data,
+                                                      size_t frame_size) {
   MutexLock lock(&mutex_);
   bitstream_parser_.ParseBitstream(
       rtc::ArrayView<const uint8_t>(frame_data, frame_size));
diff --git a/modules/video_coding/utility/qp_parser.h b/modules/video_coding/utility/qp_parser.h
index 210fe02..c397e0a 100644
--- a/modules/video_coding/utility/qp_parser.h
+++ b/modules/video_coding/utility/qp_parser.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_VIDEO_CODING_UTILITY_QP_PARSER_H_
 #define MODULES_VIDEO_CODING_UTILITY_QP_PARSER_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/video/video_codec_constants.h"
 #include "api/video/video_codec_type.h"
 #include "common_video/h264/h264_bitstream_parser.h"
@@ -23,17 +24,16 @@
 namespace webrtc {
 class QpParser {
  public:
-  absl::optional<uint32_t> Parse(VideoCodecType codec_type,
-                                 size_t spatial_idx,
-                                 const uint8_t* frame_data,
-                                 size_t frame_size);
+  std::optional<uint32_t> Parse(VideoCodecType codec_type,
+                                size_t spatial_idx,
+                                const uint8_t* frame_data,
+                                size_t frame_size);
 
  private:
   // A thread safe wrapper for H264 bitstream parser.
   class H264QpParser {
    public:
-    absl::optional<uint32_t> Parse(const uint8_t* frame_data,
-                                   size_t frame_size);
+    std::optional<uint32_t> Parse(const uint8_t* frame_data, size_t frame_size);
 
    private:
     Mutex mutex_;
@@ -46,8 +46,7 @@
   // A thread safe wrapper for H.265 bitstream parser.
   class H265QpParser {
    public:
-    absl::optional<uint32_t> Parse(const uint8_t* frame_data,
-                                   size_t frame_size);
+    std::optional<uint32_t> Parse(const uint8_t* frame_data, size_t frame_size);
 
    private:
     Mutex mutex_;
diff --git a/modules/video_coding/utility/qp_parser_unittest.cc b/modules/video_coding/utility/qp_parser_unittest.cc
index 1131288..c9ae7e7 100644
--- a/modules/video_coding/utility/qp_parser_unittest.cc
+++ b/modules/video_coding/utility/qp_parser_unittest.cc
@@ -55,21 +55,21 @@
 
 TEST(QpParserTest, ParseQpVp8) {
   QpParser parser;
-  absl::optional<uint32_t> qp = parser.Parse(
+  std::optional<uint32_t> qp = parser.Parse(
       kVideoCodecVP8, 0, kCodedFrameVp8Qp25, sizeof(kCodedFrameVp8Qp25));
   EXPECT_EQ(qp, 25u);
 }
 
 TEST(QpParserTest, ParseQpVp9) {
   QpParser parser;
-  absl::optional<uint32_t> qp = parser.Parse(
+  std::optional<uint32_t> qp = parser.Parse(
       kVideoCodecVP9, 0, kCodedFrameVp9Qp96, sizeof(kCodedFrameVp9Qp96));
   EXPECT_EQ(qp, 96u);
 }
 
 TEST(QpParserTest, ParseQpH264) {
   QpParser parser;
-  absl::optional<uint32_t> qp = parser.Parse(
+  std::optional<uint32_t> qp = parser.Parse(
       VideoCodecType::kVideoCodecH264, 0, kCodedFrameH264SpsPpsIdrQp38,
       sizeof(kCodedFrameH264SpsPpsIdrQp38));
   EXPECT_EQ(qp, 38u);
@@ -89,27 +89,27 @@
 
 TEST(QpParserTest, ParseQpUnsupportedCodecType) {
   QpParser parser;
-  absl::optional<uint32_t> qp = parser.Parse(
+  std::optional<uint32_t> qp = parser.Parse(
       kVideoCodecGeneric, 0, kCodedFrameVp8Qp25, sizeof(kCodedFrameVp8Qp25));
   EXPECT_FALSE(qp.has_value());
 }
 
 TEST(QpParserTest, ParseQpNullData) {
   QpParser parser;
-  absl::optional<uint32_t> qp = parser.Parse(kVideoCodecVP8, 0, nullptr, 100);
+  std::optional<uint32_t> qp = parser.Parse(kVideoCodecVP8, 0, nullptr, 100);
   EXPECT_FALSE(qp.has_value());
 }
 
 TEST(QpParserTest, ParseQpEmptyData) {
   QpParser parser;
-  absl::optional<uint32_t> qp =
+  std::optional<uint32_t> qp =
       parser.Parse(kVideoCodecVP8, 0, kCodedFrameVp8Qp25, 0);
   EXPECT_FALSE(qp.has_value());
 }
 
 TEST(QpParserTest, ParseQpSpatialIdxExceedsMax) {
   QpParser parser;
-  absl::optional<uint32_t> qp =
+  std::optional<uint32_t> qp =
       parser.Parse(kVideoCodecVP8, kMaxSimulcastStreams, kCodedFrameVp8Qp25,
                    sizeof(kCodedFrameVp8Qp25));
   EXPECT_FALSE(qp.has_value());
diff --git a/modules/video_coding/utility/quality_scaler.cc b/modules/video_coding/utility/quality_scaler.cc
index 4b71f90..6cb4dc9 100644
--- a/modules/video_coding/utility/quality_scaler.cc
+++ b/modules/video_coding/utility/quality_scaler.cc
@@ -42,10 +42,10 @@
         last_sample_ms_(0),
         smoother_(alpha) {}
 
-  absl::optional<int> GetAvg() const {
+  std::optional<int> GetAvg() const {
     float value = smoother_.filtered();
     if (value == rtc::ExpFilter::kValueUndefined) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return static_cast<int>(value);
   }
@@ -275,7 +275,7 @@
   }
 
   // Check if we should scale down due to high frame drop.
-  const absl::optional<int> drop_rate =
+  const std::optional<int> drop_rate =
       config_.use_all_drop_reasons
           ? framedrop_percent_all_.GetAverageRoundedDown()
           : framedrop_percent_media_opt_.GetAverageRoundedDown();
@@ -285,10 +285,10 @@
   }
 
   // Check if we should scale up or down based on QP.
-  const absl::optional<int> avg_qp_high =
+  const std::optional<int> avg_qp_high =
       qp_smoother_high_ ? qp_smoother_high_->GetAvg()
                         : average_qp_.GetAverageRoundedDown();
-  const absl::optional<int> avg_qp_low =
+  const std::optional<int> avg_qp_low =
       qp_smoother_low_ ? qp_smoother_low_->GetAvg()
                        : average_qp_.GetAverageRoundedDown();
   if (avg_qp_high && avg_qp_low) {
diff --git a/modules/video_coding/utility/quality_scaler.h b/modules/video_coding/utility/quality_scaler.h
index 7939c9e..eeb878a 100644
--- a/modules/video_coding/utility/quality_scaler.h
+++ b/modules/video_coding/utility/quality_scaler.h
@@ -15,8 +15,8 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/scoped_refptr.h"
 #include "api/sequence_checker.h"
@@ -101,7 +101,7 @@
 
   const size_t min_frames_needed_;
   const double initial_scale_factor_;
-  const absl::optional<double> scale_factor_;
+  const std::optional<double> scale_factor_;
 };
 
 // Reacts to QP being too high or too low. For best quality, when QP is high it
diff --git a/modules/video_coding/utility/simulcast_test_fixture_impl.cc b/modules/video_coding/utility/simulcast_test_fixture_impl.cc
index 7180993..7cba7e6 100644
--- a/modules/video_coding/utility/simulcast_test_fixture_impl.cc
+++ b/modules/video_coding/utility/simulcast_test_fixture_impl.cc
@@ -150,8 +150,8 @@
     return -1;
   }
   void Decoded(VideoFrame& decoded_image,
-               absl::optional<int32_t> decode_time_ms,
-               absl::optional<uint8_t> qp) override {
+               std::optional<int32_t> decode_time_ms,
+               std::optional<uint8_t> qp) override {
     Decoded(decoded_image);
   }
   int DecodedFrames() { return decoded_frames_; }
@@ -930,8 +930,8 @@
 
   EXPECT_CALL(decoder_callback, Decoded(_, _, _))
       .WillOnce(::testing::Invoke([](VideoFrame& decodedImage,
-                                     absl::optional<int32_t> decode_time_ms,
-                                     absl::optional<uint8_t> qp) {
+                                     std::optional<int32_t> decode_time_ms,
+                                     std::optional<uint8_t> qp) {
         EXPECT_EQ(decodedImage.width(), kDefaultWidth / 4);
         EXPECT_EQ(decodedImage.height(), kDefaultHeight / 4);
       }));
@@ -939,8 +939,8 @@
 
   EXPECT_CALL(decoder_callback, Decoded(_, _, _))
       .WillOnce(::testing::Invoke([](VideoFrame& decodedImage,
-                                     absl::optional<int32_t> decode_time_ms,
-                                     absl::optional<uint8_t> qp) {
+                                     std::optional<int32_t> decode_time_ms,
+                                     std::optional<uint8_t> qp) {
         EXPECT_EQ(decodedImage.width(), kDefaultWidth / 2);
         EXPECT_EQ(decodedImage.height(), kDefaultHeight / 2);
       }));
@@ -948,8 +948,8 @@
 
   EXPECT_CALL(decoder_callback, Decoded(_, _, _))
       .WillOnce(::testing::Invoke([](VideoFrame& decodedImage,
-                                     absl::optional<int32_t> decode_time_ms,
-                                     absl::optional<uint8_t> qp) {
+                                     std::optional<int32_t> decode_time_ms,
+                                     std::optional<uint8_t> qp) {
         EXPECT_EQ(decodedImage.width(), kDefaultWidth);
         EXPECT_EQ(decodedImage.height(), kDefaultHeight);
       }));
diff --git a/modules/video_coding/utility/vp9_uncompressed_header_parser.cc b/modules/video_coding/utility/vp9_uncompressed_header_parser.cc
index 9e8526a..b1e4b08 100644
--- a/modules/video_coding/utility/vp9_uncompressed_header_parser.cc
+++ b/modules/video_coding/utility/vp9_uncompressed_header_parser.cc
@@ -507,7 +507,7 @@
       (total_buffer_size_bits / 8) - (br.RemainingBitCount() / 8);
 }
 
-absl::optional<Vp9UncompressedHeader> ParseUncompressedVp9Header(
+std::optional<Vp9UncompressedHeader> ParseUncompressedVp9Header(
     rtc::ArrayView<const uint8_t> buf) {
   BitstreamReader reader(buf);
   Vp9UncompressedHeader frame_info;
@@ -515,7 +515,7 @@
   if (reader.Ok() && frame_info.frame_width > 0) {
     return frame_info;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 namespace vp9 {
diff --git a/modules/video_coding/utility/vp9_uncompressed_header_parser.h b/modules/video_coding/utility/vp9_uncompressed_header_parser.h
index 14b55c4..524d6cf 100644
--- a/modules/video_coding/utility/vp9_uncompressed_header_parser.h
+++ b/modules/video_coding/utility/vp9_uncompressed_header_parser.h
@@ -16,9 +16,9 @@
 
 #include <array>
 #include <bitset>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/video_coding/utility/vp9_constants.h"
 
@@ -90,14 +90,14 @@
 
 struct Vp9UncompressedHeader {
   int profile = 0;  // Profiles 0-3 are valid.
-  absl::optional<uint8_t> show_existing_frame;
+  std::optional<uint8_t> show_existing_frame;
   bool is_keyframe = false;
   bool show_frame = false;
   bool error_resilient = false;
   Vp9BitDept bit_detph = Vp9BitDept::k8Bit;
-  absl::optional<Vp9ColorSpace> color_space;
-  absl::optional<Vp9ColorRange> color_range;
-  absl::optional<Vp9YuvSubsampling> sub_sampling;
+  std::optional<Vp9ColorSpace> color_space;
+  std::optional<Vp9ColorRange> color_range;
+  std::optional<Vp9YuvSubsampling> sub_sampling;
   int frame_width = 0;
   int frame_height = 0;
   int render_width = 0;
@@ -105,10 +105,10 @@
   // Width/height of the tiles used (in units of 8x8 blocks).
   size_t tile_cols_log2 = 0;  // tile_cols = 1 << tile_cols_log2
   size_t tile_rows_log2 = 0;  // tile_rows = 1 << tile_rows_log2
-  absl::optional<size_t> render_size_offset_bits;
+  std::optional<size_t> render_size_offset_bits;
   // Number of bits from the start of the frame header to where the loop filter
   // parameters are located.
-  absl::optional<size_t> loop_filter_params_offset_bits;
+  std::optional<size_t> loop_filter_params_offset_bits;
   Vp9InterpolationFilter interpolation_filter =
       Vp9InterpolationFilter::kEightTap;
   bool allow_high_precision_mv = false;
@@ -117,10 +117,10 @@
   uint8_t frame_context_idx = 0;
 
   bool segmentation_enabled = false;
-  absl::optional<std::array<uint8_t, 7>> segmentation_tree_probs;
-  absl::optional<std::array<uint8_t, 3>> segmentation_pred_prob;
+  std::optional<std::array<uint8_t, 7>> segmentation_tree_probs;
+  std::optional<std::array<uint8_t, 3>> segmentation_pred_prob;
   bool segmentation_is_delta = false;
-  std::array<std::array<absl::optional<int>, kVp9SegLvlMax>, kVp9MaxSegments>
+  std::array<std::array<std::optional<int>, kVp9SegLvlMax>, kVp9MaxSegments>
       segmentation_features;
 
   // Which of the 8 reference buffers may be used as references for this frame.
@@ -132,7 +132,7 @@
   std::bitset<kVp9MaxRefFrames> reference_buffers_sign_bias = 0;
 
   // Indicates which reference buffer [0,7] to infer the frame size from.
-  absl::optional<int> infer_size_from_reference;
+  std::optional<int> infer_size_from_reference;
   // Which of the 8 reference buffers are updated by this frame.
   std::bitset<kVp9NumRefFrames> updated_buffers = 0;
 
@@ -150,7 +150,7 @@
 
 // Parses the uncompressed header and populates (most) values in a
 // UncompressedHeader struct. Returns nullopt on failure.
-absl::optional<Vp9UncompressedHeader> ParseUncompressedVp9Header(
+std::optional<Vp9UncompressedHeader> ParseUncompressedVp9Header(
     rtc::ArrayView<const uint8_t> buf);
 
 }  // namespace webrtc
diff --git a/modules/video_coding/utility/vp9_uncompressed_header_parser_unittest.cc b/modules/video_coding/utility/vp9_uncompressed_header_parser_unittest.cc
index 25ab656..685a7dd 100644
--- a/modules/video_coding/utility/vp9_uncompressed_header_parser_unittest.cc
+++ b/modules/video_coding/utility/vp9_uncompressed_header_parser_unittest.cc
@@ -31,7 +31,7 @@
       0x2e, 0x73, 0xb7, 0xee, 0x22, 0x06, 0x81, 0x82, 0xd4, 0xef, 0xc3, 0x58,
       0x1f, 0x12, 0xd2, 0x7b, 0x28, 0x1f, 0x80, 0xfc, 0x07, 0xe0, 0x00, 0x00};
 
-  absl::optional<Vp9UncompressedHeader> frame_info =
+  std::optional<Vp9UncompressedHeader> frame_info =
       ParseUncompressedVp9Header(kHeader);
   ASSERT_TRUE(frame_info.has_value());
 
@@ -74,7 +74,7 @@
   const uint8_t kHeader[] = {0x90, 0x49, 0x83, 0x42, 0x80, 0x2e,
                              0x30, 0x0,  0xb0, 0x0,  0x37, 0xff,
                              0x06, 0x80, 0x0,  0x0,  0x0,  0x0};
-  absl::optional<Vp9UncompressedHeader> frame_info =
+  std::optional<Vp9UncompressedHeader> frame_info =
       ParseUncompressedVp9Header(kHeader);
   ASSERT_TRUE(frame_info.has_value());
   EXPECT_THAT(frame_info->segmentation_pred_prob,
@@ -85,7 +85,7 @@
   const uint8_t kHeader[] = {0x90, 0x49, 0x83, 0x42, 0x80, 0x2e, 0x30, 0x00,
                              0xb0, 0x00, 0x37, 0xff, 0x06, 0x80, 0x01, 0x08,
                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-  absl::optional<Vp9UncompressedHeader> frame_info =
+  std::optional<Vp9UncompressedHeader> frame_info =
       ParseUncompressedVp9Header(kHeader);
   ASSERT_TRUE(frame_info.has_value());
   EXPECT_THAT(frame_info->segmentation_features[0][kVp9SegLvlSkip], Eq(1));
diff --git a/modules/video_coding/video_codec_initializer.cc b/modules/video_coding/video_codec_initializer.cc
index 2c6a255..fda0005 100644
--- a/modules/video_coding/video_codec_initializer.cc
+++ b/modules/video_coding/video_codec_initializer.cc
@@ -14,8 +14,8 @@
 #include <string.h>
 
 #include <algorithm>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/field_trials_view.h"
 #include "api/scoped_refptr.h"
@@ -81,8 +81,7 @@
 
   int max_framerate = 0;
 
-  absl::optional<ScalabilityMode> scalability_mode =
-      streams[0].scalability_mode;
+  std::optional<ScalabilityMode> scalability_mode = streams[0].scalability_mode;
   for (size_t i = 0; i < streams.size(); ++i) {
     SimulcastStream* sim_stream = &video_codec.simulcastStream[i];
     RTC_DCHECK_GT(streams[i].width, 0);
@@ -338,7 +337,7 @@
       break;
   }
 
-  const absl::optional<DataRate> experimental_min_bitrate =
+  const std::optional<DataRate> experimental_min_bitrate =
       GetExperimentalMinVideoBitrate(field_trials, video_codec.codecType);
   if (experimental_min_bitrate) {
     const int experimental_min_bitrate_kbps =
diff --git a/modules/video_coding/video_codec_initializer_unittest.cc b/modules/video_coding/video_codec_initializer_unittest.cc
index de88a64..d7c9171 100644
--- a/modules/video_coding/video_codec_initializer_unittest.cc
+++ b/modules/video_coding/video_codec_initializer_unittest.cc
@@ -14,8 +14,8 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
 #include "api/scoped_refptr.h"
@@ -61,8 +61,8 @@
 
  protected:
   void SetUpFor(VideoCodecType type,
-                absl::optional<int> num_simulcast_streams,
-                absl::optional<int> num_spatial_streams,
+                std::optional<int> num_simulcast_streams,
+                std::optional<int> num_spatial_streams,
                 int num_temporal_streams,
                 bool screenshare) {
     config_ = VideoEncoderConfig();
@@ -113,7 +113,7 @@
   VideoStream DefaultStream(
       int width = kDefaultWidth,
       int height = kDefaultHeight,
-      absl::optional<ScalabilityMode> scalability_mode = absl::nullopt) {
+      std::optional<ScalabilityMode> scalability_mode = std::nullopt) {
     VideoStream stream;
     stream.width = width;
     stream.height = height;
@@ -153,7 +153,7 @@
 };
 
 TEST_F(VideoCodecInitializerTest, SingleStreamVp8Screenshare) {
-  SetUpFor(VideoCodecType::kVideoCodecVP8, 1, absl::nullopt, 1, true);
+  SetUpFor(VideoCodecType::kVideoCodecVP8, 1, std::nullopt, 1, true);
   streams_.push_back(DefaultStream());
   InitializeCodec();
 
@@ -166,7 +166,7 @@
 }
 
 TEST_F(VideoCodecInitializerTest, SingleStreamVp8ScreenshareInactive) {
-  SetUpFor(VideoCodecType::kVideoCodecVP8, 1, absl::nullopt, 1, true);
+  SetUpFor(VideoCodecType::kVideoCodecVP8, 1, std::nullopt, 1, true);
   VideoStream inactive_stream = DefaultStream();
   inactive_stream.active = false;
   streams_.push_back(inactive_stream);
@@ -181,7 +181,7 @@
 }
 
 TEST_F(VideoCodecInitializerTest, TemporalLayeredVp8ScreenshareConference) {
-  SetUpFor(VideoCodecType::kVideoCodecVP8, 1, absl::nullopt, 2, true);
+  SetUpFor(VideoCodecType::kVideoCodecVP8, 1, std::nullopt, 2, true);
   streams_.push_back(DefaultScreenshareStream());
   InitializeCodec();
   bitrate_allocator_->SetLegacyConferenceMode(true);
@@ -198,7 +198,7 @@
 }
 
 TEST_F(VideoCodecInitializerTest, TemporalLayeredVp8Screenshare) {
-  SetUpFor(VideoCodecType::kVideoCodecVP8, 1, absl::nullopt, 2, true);
+  SetUpFor(VideoCodecType::kVideoCodecVP8, 1, std::nullopt, 2, true);
   streams_.push_back(DefaultScreenshareStream());
   InitializeCodec();
 
@@ -213,7 +213,7 @@
 }
 
 TEST_F(VideoCodecInitializerTest, SimulcastVp8Screenshare) {
-  SetUpFor(VideoCodecType::kVideoCodecVP8, 2, absl::nullopt, 1, true);
+  SetUpFor(VideoCodecType::kVideoCodecVP8, 2, std::nullopt, 1, true);
   streams_.push_back(DefaultScreenshareStream());
   VideoStream video_stream = DefaultStream();
   video_stream.max_framerate = kScreenshareDefaultFramerate;
@@ -237,7 +237,7 @@
 // Tests that when a video stream is inactive, then the bitrate allocation will
 // be 0 for that stream.
 TEST_F(VideoCodecInitializerTest, SimulcastVp8ScreenshareInactive) {
-  SetUpFor(VideoCodecType::kVideoCodecVP8, 2, absl::nullopt, 1, true);
+  SetUpFor(VideoCodecType::kVideoCodecVP8, 2, std::nullopt, 1, true);
   streams_.push_back(DefaultScreenshareStream());
   VideoStream inactive_video_stream = DefaultStream();
   inactive_video_stream.active = false;
@@ -262,7 +262,7 @@
 TEST_F(VideoCodecInitializerTest, HighFpsSimulcastVp8Screenshare) {
   // Two simulcast streams, the lower one using legacy settings (two temporal
   // streams, 5fps), the higher one using 3 temporal streams and 30fps.
-  SetUpFor(VideoCodecType::kVideoCodecVP8, 2, absl::nullopt, 3, true);
+  SetUpFor(VideoCodecType::kVideoCodecVP8, 2, std::nullopt, 3, true);
   streams_.push_back(DefaultScreenshareStream());
   VideoStream video_stream = DefaultStream();
   video_stream.num_temporal_layers = 3;
@@ -286,7 +286,7 @@
 }
 
 TEST_F(VideoCodecInitializerTest, Vp9SvcDefaultLayering) {
-  SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 3, 3, false);
+  SetUpFor(VideoCodecType::kVideoCodecVP9, std::nullopt, 3, 3, false);
   VideoStream stream = DefaultStream();
   stream.num_temporal_layers = 3;
   streams_.push_back(stream);
@@ -297,7 +297,7 @@
 }
 
 TEST_F(VideoCodecInitializerTest, Vp9SvcAdjustedLayering) {
-  SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 3, 3, false);
+  SetUpFor(VideoCodecType::kVideoCodecVP9, std::nullopt, 3, 3, false);
   VideoStream stream = DefaultStream();
   stream.num_temporal_layers = 3;
   // Set resolution which is only enough to produce 2 spatial layers.
@@ -312,7 +312,7 @@
 
 TEST_F(VideoCodecInitializerTest,
        Vp9SingleSpatialLayerMaxBitrateIsEqualToCodecMaxBitrate) {
-  SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 1, 3, false);
+  SetUpFor(VideoCodecType::kVideoCodecVP9, std::nullopt, 1, 3, false);
   VideoStream stream = DefaultStream();
   stream.num_temporal_layers = 3;
   streams_.push_back(stream);
@@ -340,7 +340,7 @@
 
 TEST_F(VideoCodecInitializerTest,
        Vp9SingleSpatialLayerTargetBitrateIsEqualToCodecMaxBitrate) {
-  SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 1, 1, true);
+  SetUpFor(VideoCodecType::kVideoCodecVP9, std::nullopt, 1, 1, true);
   VideoStream stream = DefaultStream();
   stream.num_temporal_layers = 1;
   streams_.push_back(stream);
@@ -355,7 +355,7 @@
   // Request 3 spatial layers for 320x180 input. Actual number of layers will be
   // reduced to 1 due to low input resolution but SVC bitrate limits should be
   // applied.
-  SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 3, 3, false);
+  SetUpFor(VideoCodecType::kVideoCodecVP9, std::nullopt, 3, 3, false);
   VideoStream stream = DefaultStream();
   stream.width = 320;
   stream.height = 180;
@@ -389,7 +389,7 @@
 }
 
 TEST_F(VideoCodecInitializerTest, Vp9DeactivateLayers) {
-  SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 3, 1, false);
+  SetUpFor(VideoCodecType::kVideoCodecVP9, std::nullopt, 3, 1, false);
   VideoStream stream = DefaultStream();
   streams_.push_back(stream);
 
@@ -463,7 +463,7 @@
 }
 
 TEST_F(VideoCodecInitializerTest, Vp9SvcResolutionAlignment) {
-  SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 3, 3, false);
+  SetUpFor(VideoCodecType::kVideoCodecVP9, std::nullopt, 3, 3, false);
   VideoStream stream = DefaultStream();
   stream.width = 1281;
   stream.height = 721;
diff --git a/modules/video_coding/video_coding_impl.cc b/modules/video_coding/video_coding_impl.cc
index 8799d9b..5c62c49 100644
--- a/modules/video_coding/video_coding_impl.cc
+++ b/modules/video_coding/video_coding_impl.cc
@@ -55,7 +55,7 @@
   // frame after RegisterReceiveCodec).
   if (current_decoder_ && current_decoder_->IsSameDecoder(it->second)) {
     // Release it if it was registered and in use.
-    current_decoder_ = absl::nullopt;
+    current_decoder_ = std::nullopt;
   }
   VideoDecoder* ret = it->second;
   decoders_.erase(it);
@@ -85,7 +85,7 @@
     const VideoDecoder::Settings& settings) {
   // If payload value already exists, erase old and insert new.
   if (payload_type == current_payload_type_) {
-    current_payload_type_ = absl::nullopt;
+    current_payload_type_ = std::nullopt;
   }
   decoder_settings_[payload_type] = settings;
 }
@@ -97,7 +97,7 @@
   }
   if (payload_type == current_payload_type_) {
     // This codec is currently in use.
-    current_payload_type_ = absl::nullopt;
+    current_payload_type_ = std::nullopt;
   }
   return true;
 }
@@ -113,12 +113,12 @@
   }
   // If decoder exists - delete.
   if (current_decoder_.has_value()) {
-    current_decoder_ = absl::nullopt;
-    current_payload_type_ = absl::nullopt;
+    current_decoder_ = std::nullopt;
+    current_payload_type_ = std::nullopt;
   }
 
   CreateAndInitDecoder(frame);
-  if (current_decoder_ == absl::nullopt) {
+  if (current_decoder_ == std::nullopt) {
     return nullptr;
   }
 
@@ -126,7 +126,7 @@
   callback->OnIncomingPayloadType(payload_type);
   if (current_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) <
       0) {
-    current_decoder_ = absl::nullopt;
+    current_decoder_ = std::nullopt;
     return nullptr;
   }
 
@@ -162,7 +162,7 @@
     decoder_item->second.set_max_render_resolution(frame_resolution);
   }
   if (!current_decoder_->Configure(decoder_item->second)) {
-    current_decoder_ = absl::nullopt;
+    current_decoder_ = std::nullopt;
     RTC_LOG(LS_ERROR) << "Failed to initialize decoder.";
   }
 }
diff --git a/modules/video_coding/video_coding_impl.h b/modules/video_coding/video_coding_impl.h
index b715d58..7f6bb10 100644
--- a/modules/video_coding/video_coding_impl.h
+++ b/modules/video_coding/video_coding_impl.h
@@ -13,10 +13,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/sequence_checker.h"
 #include "modules/video_coding/deprecated/frame_buffer.h"
@@ -89,8 +89,8 @@
 
   SequenceChecker decoder_sequence_checker_;
 
-  absl::optional<uint8_t> current_payload_type_;
-  absl::optional<VCMGenericDecoder> current_decoder_
+  std::optional<uint8_t> current_payload_type_;
+  std::optional<VCMGenericDecoder> current_decoder_
       RTC_GUARDED_BY(decoder_sequence_checker_);
   // Initialization paramaters for decoders keyed by payload type.
   std::map<uint8_t, VideoDecoder::Settings> decoder_settings_;
diff --git a/modules/video_coding/video_receiver2_unittest.cc b/modules/video_coding/video_receiver2_unittest.cc
index 88a19df..48ae8af 100644
--- a/modules/video_coding/video_receiver2_unittest.cc
+++ b/modules/video_coding/video_receiver2_unittest.cc
@@ -38,7 +38,7 @@
   MOCK_METHOD(int32_t,
               FrameToRender,
               (VideoFrame&,
-               absl::optional<uint8_t>,
+               std::optional<uint8_t>,
                TimeDelta,
                VideoContentType,
                VideoFrameType),
diff --git a/modules/video_coding/video_receiver_unittest.cc b/modules/video_coding/video_receiver_unittest.cc
index 2063653..7a04826 100644
--- a/modules/video_coding/video_receiver_unittest.cc
+++ b/modules/video_coding/video_receiver_unittest.cc
@@ -41,7 +41,7 @@
   MOCK_METHOD(int32_t,
               FrameToRender,
               (VideoFrame&,
-               absl::optional<uint8_t>,
+               std::optional<uint8_t>,
                TimeDelta,
                VideoContentType,
                VideoFrameType),
diff --git a/net/dcsctp/fuzzers/dcsctp_fuzzers.cc b/net/dcsctp/fuzzers/dcsctp_fuzzers.cc
index e8fcacf..b70c6c3 100644
--- a/net/dcsctp/fuzzers/dcsctp_fuzzers.cc
+++ b/net/dcsctp/fuzzers/dcsctp_fuzzers.cc
@@ -434,7 +434,7 @@
         SendOptions options;
         options.unordered = IsUnordered(flags & 0x01);
         options.max_retransmissions =
-            (flags & 0x02) != 0 ? absl::make_optional(0) : absl::nullopt;
+            (flags & 0x02) != 0 ? std::make_optional(0) : std::nullopt;
         options.lifecycle_id = LifecycleId(42);
         size_t payload_exponent = (flags >> 2) % 16;
         size_t payload_size = static_cast<size_t>(1) << payload_exponent;
@@ -446,7 +446,7 @@
       case 7: {
         // Expire an active timeout/timer.
         uint8_t timeout_idx = state.GetByte();
-        absl::optional<TimeoutID> timeout_id = cb.ExpireTimeout(timeout_idx);
+        std::optional<TimeoutID> timeout_id = cb.ExpireTimeout(timeout_idx);
         if (timeout_id.has_value()) {
           socket.HandleTimeout(*timeout_id);
         }
diff --git a/net/dcsctp/fuzzers/dcsctp_fuzzers.h b/net/dcsctp/fuzzers/dcsctp_fuzzers.h
index 49aa7f0..d76d0c0 100644
--- a/net/dcsctp/fuzzers/dcsctp_fuzzers.h
+++ b/net/dcsctp/fuzzers/dcsctp_fuzzers.h
@@ -44,13 +44,13 @@
     // expired.
     RTC_DCHECK(timeout_id_.has_value());
     RTC_DCHECK(active_timeouts_.erase(*timeout_id_) == 1);
-    timeout_id_ = absl::nullopt;
+    timeout_id_ = std::nullopt;
   }
 
   // A set of all active timeouts, managed by `FuzzerCallbacks`.
   std::set<TimeoutID>& active_timeouts_;
   // If present, the timout is active and will expire reported as `timeout_id`.
-  absl::optional<TimeoutID> timeout_id_;
+  std::optional<TimeoutID> timeout_id_;
 };
 
 class FuzzerCallbacks : public DcSctpSocketCallbacks {
@@ -91,7 +91,7 @@
   }
 
   // Given an index among the active timeouts, will expire that one.
-  absl::optional<TimeoutID> ExpireTimeout(size_t index) {
+  std::optional<TimeoutID> ExpireTimeout(size_t index) {
     if (index < active_timeouts_.size()) {
       auto it = active_timeouts_.begin();
       std::advance(it, index);
@@ -99,7 +99,7 @@
       active_timeouts_.erase(it);
       return timeout_id;
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
  private:
diff --git a/net/dcsctp/packet/BUILD.gn b/net/dcsctp/packet/BUILD.gn
index 942f039..dcdff08 100644
--- a/net/dcsctp/packet/BUILD.gn
+++ b/net/dcsctp/packet/BUILD.gn
@@ -29,7 +29,6 @@
     "../../../api:array_view",
     "../../../rtc_base:checks",
     "../../../rtc_base:logging",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "tlv_trait.cc",
@@ -73,7 +72,6 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "parameter/add_incoming_streams_request_parameter.cc",
@@ -118,7 +116,6 @@
     "../public:types",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "error_cause/cookie_received_while_shutting_down_cause.cc",
@@ -166,7 +163,6 @@
     "../packet:bounded_io",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "chunk/abort_chunk.cc",
@@ -235,7 +231,6 @@
     "../common:math",
     "../public:types",
     "//third_party/abseil-cpp/absl/memory",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "sctp_packet.cc",
@@ -265,7 +260,6 @@
       "../common:math",
       "../public:types",
       "../testing:testing_macros",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
     sources = [
       "bounded_byte_reader_test.cc",
diff --git a/net/dcsctp/packet/chunk/abort_chunk.cc b/net/dcsctp/packet/chunk/abort_chunk.cc
index 8348eb9..3d0e469 100644
--- a/net/dcsctp/packet/chunk/abort_chunk.cc
+++ b/net/dcsctp/packet/chunk/abort_chunk.cc
@@ -11,10 +11,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -36,16 +36,16 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int AbortChunk::kType;
 
-absl::optional<AbortChunk> AbortChunk::Parse(
+std::optional<AbortChunk> AbortChunk::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
-  absl::optional<Parameters> error_causes =
+  std::optional<Parameters> error_causes =
       Parameters::Parse(reader->variable_data());
   if (!error_causes.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   uint8_t flags = reader->Load8<1>();
   bool filled_in_verification_tag = (flags & (1 << kFlagsBitT)) == 0;
diff --git a/net/dcsctp/packet/chunk/abort_chunk.h b/net/dcsctp/packet/chunk/abort_chunk.h
index 1408a75..2072a9b 100644
--- a/net/dcsctp/packet/chunk/abort_chunk.h
+++ b/net/dcsctp/packet/chunk/abort_chunk.h
@@ -42,7 +42,7 @@
   AbortChunk(AbortChunk&& other) = default;
   AbortChunk& operator=(AbortChunk&& other) = default;
 
-  static absl::optional<AbortChunk> Parse(rtc::ArrayView<const uint8_t> data);
+  static std::optional<AbortChunk> Parse(rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
   std::string ToString() const override;
diff --git a/net/dcsctp/packet/chunk/chunk.cc b/net/dcsctp/packet/chunk/chunk.cc
index 832ab82..b2059b4 100644
--- a/net/dcsctp/packet/chunk/chunk.cc
+++ b/net/dcsctp/packet/chunk/chunk.cc
@@ -11,9 +11,9 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/math.h"
 #include "net/dcsctp/packet/chunk/abort_chunk.h"
@@ -42,7 +42,7 @@
                    rtc::ArrayView<const uint8_t> data,
                    rtc::StringBuilder& sb) {
   if (chunk_type == Chunk::kType) {
-    absl::optional<Chunk> c = Chunk::Parse(data);
+    std::optional<Chunk> c = Chunk::Parse(data);
     if (c.has_value()) {
       sb << c->ToString();
     } else {
diff --git a/net/dcsctp/packet/chunk/chunk.h b/net/dcsctp/packet/chunk/chunk.h
index 687aa1d..6fea10a 100644
--- a/net/dcsctp/packet/chunk/chunk.h
+++ b/net/dcsctp/packet/chunk/chunk.h
@@ -16,13 +16,13 @@
 #include <cstdint>
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/data.h"
 #include "net/dcsctp/packet/error_cause/error_cause.h"
diff --git a/net/dcsctp/packet/chunk/cookie_ack_chunk.cc b/net/dcsctp/packet/chunk/cookie_ack_chunk.cc
index 4839969..a6d28df 100644
--- a/net/dcsctp/packet/chunk/cookie_ack_chunk.cc
+++ b/net/dcsctp/packet/chunk/cookie_ack_chunk.cc
@@ -11,9 +11,9 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 
 namespace dcsctp {
@@ -27,10 +27,10 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int CookieAckChunk::kType;
 
-absl::optional<CookieAckChunk> CookieAckChunk::Parse(
+std::optional<CookieAckChunk> CookieAckChunk::Parse(
     rtc::ArrayView<const uint8_t> data) {
   if (!ParseTLV(data).has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return CookieAckChunk();
 }
diff --git a/net/dcsctp/packet/chunk/cookie_ack_chunk.h b/net/dcsctp/packet/chunk/cookie_ack_chunk.h
index f7d4a33..631e7a2 100644
--- a/net/dcsctp/packet/chunk/cookie_ack_chunk.h
+++ b/net/dcsctp/packet/chunk/cookie_ack_chunk.h
@@ -35,7 +35,7 @@
 
   CookieAckChunk() {}
 
-  static absl::optional<CookieAckChunk> Parse(
+  static std::optional<CookieAckChunk> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/chunk/cookie_echo_chunk.cc b/net/dcsctp/packet/chunk/cookie_echo_chunk.cc
index a01d0b1..30e2b89 100644
--- a/net/dcsctp/packet/chunk/cookie_echo_chunk.cc
+++ b/net/dcsctp/packet/chunk/cookie_echo_chunk.cc
@@ -11,10 +11,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -34,11 +34,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int CookieEchoChunk::kType;
 
-absl::optional<CookieEchoChunk> CookieEchoChunk::Parse(
+std::optional<CookieEchoChunk> CookieEchoChunk::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return CookieEchoChunk(reader->variable_data());
 }
diff --git a/net/dcsctp/packet/chunk/cookie_echo_chunk.h b/net/dcsctp/packet/chunk/cookie_echo_chunk.h
index 8cb8052..12f819b 100644
--- a/net/dcsctp/packet/chunk/cookie_echo_chunk.h
+++ b/net/dcsctp/packet/chunk/cookie_echo_chunk.h
@@ -36,7 +36,7 @@
   explicit CookieEchoChunk(rtc::ArrayView<const uint8_t> cookie)
       : cookie_(cookie.begin(), cookie.end()) {}
 
-  static absl::optional<CookieEchoChunk> Parse(
+  static std::optional<CookieEchoChunk> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/chunk/data_chunk.cc b/net/dcsctp/packet/chunk/data_chunk.cc
index cf866b7..92a988d 100644
--- a/net/dcsctp/packet/chunk/data_chunk.cc
+++ b/net/dcsctp/packet/chunk/data_chunk.cc
@@ -11,11 +11,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -43,10 +43,10 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int DataChunk::kType;
 
-absl::optional<DataChunk> DataChunk::Parse(rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+std::optional<DataChunk> DataChunk::Parse(rtc::ArrayView<const uint8_t> data) {
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   uint8_t flags = reader->Load8<1>();
diff --git a/net/dcsctp/packet/chunk/data_chunk.h b/net/dcsctp/packet/chunk/data_chunk.h
index 12bb05f..515fd9e 100644
--- a/net/dcsctp/packet/chunk/data_chunk.h
+++ b/net/dcsctp/packet/chunk/data_chunk.h
@@ -59,7 +59,7 @@
   DataChunk(TSN tsn, Data&& data, bool immediate_ack)
       : AnyDataChunk(tsn, std::move(data), immediate_ack) {}
 
-  static absl::optional<DataChunk> Parse(rtc::ArrayView<const uint8_t> data);
+  static std::optional<DataChunk> Parse(rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
   std::string ToString() const override;
diff --git a/net/dcsctp/packet/chunk/error_chunk.cc b/net/dcsctp/packet/chunk/error_chunk.cc
index baac0c5..8311ad2 100644
--- a/net/dcsctp/packet/chunk/error_chunk.cc
+++ b/net/dcsctp/packet/chunk/error_chunk.cc
@@ -11,10 +11,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -36,16 +36,16 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int ErrorChunk::kType;
 
-absl::optional<ErrorChunk> ErrorChunk::Parse(
+std::optional<ErrorChunk> ErrorChunk::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
-  absl::optional<Parameters> error_causes =
+  std::optional<Parameters> error_causes =
       Parameters::Parse(reader->variable_data());
   if (!error_causes.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ErrorChunk(*std::move(error_causes));
 }
diff --git a/net/dcsctp/packet/chunk/error_chunk.h b/net/dcsctp/packet/chunk/error_chunk.h
index 96122cf..f982547 100644
--- a/net/dcsctp/packet/chunk/error_chunk.h
+++ b/net/dcsctp/packet/chunk/error_chunk.h
@@ -41,7 +41,7 @@
   ErrorChunk(ErrorChunk&& other) = default;
   ErrorChunk& operator=(ErrorChunk&& other) = default;
 
-  static absl::optional<ErrorChunk> Parse(rtc::ArrayView<const uint8_t> data);
+  static std::optional<ErrorChunk> Parse(rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
   std::string ToString() const override;
diff --git a/net/dcsctp/packet/chunk/forward_tsn_chunk.cc b/net/dcsctp/packet/chunk/forward_tsn_chunk.cc
index e432114..1f22e35 100644
--- a/net/dcsctp/packet/chunk/forward_tsn_chunk.cc
+++ b/net/dcsctp/packet/chunk/forward_tsn_chunk.cc
@@ -12,11 +12,11 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -44,11 +44,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int ForwardTsnChunk::kType;
 
-absl::optional<ForwardTsnChunk> ForwardTsnChunk::Parse(
+std::optional<ForwardTsnChunk> ForwardTsnChunk::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   TSN new_cumulative_tsn(reader->Load32<4>());
 
diff --git a/net/dcsctp/packet/chunk/forward_tsn_chunk.h b/net/dcsctp/packet/chunk/forward_tsn_chunk.h
index b9ef666..caa3379 100644
--- a/net/dcsctp/packet/chunk/forward_tsn_chunk.h
+++ b/net/dcsctp/packet/chunk/forward_tsn_chunk.h
@@ -40,7 +40,7 @@
                   std::vector<SkippedStream> skipped_streams)
       : AnyForwardTsnChunk(new_cumulative_tsn, std::move(skipped_streams)) {}
 
-  static absl::optional<ForwardTsnChunk> Parse(
+  static std::optional<ForwardTsnChunk> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/chunk/heartbeat_ack_chunk.cc b/net/dcsctp/packet/chunk/heartbeat_ack_chunk.cc
index 3cbcd09..ba98436 100644
--- a/net/dcsctp/packet/chunk/heartbeat_ack_chunk.cc
+++ b/net/dcsctp/packet/chunk/heartbeat_ack_chunk.cc
@@ -11,10 +11,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -36,17 +36,17 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int HeartbeatAckChunk::kType;
 
-absl::optional<HeartbeatAckChunk> HeartbeatAckChunk::Parse(
+std::optional<HeartbeatAckChunk> HeartbeatAckChunk::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  absl::optional<Parameters> parameters =
+  std::optional<Parameters> parameters =
       Parameters::Parse(reader->variable_data());
   if (!parameters.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return HeartbeatAckChunk(*std::move(parameters));
 }
diff --git a/net/dcsctp/packet/chunk/heartbeat_ack_chunk.h b/net/dcsctp/packet/chunk/heartbeat_ack_chunk.h
index a6479f7..8a63205 100644
--- a/net/dcsctp/packet/chunk/heartbeat_ack_chunk.h
+++ b/net/dcsctp/packet/chunk/heartbeat_ack_chunk.h
@@ -43,7 +43,7 @@
   HeartbeatAckChunk(HeartbeatAckChunk&& other) = default;
   HeartbeatAckChunk& operator=(HeartbeatAckChunk&& other) = default;
 
-  static absl::optional<HeartbeatAckChunk> Parse(
+  static std::optional<HeartbeatAckChunk> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
@@ -51,7 +51,7 @@
 
   const Parameters& parameters() const { return parameters_; }
 
-  absl::optional<HeartbeatInfoParameter> info() const {
+  std::optional<HeartbeatInfoParameter> info() const {
     return parameters_.get<HeartbeatInfoParameter>();
   }
 
diff --git a/net/dcsctp/packet/chunk/heartbeat_request_chunk.cc b/net/dcsctp/packet/chunk/heartbeat_request_chunk.cc
index d759d6b..a94a7e3 100644
--- a/net/dcsctp/packet/chunk/heartbeat_request_chunk.cc
+++ b/net/dcsctp/packet/chunk/heartbeat_request_chunk.cc
@@ -11,10 +11,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -36,17 +36,17 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int HeartbeatRequestChunk::kType;
 
-absl::optional<HeartbeatRequestChunk> HeartbeatRequestChunk::Parse(
+std::optional<HeartbeatRequestChunk> HeartbeatRequestChunk::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  absl::optional<Parameters> parameters =
+  std::optional<Parameters> parameters =
       Parameters::Parse(reader->variable_data());
   if (!parameters.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return HeartbeatRequestChunk(*std::move(parameters));
 }
diff --git a/net/dcsctp/packet/chunk/heartbeat_request_chunk.h b/net/dcsctp/packet/chunk/heartbeat_request_chunk.h
index fe2ce19..218bd6a 100644
--- a/net/dcsctp/packet/chunk/heartbeat_request_chunk.h
+++ b/net/dcsctp/packet/chunk/heartbeat_request_chunk.h
@@ -42,7 +42,7 @@
   HeartbeatRequestChunk(HeartbeatRequestChunk&& other) = default;
   HeartbeatRequestChunk& operator=(HeartbeatRequestChunk&& other) = default;
 
-  static absl::optional<HeartbeatRequestChunk> Parse(
+  static std::optional<HeartbeatRequestChunk> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
@@ -50,7 +50,7 @@
 
   const Parameters& parameters() const { return parameters_; }
   Parameters extract_parameters() && { return std::move(parameters_); }
-  absl::optional<HeartbeatInfoParameter> info() const {
+  std::optional<HeartbeatInfoParameter> info() const {
     return parameters_.get<HeartbeatInfoParameter>();
   }
 
diff --git a/net/dcsctp/packet/chunk/idata_chunk.cc b/net/dcsctp/packet/chunk/idata_chunk.cc
index e9a777d..b6d3b3e 100644
--- a/net/dcsctp/packet/chunk/idata_chunk.cc
+++ b/net/dcsctp/packet/chunk/idata_chunk.cc
@@ -11,11 +11,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -45,11 +45,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int IDataChunk::kType;
 
-absl::optional<IDataChunk> IDataChunk::Parse(
+std::optional<IDataChunk> IDataChunk::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   uint8_t flags = reader->Load8<1>();
   TSN tsn(reader->Load32<4>());
diff --git a/net/dcsctp/packet/chunk/idata_chunk.h b/net/dcsctp/packet/chunk/idata_chunk.h
index 36b7e7e..c8b6709 100644
--- a/net/dcsctp/packet/chunk/idata_chunk.h
+++ b/net/dcsctp/packet/chunk/idata_chunk.h
@@ -59,7 +59,7 @@
   explicit IDataChunk(TSN tsn, Data&& data, bool immediate_ack)
       : AnyDataChunk(tsn, std::move(data), immediate_ack) {}
 
-  static absl::optional<IDataChunk> Parse(rtc::ArrayView<const uint8_t> data);
+  static std::optional<IDataChunk> Parse(rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
   std::string ToString() const override;
diff --git a/net/dcsctp/packet/chunk/iforward_tsn_chunk.cc b/net/dcsctp/packet/chunk/iforward_tsn_chunk.cc
index 2b8e9c9..cc83b3b 100644
--- a/net/dcsctp/packet/chunk/iforward_tsn_chunk.cc
+++ b/net/dcsctp/packet/chunk/iforward_tsn_chunk.cc
@@ -12,11 +12,11 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -48,11 +48,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int IForwardTsnChunk::kType;
 
-absl::optional<IForwardTsnChunk> IForwardTsnChunk::Parse(
+std::optional<IForwardTsnChunk> IForwardTsnChunk::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   TSN new_cumulative_tsn(reader->Load32<4>());
diff --git a/net/dcsctp/packet/chunk/iforward_tsn_chunk.h b/net/dcsctp/packet/chunk/iforward_tsn_chunk.h
index 54d23f7..fe05221 100644
--- a/net/dcsctp/packet/chunk/iforward_tsn_chunk.h
+++ b/net/dcsctp/packet/chunk/iforward_tsn_chunk.h
@@ -40,7 +40,7 @@
                    std::vector<SkippedStream> skipped_streams)
       : AnyForwardTsnChunk(new_cumulative_tsn, std::move(skipped_streams)) {}
 
-  static absl::optional<IForwardTsnChunk> Parse(
+  static std::optional<IForwardTsnChunk> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/chunk/init_ack_chunk.cc b/net/dcsctp/packet/chunk/init_ack_chunk.cc
index c7ef9da..7977faa 100644
--- a/net/dcsctp/packet/chunk/init_ack_chunk.cc
+++ b/net/dcsctp/packet/chunk/init_ack_chunk.cc
@@ -11,11 +11,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -46,11 +46,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int InitAckChunk::kType;
 
-absl::optional<InitAckChunk> InitAckChunk::Parse(
+std::optional<InitAckChunk> InitAckChunk::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   VerificationTag initiate_tag(reader->Load32<4>());
@@ -58,10 +58,10 @@
   uint16_t nbr_outbound_streams = reader->Load16<12>();
   uint16_t nbr_inbound_streams = reader->Load16<14>();
   TSN initial_tsn(reader->Load32<16>());
-  absl::optional<Parameters> parameters =
+  std::optional<Parameters> parameters =
       Parameters::Parse(reader->variable_data());
   if (!parameters.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return InitAckChunk(initiate_tag, a_rwnd, nbr_outbound_streams,
                       nbr_inbound_streams, initial_tsn, *std::move(parameters));
diff --git a/net/dcsctp/packet/chunk/init_ack_chunk.h b/net/dcsctp/packet/chunk/init_ack_chunk.h
index 6fcf64b..5058cf1 100644
--- a/net/dcsctp/packet/chunk/init_ack_chunk.h
+++ b/net/dcsctp/packet/chunk/init_ack_chunk.h
@@ -51,7 +51,7 @@
   InitAckChunk(InitAckChunk&& other) = default;
   InitAckChunk& operator=(InitAckChunk&& other) = default;
 
-  static absl::optional<InitAckChunk> Parse(rtc::ArrayView<const uint8_t> data);
+  static std::optional<InitAckChunk> Parse(rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
   std::string ToString() const override;
diff --git a/net/dcsctp/packet/chunk/init_chunk.cc b/net/dcsctp/packet/chunk/init_chunk.cc
index 8030107..dbb3382 100644
--- a/net/dcsctp/packet/chunk/init_chunk.cc
+++ b/net/dcsctp/packet/chunk/init_chunk.cc
@@ -11,11 +11,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -46,10 +46,10 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int InitChunk::kType;
 
-absl::optional<InitChunk> InitChunk::Parse(rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+std::optional<InitChunk> InitChunk::Parse(rtc::ArrayView<const uint8_t> data) {
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   VerificationTag initiate_tag(reader->Load32<4>());
@@ -58,10 +58,10 @@
   uint16_t nbr_inbound_streams = reader->Load16<14>();
   TSN initial_tsn(reader->Load32<16>());
 
-  absl::optional<Parameters> parameters =
+  std::optional<Parameters> parameters =
       Parameters::Parse(reader->variable_data());
   if (!parameters.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return InitChunk(initiate_tag, a_rwnd, nbr_outbound_streams,
                    nbr_inbound_streams, initial_tsn, *std::move(parameters));
diff --git a/net/dcsctp/packet/chunk/init_chunk.h b/net/dcsctp/packet/chunk/init_chunk.h
index 38f9994..4f3a9b9 100644
--- a/net/dcsctp/packet/chunk/init_chunk.h
+++ b/net/dcsctp/packet/chunk/init_chunk.h
@@ -51,7 +51,7 @@
   InitChunk(InitChunk&& other) = default;
   InitChunk& operator=(InitChunk&& other) = default;
 
-  static absl::optional<InitChunk> Parse(rtc::ArrayView<const uint8_t> data);
+  static std::optional<InitChunk> Parse(rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
   std::string ToString() const override;
diff --git a/net/dcsctp/packet/chunk/reconfig_chunk.cc b/net/dcsctp/packet/chunk/reconfig_chunk.cc
index f39f3b6..91fa7d7 100644
--- a/net/dcsctp/packet/chunk/reconfig_chunk.cc
+++ b/net/dcsctp/packet/chunk/reconfig_chunk.cc
@@ -11,10 +11,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -40,17 +40,17 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int ReConfigChunk::kType;
 
-absl::optional<ReConfigChunk> ReConfigChunk::Parse(
+std::optional<ReConfigChunk> ReConfigChunk::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  absl::optional<Parameters> parameters =
+  std::optional<Parameters> parameters =
       Parameters::Parse(reader->variable_data());
   if (!parameters.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return ReConfigChunk(*std::move(parameters));
diff --git a/net/dcsctp/packet/chunk/reconfig_chunk.h b/net/dcsctp/packet/chunk/reconfig_chunk.h
index 9d2539a..90df22e 100644
--- a/net/dcsctp/packet/chunk/reconfig_chunk.h
+++ b/net/dcsctp/packet/chunk/reconfig_chunk.h
@@ -38,8 +38,7 @@
   explicit ReConfigChunk(Parameters parameters)
       : parameters_(std::move(parameters)) {}
 
-  static absl::optional<ReConfigChunk> Parse(
-      rtc::ArrayView<const uint8_t> data);
+  static std::optional<ReConfigChunk> Parse(rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
   std::string ToString() const override;
diff --git a/net/dcsctp/packet/chunk/sack_chunk.cc b/net/dcsctp/packet/chunk/sack_chunk.cc
index 179f7ea..75fd9b5 100644
--- a/net/dcsctp/packet/chunk/sack_chunk.cc
+++ b/net/dcsctp/packet/chunk/sack_chunk.cc
@@ -12,11 +12,11 @@
 #include <stddef.h>
 
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -58,10 +58,10 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int SackChunk::kType;
 
-absl::optional<SackChunk> SackChunk::Parse(rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+std::optional<SackChunk> SackChunk::Parse(rtc::ArrayView<const uint8_t> data) {
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   TSN tsn_ack(reader->Load32<4>());
@@ -72,7 +72,7 @@
   if (reader->variable_data_size() != nbr_of_gap_blocks * kGapAckBlockSize +
                                           nbr_of_dup_tsns * kDupTsnBlockSize) {
     RTC_DLOG(LS_WARNING) << "Invalid number of gap blocks or duplicate TSNs";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<GapAckBlock> gap_ack_blocks;
diff --git a/net/dcsctp/packet/chunk/sack_chunk.h b/net/dcsctp/packet/chunk/sack_chunk.h
index e6758fa..ae4807d 100644
--- a/net/dcsctp/packet/chunk/sack_chunk.h
+++ b/net/dcsctp/packet/chunk/sack_chunk.h
@@ -54,7 +54,7 @@
         a_rwnd_(a_rwnd),
         gap_ack_blocks_(std::move(gap_ack_blocks)),
         duplicate_tsns_(std::move(duplicate_tsns)) {}
-  static absl::optional<SackChunk> Parse(rtc::ArrayView<const uint8_t> data);
+  static std::optional<SackChunk> Parse(rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
   std::string ToString() const override;
diff --git a/net/dcsctp/packet/chunk/shutdown_ack_chunk.cc b/net/dcsctp/packet/chunk/shutdown_ack_chunk.cc
index d42acee..3df4e5a 100644
--- a/net/dcsctp/packet/chunk/shutdown_ack_chunk.cc
+++ b/net/dcsctp/packet/chunk/shutdown_ack_chunk.cc
@@ -11,9 +11,9 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 
 namespace dcsctp {
@@ -27,10 +27,10 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int ShutdownAckChunk::kType;
 
-absl::optional<ShutdownAckChunk> ShutdownAckChunk::Parse(
+std::optional<ShutdownAckChunk> ShutdownAckChunk::Parse(
     rtc::ArrayView<const uint8_t> data) {
   if (!ParseTLV(data).has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ShutdownAckChunk();
 }
diff --git a/net/dcsctp/packet/chunk/shutdown_ack_chunk.h b/net/dcsctp/packet/chunk/shutdown_ack_chunk.h
index 29c1a98..4ed9755 100644
--- a/net/dcsctp/packet/chunk/shutdown_ack_chunk.h
+++ b/net/dcsctp/packet/chunk/shutdown_ack_chunk.h
@@ -35,7 +35,7 @@
 
   ShutdownAckChunk() {}
 
-  static absl::optional<ShutdownAckChunk> Parse(
+  static std::optional<ShutdownAckChunk> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/chunk/shutdown_chunk.cc b/net/dcsctp/packet/chunk/shutdown_chunk.cc
index 59f806f..c7f64dd 100644
--- a/net/dcsctp/packet/chunk/shutdown_chunk.cc
+++ b/net/dcsctp/packet/chunk/shutdown_chunk.cc
@@ -11,10 +11,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -33,11 +33,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int ShutdownChunk::kType;
 
-absl::optional<ShutdownChunk> ShutdownChunk::Parse(
+std::optional<ShutdownChunk> ShutdownChunk::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   TSN cumulative_tsn_ack(reader->Load32<4>());
diff --git a/net/dcsctp/packet/chunk/shutdown_chunk.h b/net/dcsctp/packet/chunk/shutdown_chunk.h
index 8148cca..f1090ae 100644
--- a/net/dcsctp/packet/chunk/shutdown_chunk.h
+++ b/net/dcsctp/packet/chunk/shutdown_chunk.h
@@ -36,8 +36,7 @@
   explicit ShutdownChunk(TSN cumulative_tsn_ack)
       : cumulative_tsn_ack_(cumulative_tsn_ack) {}
 
-  static absl::optional<ShutdownChunk> Parse(
-      rtc::ArrayView<const uint8_t> data);
+  static std::optional<ShutdownChunk> Parse(rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
   std::string ToString() const override;
diff --git a/net/dcsctp/packet/chunk/shutdown_complete_chunk.cc b/net/dcsctp/packet/chunk/shutdown_complete_chunk.cc
index 3f54857..abb04b6 100644
--- a/net/dcsctp/packet/chunk/shutdown_complete_chunk.cc
+++ b/net/dcsctp/packet/chunk/shutdown_complete_chunk.cc
@@ -11,10 +11,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -31,11 +31,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int ShutdownCompleteChunk::kType;
 
-absl::optional<ShutdownCompleteChunk> ShutdownCompleteChunk::Parse(
+std::optional<ShutdownCompleteChunk> ShutdownCompleteChunk::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   uint8_t flags = reader->Load8<1>();
   bool tag_reflected = (flags & (1 << kFlagsBitT)) != 0;
diff --git a/net/dcsctp/packet/chunk/shutdown_complete_chunk.h b/net/dcsctp/packet/chunk/shutdown_complete_chunk.h
index 46d28e8..6ab7eb9 100644
--- a/net/dcsctp/packet/chunk/shutdown_complete_chunk.h
+++ b/net/dcsctp/packet/chunk/shutdown_complete_chunk.h
@@ -37,7 +37,7 @@
   explicit ShutdownCompleteChunk(bool tag_reflected)
       : tag_reflected_(tag_reflected) {}
 
-  static absl::optional<ShutdownCompleteChunk> Parse(
+  static std::optional<ShutdownCompleteChunk> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/error_cause/cookie_received_while_shutting_down_cause.cc b/net/dcsctp/packet/error_cause/cookie_received_while_shutting_down_cause.cc
index ef67c2a..f675be2 100644
--- a/net/dcsctp/packet/error_cause/cookie_received_while_shutting_down_cause.cc
+++ b/net/dcsctp/packet/error_cause/cookie_received_while_shutting_down_cause.cc
@@ -11,9 +11,9 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 
 namespace dcsctp {
@@ -25,11 +25,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int CookieReceivedWhileShuttingDownCause::kType;
 
-absl::optional<CookieReceivedWhileShuttingDownCause>
+std::optional<CookieReceivedWhileShuttingDownCause>
 CookieReceivedWhileShuttingDownCause::Parse(
     rtc::ArrayView<const uint8_t> data) {
   if (!ParseTLV(data).has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return CookieReceivedWhileShuttingDownCause();
 }
diff --git a/net/dcsctp/packet/error_cause/cookie_received_while_shutting_down_cause.h b/net/dcsctp/packet/error_cause/cookie_received_while_shutting_down_cause.h
index 362f181..c2a44c9 100644
--- a/net/dcsctp/packet/error_cause/cookie_received_while_shutting_down_cause.h
+++ b/net/dcsctp/packet/error_cause/cookie_received_while_shutting_down_cause.h
@@ -38,7 +38,7 @@
 
   CookieReceivedWhileShuttingDownCause() {}
 
-  static absl::optional<CookieReceivedWhileShuttingDownCause> Parse(
+  static std::optional<CookieReceivedWhileShuttingDownCause> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/error_cause/error_cause.cc b/net/dcsctp/packet/error_cause/error_cause.cc
index dcd0747..c28675a 100644
--- a/net/dcsctp/packet/error_cause/error_cause.cc
+++ b/net/dcsctp/packet/error_cause/error_cause.cc
@@ -13,11 +13,11 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/math.h"
 #include "net/dcsctp/packet/error_cause/cookie_received_while_shutting_down_cause.h"
@@ -40,7 +40,7 @@
 template <class ErrorCause>
 bool ParseAndPrint(ParameterDescriptor descriptor, rtc::StringBuilder& sb) {
   if (descriptor.type == ErrorCause::kType) {
-    absl::optional<ErrorCause> p = ErrorCause::Parse(descriptor.data);
+    std::optional<ErrorCause> p = ErrorCause::Parse(descriptor.data);
     if (p.has_value()) {
       sb << p->ToString();
     } else {
diff --git a/net/dcsctp/packet/error_cause/error_cause.h b/net/dcsctp/packet/error_cause/error_cause.h
index fa2bf81..a4247cb 100644
--- a/net/dcsctp/packet/error_cause/error_cause.h
+++ b/net/dcsctp/packet/error_cause/error_cause.h
@@ -15,6 +15,7 @@
 #include <cstdint>
 #include <iosfwd>
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <utility>
@@ -22,7 +23,6 @@
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/parameter/parameter.h"
 #include "net/dcsctp/packet/tlv_trait.h"
diff --git a/net/dcsctp/packet/error_cause/invalid_mandatory_parameter_cause.cc b/net/dcsctp/packet/error_cause/invalid_mandatory_parameter_cause.cc
index 0187544..9bcba4f 100644
--- a/net/dcsctp/packet/error_cause/invalid_mandatory_parameter_cause.cc
+++ b/net/dcsctp/packet/error_cause/invalid_mandatory_parameter_cause.cc
@@ -11,9 +11,9 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 
 namespace dcsctp {
@@ -25,10 +25,10 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int InvalidMandatoryParameterCause::kType;
 
-absl::optional<InvalidMandatoryParameterCause>
+std::optional<InvalidMandatoryParameterCause>
 InvalidMandatoryParameterCause::Parse(rtc::ArrayView<const uint8_t> data) {
   if (!ParseTLV(data).has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return InvalidMandatoryParameterCause();
 }
diff --git a/net/dcsctp/packet/error_cause/invalid_mandatory_parameter_cause.h b/net/dcsctp/packet/error_cause/invalid_mandatory_parameter_cause.h
index e192b5a..9f4f0c9 100644
--- a/net/dcsctp/packet/error_cause/invalid_mandatory_parameter_cause.h
+++ b/net/dcsctp/packet/error_cause/invalid_mandatory_parameter_cause.h
@@ -37,7 +37,7 @@
 
   InvalidMandatoryParameterCause() {}
 
-  static absl::optional<InvalidMandatoryParameterCause> Parse(
+  static std::optional<InvalidMandatoryParameterCause> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/error_cause/invalid_stream_identifier_cause.cc b/net/dcsctp/packet/error_cause/invalid_stream_identifier_cause.cc
index b2ddd6f..9979b0c 100644
--- a/net/dcsctp/packet/error_cause/invalid_stream_identifier_cause.cc
+++ b/net/dcsctp/packet/error_cause/invalid_stream_identifier_cause.cc
@@ -11,11 +11,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -33,11 +33,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int InvalidStreamIdentifierCause::kType;
 
-absl::optional<InvalidStreamIdentifierCause>
-InvalidStreamIdentifierCause::Parse(rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+std::optional<InvalidStreamIdentifierCause> InvalidStreamIdentifierCause::Parse(
+    rtc::ArrayView<const uint8_t> data) {
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   StreamID stream_id(reader->Load16<4>());
diff --git a/net/dcsctp/packet/error_cause/invalid_stream_identifier_cause.h b/net/dcsctp/packet/error_cause/invalid_stream_identifier_cause.h
index b7dfe17..2f4b33e 100644
--- a/net/dcsctp/packet/error_cause/invalid_stream_identifier_cause.h
+++ b/net/dcsctp/packet/error_cause/invalid_stream_identifier_cause.h
@@ -39,7 +39,7 @@
   explicit InvalidStreamIdentifierCause(StreamID stream_id)
       : stream_id_(stream_id) {}
 
-  static absl::optional<InvalidStreamIdentifierCause> Parse(
+  static std::optional<InvalidStreamIdentifierCause> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/error_cause/missing_mandatory_parameter_cause.cc b/net/dcsctp/packet/error_cause/missing_mandatory_parameter_cause.cc
index 679439d..e4a8b2d 100644
--- a/net/dcsctp/packet/error_cause/missing_mandatory_parameter_cause.cc
+++ b/net/dcsctp/packet/error_cause/missing_mandatory_parameter_cause.cc
@@ -12,11 +12,11 @@
 #include <stddef.h>
 
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -40,17 +40,17 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int MissingMandatoryParameterCause::kType;
 
-absl::optional<MissingMandatoryParameterCause>
+std::optional<MissingMandatoryParameterCause>
 MissingMandatoryParameterCause::Parse(rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   uint32_t count = reader->Load32<4>();
   if (reader->variable_data_size() / kMissingParameterSize != count) {
     RTC_DLOG(LS_WARNING) << "Invalid number of missing parameters";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<uint16_t> missing_parameter_types;
diff --git a/net/dcsctp/packet/error_cause/missing_mandatory_parameter_cause.h b/net/dcsctp/packet/error_cause/missing_mandatory_parameter_cause.h
index 4435424..03903a9 100644
--- a/net/dcsctp/packet/error_cause/missing_mandatory_parameter_cause.h
+++ b/net/dcsctp/packet/error_cause/missing_mandatory_parameter_cause.h
@@ -40,7 +40,7 @@
       : missing_parameter_types_(missing_parameter_types.begin(),
                                  missing_parameter_types.end()) {}
 
-  static absl::optional<MissingMandatoryParameterCause> Parse(
+  static std::optional<MissingMandatoryParameterCause> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/error_cause/no_user_data_cause.cc b/net/dcsctp/packet/error_cause/no_user_data_cause.cc
index 2853915..3555e30 100644
--- a/net/dcsctp/packet/error_cause/no_user_data_cause.cc
+++ b/net/dcsctp/packet/error_cause/no_user_data_cause.cc
@@ -11,11 +11,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -34,11 +34,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int NoUserDataCause::kType;
 
-absl::optional<NoUserDataCause> NoUserDataCause::Parse(
+std::optional<NoUserDataCause> NoUserDataCause::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   TSN tsn(reader->Load32<4>());
   return NoUserDataCause(tsn);
diff --git a/net/dcsctp/packet/error_cause/no_user_data_cause.h b/net/dcsctp/packet/error_cause/no_user_data_cause.h
index 1087dcc..e4092b0 100644
--- a/net/dcsctp/packet/error_cause/no_user_data_cause.h
+++ b/net/dcsctp/packet/error_cause/no_user_data_cause.h
@@ -36,7 +36,7 @@
 
   explicit NoUserDataCause(TSN tsn) : tsn_(tsn) {}
 
-  static absl::optional<NoUserDataCause> Parse(
+  static std::optional<NoUserDataCause> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/error_cause/out_of_resource_error_cause.cc b/net/dcsctp/packet/error_cause/out_of_resource_error_cause.cc
index e5c7c0e..552f48e 100644
--- a/net/dcsctp/packet/error_cause/out_of_resource_error_cause.cc
+++ b/net/dcsctp/packet/error_cause/out_of_resource_error_cause.cc
@@ -11,9 +11,9 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 
 namespace dcsctp {
@@ -25,10 +25,10 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int OutOfResourceErrorCause::kType;
 
-absl::optional<OutOfResourceErrorCause> OutOfResourceErrorCause::Parse(
+std::optional<OutOfResourceErrorCause> OutOfResourceErrorCause::Parse(
     rtc::ArrayView<const uint8_t> data) {
   if (!ParseTLV(data).has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return OutOfResourceErrorCause();
 }
diff --git a/net/dcsctp/packet/error_cause/out_of_resource_error_cause.h b/net/dcsctp/packet/error_cause/out_of_resource_error_cause.h
index fc798ca..4234d73 100644
--- a/net/dcsctp/packet/error_cause/out_of_resource_error_cause.h
+++ b/net/dcsctp/packet/error_cause/out_of_resource_error_cause.h
@@ -36,7 +36,7 @@
 
   OutOfResourceErrorCause() {}
 
-  static absl::optional<OutOfResourceErrorCause> Parse(
+  static std::optional<OutOfResourceErrorCause> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/error_cause/protocol_violation_cause.cc b/net/dcsctp/packet/error_cause/protocol_violation_cause.cc
index 1b8d423..00360cc 100644
--- a/net/dcsctp/packet/error_cause/protocol_violation_cause.cc
+++ b/net/dcsctp/packet/error_cause/protocol_violation_cause.cc
@@ -11,11 +11,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -36,11 +36,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int ProtocolViolationCause::kType;
 
-absl::optional<ProtocolViolationCause> ProtocolViolationCause::Parse(
+std::optional<ProtocolViolationCause> ProtocolViolationCause::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ProtocolViolationCause(
       std::string(reinterpret_cast<const char*>(reader->variable_data().data()),
diff --git a/net/dcsctp/packet/error_cause/protocol_violation_cause.h b/net/dcsctp/packet/error_cause/protocol_violation_cause.h
index 3081e1f..e4e3db8 100644
--- a/net/dcsctp/packet/error_cause/protocol_violation_cause.h
+++ b/net/dcsctp/packet/error_cause/protocol_violation_cause.h
@@ -37,7 +37,7 @@
   explicit ProtocolViolationCause(absl::string_view additional_information)
       : additional_information_(additional_information) {}
 
-  static absl::optional<ProtocolViolationCause> Parse(
+  static std::optional<ProtocolViolationCause> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/error_cause/restart_of_an_association_with_new_address_cause.cc b/net/dcsctp/packet/error_cause/restart_of_an_association_with_new_address_cause.cc
index abe5de6..5cb2d64 100644
--- a/net/dcsctp/packet/error_cause/restart_of_an_association_with_new_address_cause.cc
+++ b/net/dcsctp/packet/error_cause/restart_of_an_association_with_new_address_cause.cc
@@ -11,10 +11,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -34,12 +34,12 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int RestartOfAnAssociationWithNewAddressesCause::kType;
 
-absl::optional<RestartOfAnAssociationWithNewAddressesCause>
+std::optional<RestartOfAnAssociationWithNewAddressesCause>
 RestartOfAnAssociationWithNewAddressesCause::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return RestartOfAnAssociationWithNewAddressesCause(reader->variable_data());
 }
diff --git a/net/dcsctp/packet/error_cause/restart_of_an_association_with_new_address_cause.h b/net/dcsctp/packet/error_cause/restart_of_an_association_with_new_address_cause.h
index a1cccdc..20d7163 100644
--- a/net/dcsctp/packet/error_cause/restart_of_an_association_with_new_address_cause.h
+++ b/net/dcsctp/packet/error_cause/restart_of_an_association_with_new_address_cause.h
@@ -41,7 +41,7 @@
       rtc::ArrayView<const uint8_t> new_address_tlvs)
       : new_address_tlvs_(new_address_tlvs.begin(), new_address_tlvs.end()) {}
 
-  static absl::optional<RestartOfAnAssociationWithNewAddressesCause> Parse(
+  static std::optional<RestartOfAnAssociationWithNewAddressesCause> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/error_cause/stale_cookie_error_cause.cc b/net/dcsctp/packet/error_cause/stale_cookie_error_cause.cc
index d77d848..3bd6f2c 100644
--- a/net/dcsctp/packet/error_cause/stale_cookie_error_cause.cc
+++ b/net/dcsctp/packet/error_cause/stale_cookie_error_cause.cc
@@ -11,11 +11,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -33,11 +33,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int StaleCookieErrorCause::kType;
 
-absl::optional<StaleCookieErrorCause> StaleCookieErrorCause::Parse(
+std::optional<StaleCookieErrorCause> StaleCookieErrorCause::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   uint32_t staleness_us = reader->Load32<4>();
   return StaleCookieErrorCause(staleness_us);
diff --git a/net/dcsctp/packet/error_cause/stale_cookie_error_cause.h b/net/dcsctp/packet/error_cause/stale_cookie_error_cause.h
index d8b7b5b..c40fcbc 100644
--- a/net/dcsctp/packet/error_cause/stale_cookie_error_cause.h
+++ b/net/dcsctp/packet/error_cause/stale_cookie_error_cause.h
@@ -37,7 +37,7 @@
   explicit StaleCookieErrorCause(uint32_t staleness_us)
       : staleness_us_(staleness_us) {}
 
-  static absl::optional<StaleCookieErrorCause> Parse(
+  static std::optional<StaleCookieErrorCause> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.cc b/net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.cc
index 04b960d..2b64dfd 100644
--- a/net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.cc
+++ b/net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.cc
@@ -10,11 +10,11 @@
 #include "net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.h"
 
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -33,11 +33,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int UnrecognizedChunkTypeCause::kType;
 
-absl::optional<UnrecognizedChunkTypeCause> UnrecognizedChunkTypeCause::Parse(
+std::optional<UnrecognizedChunkTypeCause> UnrecognizedChunkTypeCause::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   std::vector<uint8_t> unrecognized_chunk(reader->variable_data().begin(),
                                           reader->variable_data().end());
diff --git a/net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.h b/net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.h
index 26d3d3b..d16e21b 100644
--- a/net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.h
+++ b/net/dcsctp/packet/error_cause/unrecognized_chunk_type_cause.h
@@ -40,7 +40,7 @@
   explicit UnrecognizedChunkTypeCause(std::vector<uint8_t> unrecognized_chunk)
       : unrecognized_chunk_(std::move(unrecognized_chunk)) {}
 
-  static absl::optional<UnrecognizedChunkTypeCause> Parse(
+  static std::optional<UnrecognizedChunkTypeCause> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/error_cause/unrecognized_parameter_cause.cc b/net/dcsctp/packet/error_cause/unrecognized_parameter_cause.cc
index 80001a9..448dcb7 100644
--- a/net/dcsctp/packet/error_cause/unrecognized_parameter_cause.cc
+++ b/net/dcsctp/packet/error_cause/unrecognized_parameter_cause.cc
@@ -11,10 +11,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -32,11 +32,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int UnrecognizedParametersCause::kType;
 
-absl::optional<UnrecognizedParametersCause> UnrecognizedParametersCause::Parse(
+std::optional<UnrecognizedParametersCause> UnrecognizedParametersCause::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return UnrecognizedParametersCause(reader->variable_data());
 }
diff --git a/net/dcsctp/packet/error_cause/unrecognized_parameter_cause.h b/net/dcsctp/packet/error_cause/unrecognized_parameter_cause.h
index ebec5ed..166cc97 100644
--- a/net/dcsctp/packet/error_cause/unrecognized_parameter_cause.h
+++ b/net/dcsctp/packet/error_cause/unrecognized_parameter_cause.h
@@ -41,7 +41,7 @@
       : unrecognized_parameters_(unrecognized_parameters.begin(),
                                  unrecognized_parameters.end()) {}
 
-  static absl::optional<UnrecognizedParametersCause> Parse(
+  static std::optional<UnrecognizedParametersCause> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/error_cause/unresolvable_address_cause.cc b/net/dcsctp/packet/error_cause/unresolvable_address_cause.cc
index 8108d31..5e0f273 100644
--- a/net/dcsctp/packet/error_cause/unresolvable_address_cause.cc
+++ b/net/dcsctp/packet/error_cause/unresolvable_address_cause.cc
@@ -11,10 +11,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -32,11 +32,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int UnresolvableAddressCause::kType;
 
-absl::optional<UnresolvableAddressCause> UnresolvableAddressCause::Parse(
+std::optional<UnresolvableAddressCause> UnresolvableAddressCause::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return UnresolvableAddressCause(reader->variable_data());
 }
diff --git a/net/dcsctp/packet/error_cause/unresolvable_address_cause.h b/net/dcsctp/packet/error_cause/unresolvable_address_cause.h
index c63b377..cea735c 100644
--- a/net/dcsctp/packet/error_cause/unresolvable_address_cause.h
+++ b/net/dcsctp/packet/error_cause/unresolvable_address_cause.h
@@ -41,7 +41,7 @@
       : unresolvable_address_(unresolvable_address.begin(),
                               unresolvable_address.end()) {}
 
-  static absl::optional<UnresolvableAddressCause> Parse(
+  static std::optional<UnresolvableAddressCause> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/error_cause/user_initiated_abort_cause.cc b/net/dcsctp/packet/error_cause/user_initiated_abort_cause.cc
index da99aac..e4cd267 100644
--- a/net/dcsctp/packet/error_cause/user_initiated_abort_cause.cc
+++ b/net/dcsctp/packet/error_cause/user_initiated_abort_cause.cc
@@ -11,11 +11,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -36,11 +36,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int UserInitiatedAbortCause::kType;
 
-absl::optional<UserInitiatedAbortCause> UserInitiatedAbortCause::Parse(
+std::optional<UserInitiatedAbortCause> UserInitiatedAbortCause::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (reader->variable_data().empty()) {
     return UserInitiatedAbortCause("");
diff --git a/net/dcsctp/packet/error_cause/user_initiated_abort_cause.h b/net/dcsctp/packet/error_cause/user_initiated_abort_cause.h
index 9eb1665..e0a6109 100644
--- a/net/dcsctp/packet/error_cause/user_initiated_abort_cause.h
+++ b/net/dcsctp/packet/error_cause/user_initiated_abort_cause.h
@@ -37,7 +37,7 @@
   explicit UserInitiatedAbortCause(absl::string_view upper_layer_abort_reason)
       : upper_layer_abort_reason_(upper_layer_abort_reason) {}
 
-  static absl::optional<UserInitiatedAbortCause> Parse(
+  static std::optional<UserInitiatedAbortCause> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/parameter/add_incoming_streams_request_parameter.cc b/net/dcsctp/packet/parameter/add_incoming_streams_request_parameter.cc
index c33e3e1..e8d82b54 100644
--- a/net/dcsctp/packet/parameter/add_incoming_streams_request_parameter.cc
+++ b/net/dcsctp/packet/parameter/add_incoming_streams_request_parameter.cc
@@ -11,11 +11,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/internal_types.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
@@ -38,11 +38,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int AddIncomingStreamsRequestParameter::kType;
 
-absl::optional<AddIncomingStreamsRequestParameter>
+std::optional<AddIncomingStreamsRequestParameter>
 AddIncomingStreamsRequestParameter::Parse(rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   ReconfigRequestSN request_sequence_number(reader->Load32<4>());
   uint16_t nbr_of_new_streams = reader->Load16<8>();
diff --git a/net/dcsctp/packet/parameter/add_incoming_streams_request_parameter.h b/net/dcsctp/packet/parameter/add_incoming_streams_request_parameter.h
index 3859eb3..8997586 100644
--- a/net/dcsctp/packet/parameter/add_incoming_streams_request_parameter.h
+++ b/net/dcsctp/packet/parameter/add_incoming_streams_request_parameter.h
@@ -42,7 +42,7 @@
       : request_sequence_number_(request_sequence_number),
         nbr_of_new_streams_(nbr_of_new_streams) {}
 
-  static absl::optional<AddIncomingStreamsRequestParameter> Parse(
+  static std::optional<AddIncomingStreamsRequestParameter> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/parameter/add_outgoing_streams_request_parameter.cc b/net/dcsctp/packet/parameter/add_outgoing_streams_request_parameter.cc
index 4787ee9..1a8f4f9 100644
--- a/net/dcsctp/packet/parameter/add_outgoing_streams_request_parameter.cc
+++ b/net/dcsctp/packet/parameter/add_outgoing_streams_request_parameter.cc
@@ -11,11 +11,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -37,11 +37,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int AddOutgoingStreamsRequestParameter::kType;
 
-absl::optional<AddOutgoingStreamsRequestParameter>
+std::optional<AddOutgoingStreamsRequestParameter>
 AddOutgoingStreamsRequestParameter::Parse(rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   ReconfigRequestSN request_sequence_number(reader->Load32<4>());
   uint16_t nbr_of_new_streams = reader->Load16<8>();
diff --git a/net/dcsctp/packet/parameter/add_outgoing_streams_request_parameter.h b/net/dcsctp/packet/parameter/add_outgoing_streams_request_parameter.h
index 01e8f91..adfcb48 100644
--- a/net/dcsctp/packet/parameter/add_outgoing_streams_request_parameter.h
+++ b/net/dcsctp/packet/parameter/add_outgoing_streams_request_parameter.h
@@ -42,7 +42,7 @@
       : request_sequence_number_(request_sequence_number),
         nbr_of_new_streams_(nbr_of_new_streams) {}
 
-  static absl::optional<AddOutgoingStreamsRequestParameter> Parse(
+  static std::optional<AddOutgoingStreamsRequestParameter> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/parameter/forward_tsn_supported_parameter.cc b/net/dcsctp/packet/parameter/forward_tsn_supported_parameter.cc
index 7dd8e19..96c1629 100644
--- a/net/dcsctp/packet/parameter/forward_tsn_supported_parameter.cc
+++ b/net/dcsctp/packet/parameter/forward_tsn_supported_parameter.cc
@@ -11,9 +11,9 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 
 namespace dcsctp {
@@ -26,10 +26,10 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int ForwardTsnSupportedParameter::kType;
 
-absl::optional<ForwardTsnSupportedParameter>
-ForwardTsnSupportedParameter::Parse(rtc::ArrayView<const uint8_t> data) {
+std::optional<ForwardTsnSupportedParameter> ForwardTsnSupportedParameter::Parse(
+    rtc::ArrayView<const uint8_t> data) {
   if (!ParseTLV(data).has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ForwardTsnSupportedParameter();
 }
diff --git a/net/dcsctp/packet/parameter/forward_tsn_supported_parameter.h b/net/dcsctp/packet/parameter/forward_tsn_supported_parameter.h
index d4cff4a..45b9dcf 100644
--- a/net/dcsctp/packet/parameter/forward_tsn_supported_parameter.h
+++ b/net/dcsctp/packet/parameter/forward_tsn_supported_parameter.h
@@ -37,7 +37,7 @@
 
   ForwardTsnSupportedParameter() {}
 
-  static absl::optional<ForwardTsnSupportedParameter> Parse(
+  static std::optional<ForwardTsnSupportedParameter> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/parameter/heartbeat_info_parameter.cc b/net/dcsctp/packet/parameter/heartbeat_info_parameter.cc
index 918976d..5435c07 100644
--- a/net/dcsctp/packet/parameter/heartbeat_info_parameter.cc
+++ b/net/dcsctp/packet/parameter/heartbeat_info_parameter.cc
@@ -11,11 +11,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -37,11 +37,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int HeartbeatInfoParameter::kType;
 
-absl::optional<HeartbeatInfoParameter> HeartbeatInfoParameter::Parse(
+std::optional<HeartbeatInfoParameter> HeartbeatInfoParameter::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return HeartbeatInfoParameter(reader->variable_data());
 }
diff --git a/net/dcsctp/packet/parameter/heartbeat_info_parameter.h b/net/dcsctp/packet/parameter/heartbeat_info_parameter.h
index ec503a94..8622d9a 100644
--- a/net/dcsctp/packet/parameter/heartbeat_info_parameter.h
+++ b/net/dcsctp/packet/parameter/heartbeat_info_parameter.h
@@ -37,7 +37,7 @@
   explicit HeartbeatInfoParameter(rtc::ArrayView<const uint8_t> info)
       : info_(info.begin(), info.end()) {}
 
-  static absl::optional<HeartbeatInfoParameter> Parse(
+  static std::optional<HeartbeatInfoParameter> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.cc b/net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.cc
index 6191adf..3935f8e 100644
--- a/net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.cc
+++ b/net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.cc
@@ -12,11 +12,11 @@
 #include <stddef.h>
 
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -42,11 +42,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int IncomingSSNResetRequestParameter::kType;
 
-absl::optional<IncomingSSNResetRequestParameter>
+std::optional<IncomingSSNResetRequestParameter>
 IncomingSSNResetRequestParameter::Parse(rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   ReconfigRequestSN request_sequence_number(reader->Load32<4>());
diff --git a/net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.h b/net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.h
index 18963ef..eb14eb6 100644
--- a/net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.h
+++ b/net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.h
@@ -43,7 +43,7 @@
       : request_sequence_number_(request_sequence_number),
         stream_ids_(std::move(stream_ids)) {}
 
-  static absl::optional<IncomingSSNResetRequestParameter> Parse(
+  static std::optional<IncomingSSNResetRequestParameter> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/parameter/outgoing_ssn_reset_request_parameter.cc b/net/dcsctp/packet/parameter/outgoing_ssn_reset_request_parameter.cc
index c25a242..a1391bd 100644
--- a/net/dcsctp/packet/parameter/outgoing_ssn_reset_request_parameter.cc
+++ b/net/dcsctp/packet/parameter/outgoing_ssn_reset_request_parameter.cc
@@ -12,11 +12,11 @@
 #include <stddef.h>
 
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/internal_types.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
@@ -48,11 +48,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int OutgoingSSNResetRequestParameter::kType;
 
-absl::optional<OutgoingSSNResetRequestParameter>
+std::optional<OutgoingSSNResetRequestParameter>
 OutgoingSSNResetRequestParameter::Parse(rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   ReconfigRequestSN request_sequence_number(reader->Load32<4>());
diff --git a/net/dcsctp/packet/parameter/outgoing_ssn_reset_request_parameter.h b/net/dcsctp/packet/parameter/outgoing_ssn_reset_request_parameter.h
index 6eb44e0..3a9855c 100644
--- a/net/dcsctp/packet/parameter/outgoing_ssn_reset_request_parameter.h
+++ b/net/dcsctp/packet/parameter/outgoing_ssn_reset_request_parameter.h
@@ -49,7 +49,7 @@
         sender_last_assigned_tsn_(sender_last_assigned_tsn),
         stream_ids_(std::move(stream_ids)) {}
 
-  static absl::optional<OutgoingSSNResetRequestParameter> Parse(
+  static std::optional<OutgoingSSNResetRequestParameter> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/parameter/parameter.cc b/net/dcsctp/packet/parameter/parameter.cc
index b3b2bff..e300f0a 100644
--- a/net/dcsctp/packet/parameter/parameter.cc
+++ b/net/dcsctp/packet/parameter/parameter.cc
@@ -13,12 +13,12 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/memory/memory.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/math.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
@@ -70,20 +70,20 @@
   return result;
 }
 
-absl::optional<Parameters> Parameters::Parse(
+std::optional<Parameters> Parameters::Parse(
     rtc::ArrayView<const uint8_t> data) {
   // Validate the parameter descriptors
   rtc::ArrayView<const uint8_t> span(data);
   while (!span.empty()) {
     if (span.size() < kParameterHeaderSize) {
       RTC_DLOG(LS_WARNING) << "Insufficient parameter length";
-      return absl::nullopt;
+      return std::nullopt;
     }
     BoundedByteReader<kParameterHeaderSize> header(span);
     uint16_t length = header.Load16<2>();
     if (length < kParameterHeaderSize || length > span.size()) {
       RTC_DLOG(LS_WARNING) << "Invalid parameter length field";
-      return absl::nullopt;
+      return std::nullopt;
     }
     size_t length_with_padding = RoundUpTo4(length);
     if (length_with_padding > span.size()) {
diff --git a/net/dcsctp/packet/parameter/parameter.h b/net/dcsctp/packet/parameter/parameter.h
index e8fa67c..d32157d 100644
--- a/net/dcsctp/packet/parameter/parameter.h
+++ b/net/dcsctp/packet/parameter/parameter.h
@@ -16,6 +16,7 @@
 #include <cstdint>
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <utility>
@@ -23,7 +24,6 @@
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/tlv_trait.h"
 #include "rtc_base/strings/string_builder.h"
@@ -61,7 +61,7 @@
     std::vector<uint8_t> data_;
   };
 
-  static absl::optional<Parameters> Parse(rtc::ArrayView<const uint8_t> data);
+  static std::optional<Parameters> Parse(rtc::ArrayView<const uint8_t> data);
 
   Parameters() {}
   Parameters(Parameters&& other) = default;
@@ -71,7 +71,7 @@
   std::vector<ParameterDescriptor> descriptors() const;
 
   template <typename P>
-  absl::optional<P> get() const {
+  std::optional<P> get() const {
     static_assert(std::is_base_of<Parameter, P>::value,
                   "Template parameter not derived from Parameter");
     for (const auto& p : descriptors()) {
@@ -79,7 +79,7 @@
         return P::Parse(p.data);
       }
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
  private:
diff --git a/net/dcsctp/packet/parameter/reconfiguration_response_parameter.cc b/net/dcsctp/packet/parameter/reconfiguration_response_parameter.cc
index fafb204..eed1e02 100644
--- a/net/dcsctp/packet/parameter/reconfiguration_response_parameter.cc
+++ b/net/dcsctp/packet/parameter/reconfiguration_response_parameter.cc
@@ -12,12 +12,12 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -64,11 +64,11 @@
   }
 }
 
-absl::optional<ReconfigurationResponseParameter>
+std::optional<ReconfigurationResponseParameter>
 ReconfigurationResponseParameter::Parse(rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   ReconfigRequestSN response_sequence_number(reader->Load32<4>());
@@ -101,14 +101,14 @@
     default:
       RTC_DLOG(LS_WARNING) << "Invalid reconfig response result: "
                            << result_nbr;
-      return absl::nullopt;
+      return std::nullopt;
   }
 
   if (reader->variable_data().empty()) {
     return ReconfigurationResponseParameter(response_sequence_number, result);
   } else if (reader->variable_data_size() != kNextTsnHeaderSize) {
     RTC_DLOG(LS_WARNING) << "Invalid parameter size";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   BoundedByteReader<kNextTsnHeaderSize> sub_reader =
diff --git a/net/dcsctp/packet/parameter/reconfiguration_response_parameter.h b/net/dcsctp/packet/parameter/reconfiguration_response_parameter.h
index c5a68ac..a8cf4dd 100644
--- a/net/dcsctp/packet/parameter/reconfiguration_response_parameter.h
+++ b/net/dcsctp/packet/parameter/reconfiguration_response_parameter.h
@@ -12,11 +12,11 @@
 #include <stddef.h>
 
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/internal_types.h"
 #include "net/dcsctp/packet/parameter/parameter.h"
@@ -51,8 +51,8 @@
                                    Result result)
       : response_sequence_number_(response_sequence_number),
         result_(result),
-        sender_next_tsn_(absl::nullopt),
-        receiver_next_tsn_(absl::nullopt) {}
+        sender_next_tsn_(std::nullopt),
+        receiver_next_tsn_(std::nullopt) {}
 
   explicit ReconfigurationResponseParameter(
       ReconfigRequestSN response_sequence_number,
@@ -64,7 +64,7 @@
         sender_next_tsn_(sender_next_tsn),
         receiver_next_tsn_(receiver_next_tsn) {}
 
-  static absl::optional<ReconfigurationResponseParameter> Parse(
+  static std::optional<ReconfigurationResponseParameter> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
@@ -74,15 +74,15 @@
     return response_sequence_number_;
   }
   Result result() const { return result_; }
-  absl::optional<TSN> sender_next_tsn() const { return sender_next_tsn_; }
-  absl::optional<TSN> receiver_next_tsn() const { return receiver_next_tsn_; }
+  std::optional<TSN> sender_next_tsn() const { return sender_next_tsn_; }
+  std::optional<TSN> receiver_next_tsn() const { return receiver_next_tsn_; }
 
  private:
   static constexpr size_t kNextTsnHeaderSize = 8;
   ReconfigRequestSN response_sequence_number_;
   Result result_;
-  absl::optional<TSN> sender_next_tsn_;
-  absl::optional<TSN> receiver_next_tsn_;
+  std::optional<TSN> sender_next_tsn_;
+  std::optional<TSN> receiver_next_tsn_;
 };
 
 absl::string_view ToString(ReconfigurationResponseParameter::Result result);
diff --git a/net/dcsctp/packet/parameter/reconfiguration_response_parameter_test.cc b/net/dcsctp/packet/parameter/reconfiguration_response_parameter_test.cc
index 8125d93..b784545 100644
--- a/net/dcsctp/packet/parameter/reconfiguration_response_parameter_test.cc
+++ b/net/dcsctp/packet/parameter/reconfiguration_response_parameter_test.cc
@@ -11,10 +11,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "net/dcsctp/testing/testing_macros.h"
 #include "rtc_base/gunit.h"
 #include "test/gmock.h"
@@ -37,8 +37,8 @@
   EXPECT_EQ(*deserialized.response_sequence_number(), 1u);
   EXPECT_EQ(deserialized.result(),
             ReconfigurationResponseParameter::Result::kSuccessPerformed);
-  EXPECT_EQ(deserialized.sender_next_tsn(), absl::nullopt);
-  EXPECT_EQ(deserialized.receiver_next_tsn(), absl::nullopt);
+  EXPECT_EQ(deserialized.sender_next_tsn(), std::nullopt);
+  EXPECT_EQ(deserialized.receiver_next_tsn(), std::nullopt);
 }
 
 TEST(ReconfigurationResponseParameterTest,
diff --git a/net/dcsctp/packet/parameter/ssn_tsn_reset_request_parameter.cc b/net/dcsctp/packet/parameter/ssn_tsn_reset_request_parameter.cc
index d656e0d..1e37ea7 100644
--- a/net/dcsctp/packet/parameter/ssn_tsn_reset_request_parameter.cc
+++ b/net/dcsctp/packet/parameter/ssn_tsn_reset_request_parameter.cc
@@ -11,11 +11,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -35,11 +35,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int SSNTSNResetRequestParameter::kType;
 
-absl::optional<SSNTSNResetRequestParameter> SSNTSNResetRequestParameter::Parse(
+std::optional<SSNTSNResetRequestParameter> SSNTSNResetRequestParameter::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   ReconfigRequestSN request_sequence_number(reader->Load32<4>());
 
diff --git a/net/dcsctp/packet/parameter/ssn_tsn_reset_request_parameter.h b/net/dcsctp/packet/parameter/ssn_tsn_reset_request_parameter.h
index e31d7eb..eb156a7 100644
--- a/net/dcsctp/packet/parameter/ssn_tsn_reset_request_parameter.h
+++ b/net/dcsctp/packet/parameter/ssn_tsn_reset_request_parameter.h
@@ -40,7 +40,7 @@
       ReconfigRequestSN request_sequence_number)
       : request_sequence_number_(request_sequence_number) {}
 
-  static absl::optional<SSNTSNResetRequestParameter> Parse(
+  static std::optional<SSNTSNResetRequestParameter> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/parameter/state_cookie_parameter.cc b/net/dcsctp/packet/parameter/state_cookie_parameter.cc
index 9777aa6..be4b6a5 100644
--- a/net/dcsctp/packet/parameter/state_cookie_parameter.cc
+++ b/net/dcsctp/packet/parameter/state_cookie_parameter.cc
@@ -11,11 +11,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -28,11 +28,11 @@
 
 constexpr int StateCookieParameter::kType;
 
-absl::optional<StateCookieParameter> StateCookieParameter::Parse(
+std::optional<StateCookieParameter> StateCookieParameter::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return StateCookieParameter(reader->variable_data());
 }
diff --git a/net/dcsctp/packet/parameter/state_cookie_parameter.h b/net/dcsctp/packet/parameter/state_cookie_parameter.h
index f435549..473ee4f 100644
--- a/net/dcsctp/packet/parameter/state_cookie_parameter.h
+++ b/net/dcsctp/packet/parameter/state_cookie_parameter.h
@@ -38,7 +38,7 @@
   explicit StateCookieParameter(rtc::ArrayView<const uint8_t> data)
       : data_(data.begin(), data.end()) {}
 
-  static absl::optional<StateCookieParameter> Parse(
+  static std::optional<StateCookieParameter> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/parameter/supported_extensions_parameter.cc b/net/dcsctp/packet/parameter/supported_extensions_parameter.cc
index 87a5bd9b..a21819f 100644
--- a/net/dcsctp/packet/parameter/supported_extensions_parameter.cc
+++ b/net/dcsctp/packet/parameter/supported_extensions_parameter.cc
@@ -10,11 +10,11 @@
 #include "net/dcsctp/packet/parameter/supported_extensions_parameter.h"
 
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -39,11 +39,11 @@
 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int SupportedExtensionsParameter::kType;
 
-absl::optional<SupportedExtensionsParameter>
-SupportedExtensionsParameter::Parse(rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+std::optional<SupportedExtensionsParameter> SupportedExtensionsParameter::Parse(
+    rtc::ArrayView<const uint8_t> data) {
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<uint8_t> chunk_types(reader->variable_data().begin(),
diff --git a/net/dcsctp/packet/parameter/supported_extensions_parameter.h b/net/dcsctp/packet/parameter/supported_extensions_parameter.h
index 5689fd8..6a024ad 100644
--- a/net/dcsctp/packet/parameter/supported_extensions_parameter.h
+++ b/net/dcsctp/packet/parameter/supported_extensions_parameter.h
@@ -41,7 +41,7 @@
   explicit SupportedExtensionsParameter(std::vector<uint8_t> chunk_types)
       : chunk_types_(std::move(chunk_types)) {}
 
-  static absl::optional<SupportedExtensionsParameter> Parse(
+  static std::optional<SupportedExtensionsParameter> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.cc b/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.cc
index a846d6d..04b7412 100644
--- a/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.cc
+++ b/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.cc
@@ -11,9 +11,9 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "rtc_base/strings/string_builder.h"
 
@@ -29,17 +29,17 @@
 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 constexpr int ZeroChecksumAcceptableChunkParameter::kType;
 
-absl::optional<ZeroChecksumAcceptableChunkParameter>
+std::optional<ZeroChecksumAcceptableChunkParameter>
 ZeroChecksumAcceptableChunkParameter::Parse(
     rtc::ArrayView<const uint8_t> data) {
-  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
+  std::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
   if (!reader.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   ZeroChecksumAlternateErrorDetectionMethod method(reader->Load32<4>());
   if (method == ZeroChecksumAlternateErrorDetectionMethod::None()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ZeroChecksumAcceptableChunkParameter(method);
 }
diff --git a/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.h b/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.h
index 18c98c9..4b24692 100644
--- a/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.h
+++ b/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.h
@@ -41,7 +41,7 @@
       ZeroChecksumAlternateErrorDetectionMethod error_detection_method)
       : error_detection_method_(error_detection_method) {}
 
-  static absl::optional<ZeroChecksumAcceptableChunkParameter> Parse(
+  static std::optional<ZeroChecksumAcceptableChunkParameter> Parse(
       rtc::ArrayView<const uint8_t> data);
 
   void SerializeTo(std::vector<uint8_t>& out) const override;
diff --git a/net/dcsctp/packet/sctp_packet.cc b/net/dcsctp/packet/sctp_packet.cc
index 978181f..f9c8812 100644
--- a/net/dcsctp/packet/sctp_packet.cc
+++ b/net/dcsctp/packet/sctp_packet.cc
@@ -12,12 +12,12 @@
 #include <stddef.h>
 
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/memory/memory.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/math.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
@@ -105,12 +105,12 @@
   return out;
 }
 
-absl::optional<SctpPacket> SctpPacket::Parse(rtc::ArrayView<const uint8_t> data,
-                                             const DcSctpOptions& options) {
+std::optional<SctpPacket> SctpPacket::Parse(rtc::ArrayView<const uint8_t> data,
+                                            const DcSctpOptions& options) {
   if (data.size() < kHeaderSize + kChunkTlvHeaderSize ||
       data.size() > kMaxUdpPacketSize) {
     RTC_DLOG(LS_WARNING) << "Invalid packet size";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   BoundedByteReader<kHeaderSize> reader(data);
@@ -143,7 +143,7 @@
           "Invalid packet checksum, packet_checksum=0x%08x, "
           "calculated_checksum=0x%08x",
           common_header.checksum, calculated_checksum);
-      return absl::nullopt;
+      return std::nullopt;
     }
     // Restore the checksum in the header.
     BoundedByteWriter<kHeaderSize>(data_copy).Store32<8>(
@@ -166,7 +166,7 @@
   while (!descriptor_data.empty()) {
     if (descriptor_data.size() < kChunkTlvHeaderSize) {
       RTC_DLOG(LS_WARNING) << "Too small chunk";
-      return absl::nullopt;
+      return std::nullopt;
     }
     BoundedByteReader<kChunkTlvHeaderSize> chunk_header(descriptor_data);
     uint8_t type = chunk_header.Load8<0>();
@@ -176,10 +176,10 @@
     if (padded_length > descriptor_data.size()) {
       RTC_DLOG(LS_WARNING) << "Too large chunk. length=" << length
                            << ", remaining=" << descriptor_data.size();
-      return absl::nullopt;
+      return std::nullopt;
     } else if (padded_length < kChunkTlvHeaderSize) {
       RTC_DLOG(LS_WARNING) << "Too small chunk. length=" << length;
-      return absl::nullopt;
+      return std::nullopt;
     }
     descriptors.emplace_back(type, flags,
                              descriptor_data.subview(0, padded_length));
diff --git a/net/dcsctp/packet/sctp_packet.h b/net/dcsctp/packet/sctp_packet.h
index 0d348b4..9c06106 100644
--- a/net/dcsctp/packet/sctp_packet.h
+++ b/net/dcsctp/packet/sctp_packet.h
@@ -89,8 +89,8 @@
   };
 
   // Parses `data` as an SCTP packet and returns it if it validates.
-  static absl::optional<SctpPacket> Parse(rtc::ArrayView<const uint8_t> data,
-                                          const DcSctpOptions& options);
+  static std::optional<SctpPacket> Parse(rtc::ArrayView<const uint8_t> data,
+                                         const DcSctpOptions& options);
 
   // Returns the SCTP common header.
   const CommonHeader& common_header() const { return common_header_; }
diff --git a/net/dcsctp/packet/tlv_trait.h b/net/dcsctp/packet/tlv_trait.h
index a3c728e..37b3628 100644
--- a/net/dcsctp/packet/tlv_trait.h
+++ b/net/dcsctp/packet/tlv_trait.h
@@ -16,10 +16,10 @@
 #include <algorithm>
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -80,11 +80,11 @@
 
   // Validates the data with regards to size, alignment and type.
   // If valid, returns a bounded buffer.
-  static absl::optional<BoundedByteReader<Config::kHeaderSize>> ParseTLV(
+  static std::optional<BoundedByteReader<Config::kHeaderSize>> ParseTLV(
       rtc::ArrayView<const uint8_t> data) {
     if (data.size() < Config::kHeaderSize) {
       tlv_trait_impl::ReportInvalidSize(data.size(), Config::kHeaderSize);
-      return absl::nullopt;
+      return std::nullopt;
     }
     BoundedByteReader<kTlvHeaderSize> tlv_header(data);
 
@@ -94,7 +94,7 @@
 
     if (type != Config::kType) {
       tlv_trait_impl::ReportInvalidType(type, Config::kType);
-      return absl::nullopt;
+      return std::nullopt;
     }
     const uint16_t length = tlv_header.template Load16<2>();
     if (Config::kVariableLengthAlignment == 0) {
@@ -102,25 +102,25 @@
       if (length != Config::kHeaderSize || data.size() != Config::kHeaderSize) {
         tlv_trait_impl::ReportInvalidFixedLengthField(length,
                                                       Config::kHeaderSize);
-        return absl::nullopt;
+        return std::nullopt;
       }
     } else {
       // Expect variable length data - verify its size alignment.
       if (length > data.size() || length < Config::kHeaderSize) {
         tlv_trait_impl::ReportInvalidVariableLengthField(length, data.size());
-        return absl::nullopt;
+        return std::nullopt;
       }
       const size_t padding = data.size() - length;
       if (padding > 3) {
         // https://tools.ietf.org/html/rfc4960#section-3.2
         // "This padding MUST NOT be more than 3 bytes in total"
         tlv_trait_impl::ReportInvalidPadding(padding);
-        return absl::nullopt;
+        return std::nullopt;
       }
       if (!ValidateLengthAlignment(length, Config::kVariableLengthAlignment)) {
         tlv_trait_impl::ReportInvalidLengthMultiple(
             length, Config::kVariableLengthAlignment);
-        return absl::nullopt;
+        return std::nullopt;
       }
     }
     return BoundedByteReader<Config::kHeaderSize>(data.subview(0, length));
diff --git a/net/dcsctp/packet/tlv_trait_test.cc b/net/dcsctp/packet/tlv_trait_test.cc
index a0dd1a1..e0fabd9 100644
--- a/net/dcsctp/packet/tlv_trait_test.cc
+++ b/net/dcsctp/packet/tlv_trait_test.cc
@@ -44,8 +44,8 @@
     writer.CopyToVariableData(rtc::ArrayView<const uint8_t>(variable_data));
   }
 
-  static absl::optional<BoundedByteReader<OneByteTypeConfig::kHeaderSize>>
-  Parse(rtc::ArrayView<const uint8_t> data) {
+  static std::optional<BoundedByteReader<OneByteTypeConfig::kHeaderSize>> Parse(
+      rtc::ArrayView<const uint8_t> data) {
     return ParseTLV(data);
   }
 };
@@ -64,7 +64,7 @@
   uint8_t data[] = {0x49, 0x00, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04,
                     0x05, 0x06, 0x07, 0x08, 0xDE, 0xAD, 0xBE, 0xEF};
 
-  absl::optional<BoundedByteReader<OneByteTypeConfig::kHeaderSize>> reader =
+  std::optional<BoundedByteReader<OneByteTypeConfig::kHeaderSize>> reader =
       OneByteChunk::Parse(data);
   ASSERT_TRUE(reader.has_value());
   EXPECT_EQ(reader->Load32<4>(), 0x01020304U);
@@ -93,8 +93,8 @@
     writer.CopyToVariableData(rtc::ArrayView<const uint8_t>(variable_data));
   }
 
-  static absl::optional<BoundedByteReader<TwoByteTypeConfig::kHeaderSize>>
-  Parse(rtc::ArrayView<const uint8_t> data) {
+  static std::optional<BoundedByteReader<TwoByteTypeConfig::kHeaderSize>> Parse(
+      rtc::ArrayView<const uint8_t> data) {
     return ParseTLV(data);
   }
 };
@@ -114,7 +114,7 @@
   uint8_t data[] = {0x7A, 0x69, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04,
                     0x05, 0x06, 0x07, 0x08, 0xDE, 0xAD, 0xBE, 0xEF};
 
-  absl::optional<BoundedByteReader<TwoByteTypeConfig::kHeaderSize>> reader =
+  std::optional<BoundedByteReader<TwoByteTypeConfig::kHeaderSize>> reader =
       TwoByteChunk::Parse(data);
   EXPECT_TRUE(reader.has_value());
   EXPECT_EQ(reader->Load32<4>(), 0x01020304U);
diff --git a/net/dcsctp/public/BUILD.gn b/net/dcsctp/public/BUILD.gn
index 316af7b..97f7651 100644
--- a/net/dcsctp/public/BUILD.gn
+++ b/net/dcsctp/public/BUILD.gn
@@ -13,7 +13,6 @@
     "../../../api:array_view",
     "../../../api/units:time_delta",
     "../../../rtc_base:strong_alias",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "dcsctp_message.h",
@@ -31,7 +30,6 @@
     "../../../rtc_base:checks",
     "../../../rtc_base:strong_alias",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "dcsctp_handover_state.cc",
diff --git a/net/dcsctp/public/dcsctp_options.h b/net/dcsctp/public/dcsctp_options.h
index 8b4ed3c..115cf5e 100644
--- a/net/dcsctp/public/dcsctp_options.h
+++ b/net/dcsctp/public/dcsctp_options.h
@@ -13,7 +13,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "net/dcsctp/public/types.h"
 
 namespace dcsctp {
@@ -128,7 +129,7 @@
   // transient network issues. Setting this value may require changing
   // `max_retransmissions` and `max_init_retransmits` to ensure that the
   // connection is not closed too quickly.
-  absl::optional<DurationMs> max_timer_backoff_duration = absl::nullopt;
+  std::optional<DurationMs> max_timer_backoff_duration = std::nullopt;
 
   // Hearbeat interval (on idle connections only). Set to zero to disable.
   DurationMs heartbeat_interval = DurationMs(30000);
@@ -183,13 +184,13 @@
   // retransmission scenarios.
   int max_burst = 4;
 
-  // Maximum Data Retransmit Attempts (per DATA chunk). Set to absl::nullopt for
+  // Maximum Data Retransmit Attempts (per DATA chunk). Set to std::nullopt for
   // no limit.
-  absl::optional<int> max_retransmissions = 10;
+  std::optional<int> max_retransmissions = 10;
 
   // Max.Init.Retransmits (https://tools.ietf.org/html/rfc4960#section-15). Set
-  // to absl::nullopt for no limit.
-  absl::optional<int> max_init_retransmits = 8;
+  // to std::nullopt for no limit.
+  std::optional<int> max_init_retransmits = 8;
 
   // RFC3758 Partial Reliability Extension
   bool enable_partial_reliability = true;
diff --git a/net/dcsctp/public/dcsctp_socket.h b/net/dcsctp/public/dcsctp_socket.h
index 9989ae8..bf53ebd 100644
--- a/net/dcsctp/public/dcsctp_socket.h
+++ b/net/dcsctp/public/dcsctp_socket.h
@@ -12,11 +12,11 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/units/timestamp.h"
@@ -51,11 +51,11 @@
   // If set, will discard messages that haven't been correctly sent and
   // received before the lifetime has expired. This is only available if the
   // peer supports Partial Reliability Extension (RFC3758).
-  absl::optional<DurationMs> lifetime = absl::nullopt;
+  std::optional<DurationMs> lifetime = std::nullopt;
 
   // If set, limits the number of retransmissions. This is only available
   // if the peer supports Partial Reliability Extension (RFC3758).
-  absl::optional<size_t> max_retransmissions = absl::nullopt;
+  std::optional<size_t> max_retransmissions = std::nullopt;
 
   // If set, will generate lifecycle events for this message. See e.g.
   // `DcSctpSocketCallbacks::OnLifecycleMessageFullySent`. This value is decided
@@ -621,10 +621,10 @@
                                              size_t bytes) = 0;
 
   // Retrieves the latest metrics. If the socket is not fully connected,
-  // `absl::nullopt` will be returned. Note that metrics are not guaranteed to
+  // `std::nullopt` will be returned. Note that metrics are not guaranteed to
   // be carried over if this socket is handed over by calling
   // `GetHandoverStateAndClose`.
-  virtual absl::optional<Metrics> GetMetrics() const = 0;
+  virtual std::optional<Metrics> GetMetrics() const = 0;
 
   // Returns empty bitmask if the socket is in the state in which a snapshot of
   // the state can be made by `GetHandoverStateAndClose()`. Return value is
@@ -637,7 +637,7 @@
   // The method fails if the socket is not in a state ready for handover.
   // nullopt indicates the failure. `DcSctpSocketCallbacks::OnClosed` will be
   // called on success.
-  virtual absl::optional<DcSctpSocketHandoverState>
+  virtual std::optional<DcSctpSocketHandoverState>
   GetHandoverStateAndClose() = 0;
 
   // Returns the detected SCTP implementation of the peer. As this is not
diff --git a/net/dcsctp/public/mock_dcsctp_socket.h b/net/dcsctp/public/mock_dcsctp_socket.h
index c71c3ae..627b20d 100644
--- a/net/dcsctp/public/mock_dcsctp_socket.h
+++ b/net/dcsctp/public/mock_dcsctp_socket.h
@@ -81,13 +81,13 @@
               (StreamID stream_id, size_t bytes),
               (override));
 
-  MOCK_METHOD(absl::optional<Metrics>, GetMetrics, (), (const, override));
+  MOCK_METHOD(std::optional<Metrics>, GetMetrics, (), (const, override));
 
   MOCK_METHOD(HandoverReadinessStatus,
               GetHandoverReadiness,
               (),
               (const, override));
-  MOCK_METHOD(absl::optional<DcSctpSocketHandoverState>,
+  MOCK_METHOD(std::optional<DcSctpSocketHandoverState>,
               GetHandoverStateAndClose,
               (),
               (override));
diff --git a/net/dcsctp/rx/BUILD.gn b/net/dcsctp/rx/BUILD.gn
index a39441f..2046a27 100644
--- a/net/dcsctp/rx/BUILD.gn
+++ b/net/dcsctp/rx/BUILD.gn
@@ -21,7 +21,6 @@
     "../timer",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "data_tracker.cc",
@@ -72,7 +71,6 @@
     "../public:types",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "traditional_reassembly_streams.cc",
@@ -99,7 +97,6 @@
     "../public:types",
     "//third_party/abseil-cpp/absl/functional:any_invocable",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "reassembly_queue.cc",
@@ -129,7 +126,6 @@
       "../public:types",
       "../testing:data_generator",
       "../timer",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
     sources = [
       "data_tracker_test.cc",
diff --git a/net/dcsctp/rx/data_tracker.cc b/net/dcsctp/rx/data_tracker.cc
index 70b7587..627478a 100644
--- a/net/dcsctp/rx/data_tracker.cc
+++ b/net/dcsctp/rx/data_tracker.cc
@@ -12,6 +12,7 @@
 #include <algorithm>
 #include <cstdint>
 #include <iterator>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
@@ -19,7 +20,6 @@
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "net/dcsctp/common/sequence_numbers.h"
 #include "net/dcsctp/packet/chunk/sack_chunk.h"
 #include "net/dcsctp/timer/timer.h"
diff --git a/net/dcsctp/rx/data_tracker_test.cc b/net/dcsctp/rx/data_tracker_test.cc
index 0e9e4fc..e0bf4cf 100644
--- a/net/dcsctp/rx/data_tracker_test.cc
+++ b/net/dcsctp/rx/data_tracker_test.cc
@@ -12,8 +12,8 @@
 #include <cstdint>
 #include <initializer_list>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/task_queue/task_queue_base.h"
 #include "net/dcsctp/common/handover_testing.h"
diff --git a/net/dcsctp/rx/reassembly_queue.cc b/net/dcsctp/rx/reassembly_queue.cc
index 6f22806..4947d74 100644
--- a/net/dcsctp/rx/reassembly_queue.cc
+++ b/net/dcsctp/rx/reassembly_queue.cc
@@ -14,13 +14,13 @@
 #include <algorithm>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/sequence_numbers.h"
 #include "net/dcsctp/packet/chunk/forward_tsn_common.h"
@@ -135,7 +135,7 @@
     // normally."
     auto deferred_actions =
         std::move(deferred_reset_streams_->deferred_actions);
-    deferred_reset_streams_ = absl::nullopt;
+    deferred_reset_streams_ = std::nullopt;
 
     for (auto& action : deferred_actions) {
       action();
@@ -152,7 +152,7 @@
     RTC_DLOG(LS_VERBOSE) << log_prefix_
                          << "Entering deferred reset; sender_last_assigned_tsn="
                          << *sender_last_assigned_tsn;
-    deferred_reset_streams_ = absl::make_optional<DeferredResetStreams>(
+    deferred_reset_streams_ = std::make_optional<DeferredResetStreams>(
         tsn_unwrapper_.Unwrap(sender_last_assigned_tsn),
         webrtc::flat_set<StreamID>(streams.begin(), streams.end()));
   }
diff --git a/net/dcsctp/rx/reassembly_queue.h b/net/dcsctp/rx/reassembly_queue.h
index 9e0b6e2..ef6f0fe 100644
--- a/net/dcsctp/rx/reassembly_queue.h
+++ b/net/dcsctp/rx/reassembly_queue.h
@@ -151,7 +151,7 @@
   std::vector<DcSctpMessage> reassembled_messages_;
 
   // If present, "deferred reset processing" mode is active.
-  absl::optional<DeferredResetStreams> deferred_reset_streams_;
+  std::optional<DeferredResetStreams> deferred_reset_streams_;
 
   // The number of "payload bytes" that are in this queue, in total.
   size_t queued_bytes_ = 0;
diff --git a/net/dcsctp/rx/traditional_reassembly_streams.cc b/net/dcsctp/rx/traditional_reassembly_streams.cc
index c94691f..296258c 100644
--- a/net/dcsctp/rx/traditional_reassembly_streams.cc
+++ b/net/dcsctp/rx/traditional_reassembly_streams.cc
@@ -16,11 +16,11 @@
 #include <iterator>
 #include <map>
 #include <numeric>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/sequence_numbers.h"
 #include "net/dcsctp/packet/chunk/forward_tsn_common.h"
@@ -34,8 +34,8 @@
 // Given a map (`chunks`) and an iterator to within that map (`iter`), this
 // function will return an iterator to the first chunk in that message, which
 // has the `is_beginning` flag set. If there are any gaps, or if the beginning
-// can't be found, `absl::nullopt` is returned.
-absl::optional<std::map<UnwrappedTSN, Data>::iterator> FindBeginning(
+// can't be found, `std::nullopt` is returned.
+std::optional<std::map<UnwrappedTSN, Data>::iterator> FindBeginning(
     const std::map<UnwrappedTSN, Data>& chunks,
     std::map<UnwrappedTSN, Data>::iterator iter) {
   UnwrappedTSN prev_tsn = iter->first;
@@ -44,11 +44,11 @@
       return iter;
     }
     if (iter == chunks.begin()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     --iter;
     if (iter->first.next_value() != prev_tsn) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     prev_tsn = iter->first;
   }
@@ -57,8 +57,8 @@
 // Given a map (`chunks`) and an iterator to within that map (`iter`), this
 // function will return an iterator to the chunk after the last chunk in that
 // message, which has the `is_end` flag set. If there are any gaps, or if the
-// end can't be found, `absl::nullopt` is returned.
-absl::optional<std::map<UnwrappedTSN, Data>::iterator> FindEnd(
+// end can't be found, `std::nullopt` is returned.
+std::optional<std::map<UnwrappedTSN, Data>::iterator> FindEnd(
     std::map<UnwrappedTSN, Data>& chunks,
     std::map<UnwrappedTSN, Data>::iterator iter) {
   UnwrappedTSN prev_tsn = iter->first;
@@ -68,10 +68,10 @@
     }
     ++iter;
     if (iter == chunks.end()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (iter->first != prev_tsn.next_value()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     prev_tsn = iter->first;
   }
@@ -108,11 +108,11 @@
   // message, which can be inefficient for very large values of N. This could be
   // optimized by e.g. only trying to assemble a message once _any_ beginning
   // and _any_ end has been found.
-  absl::optional<ChunkMap::iterator> start = FindBeginning(chunks_, iter);
+  std::optional<ChunkMap::iterator> start = FindBeginning(chunks_, iter);
   if (!start.has_value()) {
     return 0;
   }
-  absl::optional<ChunkMap::iterator> end = FindEnd(chunks_, iter);
+  std::optional<ChunkMap::iterator> end = FindEnd(chunks_, iter);
   if (!end.has_value()) {
     return 0;
   }
diff --git a/net/dcsctp/socket/BUILD.gn b/net/dcsctp/socket/BUILD.gn
index 56c7907..1f05c2a 100644
--- a/net/dcsctp/socket/BUILD.gn
+++ b/net/dcsctp/socket/BUILD.gn
@@ -36,7 +36,6 @@
     "../timer",
     "//third_party/abseil-cpp/absl/functional:bind_front",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "heartbeat_handler.cc",
@@ -66,7 +65,6 @@
     "../tx:retransmission_queue",
     "//third_party/abseil-cpp/absl/functional:bind_front",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "stream_reset_handler.cc",
@@ -113,7 +111,6 @@
     "../tx:send_queue",
     "//third_party/abseil-cpp/absl/functional:bind_front",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "capabilities.h",
@@ -159,7 +156,6 @@
     "//third_party/abseil-cpp/absl/functional:bind_front",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
   sources = [
@@ -186,7 +182,6 @@
       "../public:types",
       "../timer",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -202,7 +197,6 @@
       "../public:socket",
       "../public:types",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -256,7 +250,6 @@
       "//third_party/abseil-cpp/absl/flags:flag",
       "//third_party/abseil-cpp/absl/memory",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
     sources = [
       "dcsctp_socket_network_test.cc",
diff --git a/net/dcsctp/socket/dcsctp_socket.cc b/net/dcsctp/socket/dcsctp_socket.cc
index 48b6edb..0db5ce1 100644
--- a/net/dcsctp/socket/dcsctp_socket.cc
+++ b/net/dcsctp/socket/dcsctp_socket.cc
@@ -13,6 +13,7 @@
 #include <cstdint>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -20,7 +21,6 @@
 #include "absl/functional/bind_front.h"
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/chunk/abort_chunk.h"
 #include "net/dcsctp/packet/chunk/chunk.h"
@@ -97,7 +97,7 @@
                                  uint16_t peer_nbr_inbound_streams,
                                  const Parameters& parameters) {
   Capabilities capabilities;
-  absl::optional<SupportedExtensionsParameter> supported_extensions =
+  std::optional<SupportedExtensionsParameter> supported_extensions =
       parameters.get<SupportedExtensionsParameter>();
 
   if (options.enable_partial_reliability) {
@@ -612,9 +612,9 @@
   send_queue_.SetBufferedAmountLowThreshold(stream_id, bytes);
 }
 
-absl::optional<Metrics> DcSctpSocket::GetMetrics() const {
+std::optional<Metrics> DcSctpSocket::GetMetrics() const {
   if (tcb_ == nullptr) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   Metrics metrics = metrics_;
@@ -657,7 +657,7 @@
 }
 
 void DcSctpSocket::MaybeSendResetStreamsRequest() {
-  absl::optional<ReConfigChunk> reconfig =
+  std::optional<ReConfigChunk> reconfig =
       tcb_->stream_reset_handler().MakeStreamResetRequest();
   if (reconfig.has_value()) {
     SctpPacket::Builder builder = tcb_->PacketBuilder();
@@ -788,7 +788,7 @@
     packet_observer_->OnReceivedPacket(TimeMs(callbacks_.Now().ms()), data);
   }
 
-  absl::optional<SctpPacket> packet = SctpPacket::Parse(data, options_);
+  std::optional<SctpPacket> packet = SctpPacket::Parse(data, options_);
   if (!packet.has_value()) {
     // https://tools.ietf.org/html/rfc4960#section-6.8
     // "The default procedure for handling invalid SCTP packets is to
@@ -1044,7 +1044,7 @@
 
 void DcSctpSocket::HandleData(const CommonHeader& header,
                               const SctpPacket::ChunkDescriptor& descriptor) {
-  absl::optional<DataChunk> chunk = DataChunk::Parse(descriptor.data);
+  std::optional<DataChunk> chunk = DataChunk::Parse(descriptor.data);
   if (ValidateParseSuccess(chunk) && ValidateHasTCB()) {
     HandleDataCommon(*chunk);
   }
@@ -1052,7 +1052,7 @@
 
 void DcSctpSocket::HandleIData(const CommonHeader& header,
                                const SctpPacket::ChunkDescriptor& descriptor) {
-  absl::optional<IDataChunk> chunk = IDataChunk::Parse(descriptor.data);
+  std::optional<IDataChunk> chunk = IDataChunk::Parse(descriptor.data);
   if (ValidateParseSuccess(chunk) && ValidateHasTCB()) {
     HandleDataCommon(*chunk);
   }
@@ -1119,7 +1119,7 @@
 
 void DcSctpSocket::HandleInit(const CommonHeader& header,
                               const SctpPacket::ChunkDescriptor& descriptor) {
-  absl::optional<InitChunk> chunk = InitChunk::Parse(descriptor.data);
+  std::optional<InitChunk> chunk = InitChunk::Parse(descriptor.data);
   if (!ValidateParseSuccess(chunk)) {
     return;
   }
@@ -1249,7 +1249,7 @@
 void DcSctpSocket::HandleInitAck(
     const CommonHeader& header,
     const SctpPacket::ChunkDescriptor& descriptor) {
-  absl::optional<InitAckChunk> chunk = InitAckChunk::Parse(descriptor.data);
+  std::optional<InitAckChunk> chunk = InitAckChunk::Parse(descriptor.data);
   if (!ValidateParseSuccess(chunk)) {
     return;
   }
@@ -1307,14 +1307,13 @@
 void DcSctpSocket::HandleCookieEcho(
     const CommonHeader& header,
     const SctpPacket::ChunkDescriptor& descriptor) {
-  absl::optional<CookieEchoChunk> chunk =
+  std::optional<CookieEchoChunk> chunk =
       CookieEchoChunk::Parse(descriptor.data);
   if (!ValidateParseSuccess(chunk)) {
     return;
   }
 
-  absl::optional<StateCookie> cookie =
-      StateCookie::Deserialize(chunk->cookie());
+  std::optional<StateCookie> cookie = StateCookie::Deserialize(chunk->cookie());
   if (!cookie.has_value()) {
     callbacks_.OnError(ErrorKind::kParseFailed, "Failed to parse state cookie");
     return;
@@ -1449,7 +1448,7 @@
 void DcSctpSocket::HandleCookieAck(
     const CommonHeader& header,
     const SctpPacket::ChunkDescriptor& descriptor) {
-  absl::optional<CookieAckChunk> chunk = CookieAckChunk::Parse(descriptor.data);
+  std::optional<CookieAckChunk> chunk = CookieAckChunk::Parse(descriptor.data);
   if (!ValidateParseSuccess(chunk)) {
     return;
   }
@@ -1480,7 +1479,7 @@
 
 void DcSctpSocket::HandleSack(const CommonHeader& header,
                               const SctpPacket::ChunkDescriptor& descriptor) {
-  absl::optional<SackChunk> chunk = SackChunk::Parse(descriptor.data);
+  std::optional<SackChunk> chunk = SackChunk::Parse(descriptor.data);
 
   if (ValidateParseSuccess(chunk) && ValidateHasTCB()) {
     Timestamp now = callbacks_.Now();
@@ -1513,7 +1512,7 @@
 void DcSctpSocket::HandleHeartbeatRequest(
     const CommonHeader& header,
     const SctpPacket::ChunkDescriptor& descriptor) {
-  absl::optional<HeartbeatRequestChunk> chunk =
+  std::optional<HeartbeatRequestChunk> chunk =
       HeartbeatRequestChunk::Parse(descriptor.data);
 
   if (ValidateParseSuccess(chunk) && ValidateHasTCB()) {
@@ -1524,7 +1523,7 @@
 void DcSctpSocket::HandleHeartbeatAck(
     const CommonHeader& header,
     const SctpPacket::ChunkDescriptor& descriptor) {
-  absl::optional<HeartbeatAckChunk> chunk =
+  std::optional<HeartbeatAckChunk> chunk =
       HeartbeatAckChunk::Parse(descriptor.data);
 
   if (ValidateParseSuccess(chunk) && ValidateHasTCB()) {
@@ -1534,7 +1533,7 @@
 
 void DcSctpSocket::HandleAbort(const CommonHeader& header,
                                const SctpPacket::ChunkDescriptor& descriptor) {
-  absl::optional<AbortChunk> chunk = AbortChunk::Parse(descriptor.data);
+  std::optional<AbortChunk> chunk = AbortChunk::Parse(descriptor.data);
   if (ValidateParseSuccess(chunk)) {
     std::string error_string = ErrorCausesToString(chunk->error_causes());
     if (tcb_ == nullptr) {
@@ -1554,7 +1553,7 @@
 
 void DcSctpSocket::HandleError(const CommonHeader& header,
                                const SctpPacket::ChunkDescriptor& descriptor) {
-  absl::optional<ErrorChunk> chunk = ErrorChunk::Parse(descriptor.data);
+  std::optional<ErrorChunk> chunk = ErrorChunk::Parse(descriptor.data);
   if (ValidateParseSuccess(chunk)) {
     std::string error_string = ErrorCausesToString(chunk->error_causes());
     if (tcb_ == nullptr) {
@@ -1573,7 +1572,7 @@
     const CommonHeader& header,
     const SctpPacket::ChunkDescriptor& descriptor) {
   Timestamp now = callbacks_.Now();
-  absl::optional<ReConfigChunk> chunk = ReConfigChunk::Parse(descriptor.data);
+  std::optional<ReConfigChunk> chunk = ReConfigChunk::Parse(descriptor.data);
   if (ValidateParseSuccess(chunk) && ValidateHasTCB()) {
     tcb_->stream_reset_handler().HandleReConfig(*std::move(chunk));
     // Handling this response may result in outgoing stream resets finishing
@@ -1694,7 +1693,7 @@
 void DcSctpSocket::HandleForwardTsn(
     const CommonHeader& header,
     const SctpPacket::ChunkDescriptor& descriptor) {
-  absl::optional<ForwardTsnChunk> chunk =
+  std::optional<ForwardTsnChunk> chunk =
       ForwardTsnChunk::Parse(descriptor.data);
   if (ValidateParseSuccess(chunk) && ValidateHasTCB()) {
     HandleForwardTsnCommon(*chunk);
@@ -1704,7 +1703,7 @@
 void DcSctpSocket::HandleIForwardTsn(
     const CommonHeader& header,
     const SctpPacket::ChunkDescriptor& descriptor) {
-  absl::optional<IForwardTsnChunk> chunk =
+  std::optional<IForwardTsnChunk> chunk =
       IForwardTsnChunk::Parse(descriptor.data);
   if (ValidateParseSuccess(chunk) && ValidateHasTCB()) {
     HandleForwardTsnCommon(*chunk);
@@ -1788,12 +1787,12 @@
   return status;
 }
 
-absl::optional<DcSctpSocketHandoverState>
+std::optional<DcSctpSocketHandoverState>
 DcSctpSocket::GetHandoverStateAndClose() {
   CallbackDeferrer::ScopedDeferrer deferrer(callbacks_);
 
   if (!GetHandoverReadiness().IsReady()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   DcSctpSocketHandoverState state;
diff --git a/net/dcsctp/socket/dcsctp_socket.h b/net/dcsctp/socket/dcsctp_socket.h
index c65571a..f694307 100644
--- a/net/dcsctp/socket/dcsctp_socket.h
+++ b/net/dcsctp/socket/dcsctp_socket.h
@@ -103,9 +103,9 @@
   size_t buffered_amount(StreamID stream_id) const override;
   size_t buffered_amount_low_threshold(StreamID stream_id) const override;
   void SetBufferedAmountLowThreshold(StreamID stream_id, size_t bytes) override;
-  absl::optional<Metrics> GetMetrics() const override;
+  std::optional<Metrics> GetMetrics() const override;
   HandoverReadinessStatus GetHandoverReadiness() const override;
-  absl::optional<DcSctpSocketHandoverState> GetHandoverStateAndClose() override;
+  std::optional<DcSctpSocketHandoverState> GetHandoverStateAndClose() override;
   SctpImplementation peer_implementation() const override {
     return metrics_.peer_implementation;
   }
@@ -191,7 +191,7 @@
   // Returns true if the parsing of a chunk of type `T` succeeded. If it didn't,
   // it reports an error and returns false.
   template <class T>
-  bool ValidateParseSuccess(const absl::optional<T>& c) {
+  bool ValidateParseSuccess(const std::optional<T>& c) {
     if (c.has_value()) {
       return true;
     }
diff --git a/net/dcsctp/socket/dcsctp_socket_network_test.cc b/net/dcsctp/socket/dcsctp_socket_network_test.cc
index f497cfa..679ed17 100644
--- a/net/dcsctp/socket/dcsctp_socket_network_test.cc
+++ b/net/dcsctp/socket/dcsctp_socket_network_test.cc
@@ -10,13 +10,13 @@
 #include <cstdint>
 #include <deque>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/task_queue/pending_task_safety_flag.h"
 #include "api/task_queue/task_queue_base.h"
@@ -243,7 +243,7 @@
                           std::vector<uint8_t>(kLargePayloadSize)),
             send_options);
 
-        send_options.max_retransmissions = absl::nullopt;
+        send_options.max_retransmissions = std::nullopt;
         sctp_socket_.Send(
             DcSctpMessage(kStreamId, kPpid,
                           std::vector<uint8_t>(kSmallPayloadSize)),
@@ -252,12 +252,12 @@
     }
   }
 
-  absl::optional<DcSctpMessage> ConsumeReceivedMessage() {
+  std::optional<DcSctpMessage> ConsumeReceivedMessage() {
     if (!last_received_message_.has_value()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     DcSctpMessage ret = *std::move(last_received_message_);
-    last_received_message_ = absl::nullopt;
+    last_received_message_ = std::nullopt;
     return ret;
   }
 
@@ -317,7 +317,7 @@
   webrtc::Random random_;
   DcSctpSocket sctp_socket_;
   size_t received_bytes_ = 0;
-  absl::optional<DcSctpMessage> last_received_message_;
+  std::optional<DcSctpMessage> last_received_message_;
   Timestamp last_bandwidth_printout_;
   // Per-second received bitrates, in Mbps
   std::vector<double> received_bitrate_mbps_;
diff --git a/net/dcsctp/socket/dcsctp_socket_test.cc b/net/dcsctp/socket/dcsctp_socket_test.cc
index 7266dc8..cea30a9 100644
--- a/net/dcsctp/socket/dcsctp_socket_test.cc
+++ b/net/dcsctp/socket/dcsctp_socket_test.cc
@@ -13,6 +13,7 @@
 #include <cstdint>
 #include <deque>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -20,7 +21,6 @@
 #include "absl/flags/flag.h"
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/handover_testing.h"
 #include "net/dcsctp/common/math.h"
@@ -84,7 +84,7 @@
 constexpr DcSctpOptions kDefaultOptions;
 
 MATCHER_P(HasChunks, chunks, "") {
-  absl::optional<SctpPacket> packet = SctpPacket::Parse(arg, kDefaultOptions);
+  std::optional<SctpPacket> packet = SctpPacket::Parse(arg, kDefaultOptions);
   if (!packet.has_value()) {
     *result_listener << "data didn't parse as an SctpPacket";
     return false;
@@ -103,7 +103,7 @@
     return false;
   }
 
-  absl::optional<DataChunk> chunk = DataChunk::Parse(arg.data);
+  std::optional<DataChunk> chunk = DataChunk::Parse(arg.data);
   if (!chunk.has_value()) {
     *result_listener << "The chunk didn't parse as a data chunk";
     return false;
@@ -118,7 +118,7 @@
     return false;
   }
 
-  absl::optional<SackChunk> chunk = SackChunk::Parse(arg.data);
+  std::optional<SackChunk> chunk = SackChunk::Parse(arg.data);
   if (!chunk.has_value()) {
     *result_listener << "The chunk didn't parse as a sack chunk";
     return false;
@@ -133,7 +133,7 @@
     return false;
   }
 
-  absl::optional<ReConfigChunk> chunk = ReConfigChunk::Parse(arg.data);
+  std::optional<ReConfigChunk> chunk = ReConfigChunk::Parse(arg.data);
   if (!chunk.has_value()) {
     *result_listener << "The chunk didn't parse as a re-config chunk";
     return false;
@@ -148,7 +148,7 @@
     return false;
   }
 
-  absl::optional<HeartbeatAckChunk> chunk = HeartbeatAckChunk::Parse(arg.data);
+  std::optional<HeartbeatAckChunk> chunk = HeartbeatAckChunk::Parse(arg.data);
   if (!chunk.has_value()) {
     *result_listener << "The chunk didn't parse as a HeartbeatAckChunk";
     return false;
@@ -163,7 +163,7 @@
     return false;
   }
 
-  absl::optional<HeartbeatRequestChunk> chunk =
+  std::optional<HeartbeatRequestChunk> chunk =
       HeartbeatRequestChunk::Parse(arg.data);
   if (!chunk.has_value()) {
     *result_listener << "The chunk didn't parse as a HeartbeatRequestChunk";
@@ -185,7 +185,7 @@
     return false;
   }
 
-  absl::optional<OutgoingSSNResetRequestParameter> parameter =
+  std::optional<OutgoingSSNResetRequestParameter> parameter =
       OutgoingSSNResetRequestParameter::Parse(arg.data);
   if (!parameter.has_value()) {
     *result_listener
@@ -203,7 +203,7 @@
     return false;
   }
 
-  absl::optional<ReconfigurationResponseParameter> parameter =
+  std::optional<ReconfigurationResponseParameter> parameter =
       ReconfigurationResponseParameter::Parse(arg.data);
   if (!parameter.has_value()) {
     *result_listener
@@ -264,7 +264,7 @@
 
 void RunTimers(SocketUnderTest& s) {
   for (;;) {
-    absl::optional<TimeoutID> timeout_id = s.cb.GetNextExpiredTimeout();
+    std::optional<TimeoutID> timeout_id = s.cb.GetNextExpiredTimeout();
     if (!timeout_id.has_value()) {
       break;
     }
@@ -324,7 +324,7 @@
   if (!is_closed) {
     EXPECT_CALL(sut->cb, OnClosed).Times(1);
   }
-  absl::optional<DcSctpSocketHandoverState> handover_state =
+  std::optional<DcSctpSocketHandoverState> handover_state =
       sut->socket.GetHandoverStateAndClose();
   EXPECT_TRUE(handover_state.has_value());
   g_handover_state_transformer_for_test(&*handover_state);
@@ -340,7 +340,7 @@
 std::vector<uint32_t> GetReceivedMessagePpids(SocketUnderTest& z) {
   std::vector<uint32_t> ppids;
   for (;;) {
-    absl::optional<DcSctpMessage> msg = z.cb.ConsumeReceivedMessage();
+    std::optional<DcSctpMessage> msg = z.cb.ConsumeReceivedMessage();
     if (!msg.has_value()) {
       break;
     }
@@ -382,7 +382,7 @@
     a.socket.Send(DcSctpMessage(StreamID(1), PPID(53), {1, 2}), kSendOptions);
     ExchangeMessages(a, *z);
 
-    absl::optional<DcSctpMessage> msg = z->cb.ConsumeReceivedMessage();
+    std::optional<DcSctpMessage> msg = z->cb.ConsumeReceivedMessage();
     ASSERT_TRUE(msg.has_value());
     EXPECT_EQ(msg->stream_id(), StreamID(1));
   }
@@ -792,7 +792,7 @@
   EXPECT_EQ(a.socket.state(), SocketState::kConnected);
   EXPECT_EQ(z.socket.state(), SocketState::kConnected);
 
-  absl::optional<DcSctpMessage> msg = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg.has_value());
   EXPECT_EQ(msg->stream_id(), StreamID(1));
 }
@@ -806,7 +806,7 @@
   a.socket.Send(DcSctpMessage(StreamID(1), PPID(53), {1, 2}), kSendOptions);
   z.socket.ReceivePacket(a.cb.ConsumeSentPacket());
 
-  absl::optional<DcSctpMessage> msg = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg.has_value());
   EXPECT_EQ(msg->stream_id(), StreamID(1));
 }
@@ -826,7 +826,7 @@
 
   z->socket.ReceivePacket(a.cb.ConsumeSentPacket());
 
-  absl::optional<DcSctpMessage> msg = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg = z->cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg.has_value());
   EXPECT_EQ(msg->stream_id(), StreamID(1));
 
@@ -851,7 +851,7 @@
   // Retransmit and handle the rest
   ExchangeMessages(a, *z);
 
-  absl::optional<DcSctpMessage> msg = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg = z->cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg.has_value());
   EXPECT_EQ(msg->stream_id(), StreamID(1));
   EXPECT_THAT(msg->payload(), testing::ElementsAreArray(payload));
@@ -1051,7 +1051,7 @@
   a.socket.Send(DcSctpMessage(StreamID(1), PPID(53), {1, 2}), {});
   z->socket.ReceivePacket(a.cb.ConsumeSentPacket());
 
-  absl::optional<DcSctpMessage> msg = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg = z->cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg.has_value());
   EXPECT_EQ(msg->stream_id(), StreamID(1));
 
@@ -1100,11 +1100,11 @@
   // Handle SACK
   a.socket.ReceivePacket(z->cb.ConsumeSentPacket());
 
-  absl::optional<DcSctpMessage> msg1 = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg1 = z->cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg1.has_value());
   EXPECT_EQ(msg1->stream_id(), StreamID(1));
 
-  absl::optional<DcSctpMessage> msg2 = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg2 = z->cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg2.has_value());
   EXPECT_EQ(msg2->stream_id(), StreamID(1));
 
@@ -1182,19 +1182,19 @@
   a.socket.ReceivePacket(z->cb.ConsumeSentPacket());
 
   // Receive all messages.
-  absl::optional<DcSctpMessage> msg1 = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg1 = z->cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg1.has_value());
   EXPECT_EQ(msg1->stream_id(), StreamID(1));
 
-  absl::optional<DcSctpMessage> msg2 = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg2 = z->cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg2.has_value());
   EXPECT_EQ(msg2->stream_id(), StreamID(1));
 
-  absl::optional<DcSctpMessage> msg3 = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg3 = z->cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg3.has_value());
   EXPECT_EQ(msg3->stream_id(), StreamID(3));
 
-  absl::optional<DcSctpMessage> msg4 = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg4 = z->cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg4.has_value());
   EXPECT_EQ(msg4->stream_id(), StreamID(3));
 
@@ -1253,7 +1253,7 @@
   // have the wrong verification tag, those will yield errors.
   ExchangeMessages(a, z2);
 
-  absl::optional<DcSctpMessage> msg = z2.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg = z2.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg.has_value());
   EXPECT_EQ(msg->stream_id(), StreamID(1));
   EXPECT_THAT(msg->payload(), testing::ElementsAreArray(payload));
@@ -1304,15 +1304,15 @@
   // Which will trigger a SACK
   a.socket.ReceivePacket(z->cb.ConsumeSentPacket());
 
-  absl::optional<DcSctpMessage> msg1 = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg1 = z->cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg1.has_value());
   EXPECT_EQ(msg1->ppid(), PPID(51));
 
-  absl::optional<DcSctpMessage> msg2 = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg2 = z->cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg2.has_value());
   EXPECT_EQ(msg2->ppid(), PPID(53));
 
-  absl::optional<DcSctpMessage> msg3 = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg3 = z->cb.ConsumeReceivedMessage();
   EXPECT_FALSE(msg3.has_value());
 
   MaybeHandoverSocketAndSendMessage(a, std::move(z));
@@ -1395,7 +1395,7 @@
 
   ExchangeMessages(a, *z);
 
-  absl::optional<DcSctpMessage> msg1 = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg1 = z->cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg1.has_value());
   EXPECT_EQ(msg1->ppid(), PPID(54));
 
@@ -2154,7 +2154,7 @@
 
   z = HandoverSocket(std::move(z));
 
-  absl::optional<DcSctpMessage> msg;
+  std::optional<DcSctpMessage> msg;
 
   RTC_LOG(LS_INFO) << "Sending A #1";
 
@@ -2241,7 +2241,7 @@
   ExchangeMessages(a, *z);
 
   // The Z socket should receive the second message, but not the first.
-  absl::optional<DcSctpMessage> msg = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg = z->cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg.has_value());
   EXPECT_EQ(msg->ppid(), PPID(52));
 
@@ -2380,13 +2380,13 @@
   ExchangeMessages(a, z);
 
   // Receive these messages
-  absl::optional<DcSctpMessage> msg1 = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg1 = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg1.has_value());
   EXPECT_EQ(msg1->stream_id(), StreamID(1));
-  absl::optional<DcSctpMessage> msg2 = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg2 = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg2.has_value());
   EXPECT_EQ(msg2->stream_id(), StreamID(2));
-  absl::optional<DcSctpMessage> msg3 = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg3 = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg3.has_value());
   EXPECT_EQ(msg3->stream_id(), StreamID(3));
 
@@ -2415,13 +2415,13 @@
   ExchangeMessages(a, z);
 
   // Receive these messages
-  absl::optional<DcSctpMessage> msg4 = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg4 = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg4.has_value());
   EXPECT_EQ(msg4->stream_id(), StreamID(1));
-  absl::optional<DcSctpMessage> msg5 = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg5 = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg5.has_value());
   EXPECT_EQ(msg5->stream_id(), StreamID(2));
-  absl::optional<DcSctpMessage> msg6 = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg6 = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg6.has_value());
   EXPECT_EQ(msg6->stream_id(), StreamID(3));
 }
@@ -2527,7 +2527,7 @@
 
   std::vector<uint32_t> received_ppids;
   for (;;) {
-    absl::optional<DcSctpMessage> msg = z.cb.ConsumeReceivedMessage();
+    std::optional<DcSctpMessage> msg = z.cb.ConsumeReceivedMessage();
     if (!msg.has_value()) {
       break;
     }
@@ -2800,13 +2800,13 @@
   z.socket.ReceivePacket(data2);
   z.socket.ReceivePacket(data3);
 
-  absl::optional<DcSctpMessage> msg1 = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg1 = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg1.has_value());
   EXPECT_EQ(msg1->stream_id(), StreamID(1));
   EXPECT_EQ(msg1->ppid(), PPID(53));
   EXPECT_EQ(msg1->payload().size(), kTwoFragmentsSize);
 
-  absl::optional<DcSctpMessage> msg2 = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg2 = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg2.has_value());
   EXPECT_EQ(msg2->stream_id(), StreamID(1));
   EXPECT_EQ(msg2->ppid(), PPID(54));
@@ -2855,7 +2855,7 @@
                 {});
   ExchangeMessages(a, z);
 
-  absl::optional<DcSctpMessage> msg3 = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg3 = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg3.has_value());
   EXPECT_EQ(msg3->stream_id(), StreamID(1));
   EXPECT_EQ(msg3->ppid(), PPID(55));
@@ -2883,13 +2883,13 @@
   EXPECT_CALL(z.cb, OnIncomingStreamsReset(ElementsAre(StreamID(1))));
   ExchangeMessages(a, z);
 
-  absl::optional<DcSctpMessage> msg1 = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg1 = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg1.has_value());
   EXPECT_EQ(msg1->stream_id(), StreamID(1));
   EXPECT_EQ(msg1->ppid(), PPID(51));
   EXPECT_EQ(msg1->payload().size(), kSmallMessageSize);
 
-  absl::optional<DcSctpMessage> msg2 = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg2 = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg2.has_value());
   EXPECT_EQ(msg2->stream_id(), StreamID(1));
   EXPECT_EQ(msg2->ppid(), PPID(52));
@@ -3057,11 +3057,11 @@
     }
   }
 
-  absl::optional<DcSctpMessage> msg1 = z->cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg1 = z->cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg1.has_value());
   EXPECT_THAT(msg1->payload(), SizeIs(kLargeMessageSize));
 
-  absl::optional<DcSctpMessage> msg2 = a.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg2 = a.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg2.has_value());
   EXPECT_THAT(msg2->payload(), SizeIs(kLargeMessageSize));
 
@@ -3223,7 +3223,7 @@
   // Then let the rest continue.
   ExchangeMessages(a, z);
 
-  absl::optional<DcSctpMessage> msg = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg.has_value());
   EXPECT_EQ(msg->stream_id(), StreamID(1));
   EXPECT_THAT(msg->payload(), SizeIs(kLargeMessageSize));
@@ -3260,7 +3260,7 @@
   // Then let the rest continue.
   ExchangeMessages(a, z);
 
-  absl::optional<DcSctpMessage> msg = z.cb.ConsumeReceivedMessage();
+  std::optional<DcSctpMessage> msg = z.cb.ConsumeReceivedMessage();
   ASSERT_TRUE(msg.has_value());
   EXPECT_EQ(msg->stream_id(), StreamID(1));
   EXPECT_THAT(msg->payload(), SizeIs(kLargeMessageSize));
diff --git a/net/dcsctp/socket/heartbeat_handler.cc b/net/dcsctp/socket/heartbeat_handler.cc
index 31211e0..d5ff6fc 100644
--- a/net/dcsctp/socket/heartbeat_handler.cc
+++ b/net/dcsctp/socket/heartbeat_handler.cc
@@ -13,13 +13,13 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/functional/bind_front.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/units/time_delta.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
@@ -65,12 +65,12 @@
     return data;
   }
 
-  static absl::optional<HeartbeatInfo> Deserialize(
+  static std::optional<HeartbeatInfo> Deserialize(
       rtc::ArrayView<const uint8_t> data) {
     if (data.size() != kBufferSize) {
       RTC_LOG(LS_WARNING) << "Invalid heartbeat info: " << data.size()
                           << " bytes";
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     BoundedByteReader<kBufferSize> reader(data);
@@ -142,14 +142,14 @@
 
 void HeartbeatHandler::HandleHeartbeatAck(HeartbeatAckChunk chunk) {
   timeout_timer_->Stop();
-  absl::optional<HeartbeatInfoParameter> info_param = chunk.info();
+  std::optional<HeartbeatInfoParameter> info_param = chunk.info();
   if (!info_param.has_value()) {
     ctx_->callbacks().OnError(
         ErrorKind::kParseFailed,
         "Failed to parse HEARTBEAT-ACK; No Heartbeat Info parameter");
     return;
   }
-  absl::optional<HeartbeatInfo> info =
+  std::optional<HeartbeatInfo> info =
       HeartbeatInfo::Deserialize(info_param->info());
   if (!info.has_value()) {
     ctx_->callbacks().OnError(ErrorKind::kParseFailed,
diff --git a/net/dcsctp/socket/heartbeat_handler_test.cc b/net/dcsctp/socket/heartbeat_handler_test.cc
index b7f3a60..8f6af0c 100644
--- a/net/dcsctp/socket/heartbeat_handler_test.cc
+++ b/net/dcsctp/socket/heartbeat_handler_test.cc
@@ -56,7 +56,7 @@
   void AdvanceTime(webrtc::TimeDelta duration) {
     callbacks_.AdvanceTime(duration);
     for (;;) {
-      absl::optional<TimeoutID> timeout_id = callbacks_.GetNextExpiredTimeout();
+      std::optional<TimeoutID> timeout_id = callbacks_.GetNextExpiredTimeout();
       if (!timeout_id.has_value()) {
         break;
       }
diff --git a/net/dcsctp/socket/mock_context.h b/net/dcsctp/socket/mock_context.h
index bbd9cd1..5980169 100644
--- a/net/dcsctp/socket/mock_context.h
+++ b/net/dcsctp/socket/mock_context.h
@@ -11,9 +11,9 @@
 #define NET_DCSCTP_SOCKET_MOCK_CONTEXT_H_
 
 #include <cstdint>
+#include <optional>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "net/dcsctp/packet/sctp_packet.h"
 #include "net/dcsctp/public/dcsctp_options.h"
 #include "net/dcsctp/public/dcsctp_socket.h"
diff --git a/net/dcsctp/socket/mock_dcsctp_socket_callbacks.h b/net/dcsctp/socket/mock_dcsctp_socket_callbacks.h
index 972e547..827609f 100644
--- a/net/dcsctp/socket/mock_dcsctp_socket_callbacks.h
+++ b/net/dcsctp/socket/mock_dcsctp_socket_callbacks.h
@@ -13,12 +13,12 @@
 #include <cstdint>
 #include <deque>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/task_queue/task_queue_base.h"
 #include "net/dcsctp/public/dcsctp_message.h"
@@ -150,9 +150,9 @@
     sent_packets_.pop_front();
     return ret;
   }
-  absl::optional<DcSctpMessage> ConsumeReceivedMessage() {
+  std::optional<DcSctpMessage> ConsumeReceivedMessage() {
     if (received_messages_.empty()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     DcSctpMessage ret = std::move(received_messages_.front());
     received_messages_.pop_front();
@@ -162,7 +162,7 @@
   void AdvanceTime(webrtc::TimeDelta duration) { now_ = now_ + duration; }
   void SetTime(webrtc::Timestamp now) { now_ = now; }
 
-  absl::optional<TimeoutID> GetNextExpiredTimeout() {
+  std::optional<TimeoutID> GetNextExpiredTimeout() {
     return timeout_manager_.GetNextExpiredTimeout();
   }
 
diff --git a/net/dcsctp/socket/state_cookie.cc b/net/dcsctp/socket/state_cookie.cc
index 1e7c43f..31488c3 100644
--- a/net/dcsctp/socket/state_cookie.cc
+++ b/net/dcsctp/socket/state_cookie.cc
@@ -10,9 +10,9 @@
 #include "net/dcsctp/socket/state_cookie.h"
 
 #include <cstdint>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/bounded_byte_reader.h"
 #include "net/dcsctp/packet/bounded_byte_writer.h"
@@ -48,12 +48,12 @@
   return cookie;
 }
 
-absl::optional<StateCookie> StateCookie::Deserialize(
+std::optional<StateCookie> StateCookie::Deserialize(
     rtc::ArrayView<const uint8_t> cookie) {
   if (cookie.size() != kCookieSize) {
     RTC_DLOG(LS_WARNING) << "Invalid state cookie: " << cookie.size()
                          << " bytes";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   BoundedByteReader<kCookieSize> buffer(cookie);
@@ -61,7 +61,7 @@
   uint32_t magic2 = buffer.Load32<4>();
   if (magic1 != kMagic1 || magic2 != kMagic2) {
     RTC_DLOG(LS_WARNING) << "Invalid state cookie; wrong magic";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   VerificationTag peer_tag(buffer.Load32<8>());
diff --git a/net/dcsctp/socket/state_cookie.h b/net/dcsctp/socket/state_cookie.h
index 734d64d..731a68e 100644
--- a/net/dcsctp/socket/state_cookie.h
+++ b/net/dcsctp/socket/state_cookie.h
@@ -11,9 +11,9 @@
 #define NET_DCSCTP_SOCKET_STATE_COOKIE_H_
 
 #include <cstdint>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/internal_types.h"
 #include "net/dcsctp/socket/capabilities.h"
@@ -47,8 +47,8 @@
   // Returns a serialized version of this cookie.
   std::vector<uint8_t> Serialize();
 
-  // Deserializes the cookie, and returns absl::nullopt if that failed.
-  static absl::optional<StateCookie> Deserialize(
+  // Deserializes the cookie, and returns std::nullopt if that failed.
+  static std::optional<StateCookie> Deserialize(
       rtc::ArrayView<const uint8_t> cookie);
 
   VerificationTag peer_tag() const { return peer_tag_; }
diff --git a/net/dcsctp/socket/stream_reset_handler.cc b/net/dcsctp/socket/stream_reset_handler.cc
index fafb993..322ecd5 100644
--- a/net/dcsctp/socket/stream_reset_handler.cc
+++ b/net/dcsctp/socket/stream_reset_handler.cc
@@ -11,10 +11,10 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/units/time_delta.h"
 #include "net/dcsctp/common/internal_types.h"
@@ -84,10 +84,10 @@
   return false;
 }
 
-absl::optional<std::vector<ReconfigurationResponseParameter>>
+std::optional<std::vector<ReconfigurationResponseParameter>>
 StreamResetHandler::Process(const ReConfigChunk& chunk) {
   if (!Validate(chunk)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<ReconfigurationResponseParameter> responses;
@@ -112,7 +112,7 @@
 }
 
 void StreamResetHandler::HandleReConfig(ReConfigChunk chunk) {
-  absl::optional<std::vector<ReconfigurationResponseParameter>> responses =
+  std::optional<std::vector<ReconfigurationResponseParameter>> responses =
       Process(chunk);
 
   if (!responses.has_value()) {
@@ -168,7 +168,7 @@
 void StreamResetHandler::HandleResetOutgoing(
     const ParameterDescriptor& descriptor,
     std::vector<ReconfigurationResponseParameter>& responses) {
-  absl::optional<OutgoingSSNResetRequestParameter> req =
+  std::optional<OutgoingSSNResetRequestParameter> req =
       OutgoingSSNResetRequestParameter::Parse(descriptor.data);
   if (!req.has_value()) {
     ctx_->callbacks().OnError(ErrorKind::kParseFailed,
@@ -222,7 +222,7 @@
 void StreamResetHandler::HandleResetIncoming(
     const ParameterDescriptor& descriptor,
     std::vector<ReconfigurationResponseParameter>& responses) {
-  absl::optional<IncomingSSNResetRequestParameter> req =
+  std::optional<IncomingSSNResetRequestParameter> req =
       IncomingSSNResetRequestParameter::Parse(descriptor.data);
   if (!req.has_value()) {
     ctx_->callbacks().OnError(ErrorKind::kParseFailed,
@@ -242,7 +242,7 @@
 }
 
 void StreamResetHandler::HandleResponse(const ParameterDescriptor& descriptor) {
-  absl::optional<ReconfigurationResponseParameter> resp =
+  std::optional<ReconfigurationResponseParameter> resp =
       ReconfigurationResponseParameter::Parse(descriptor.data);
   if (!resp.has_value()) {
     ctx_->callbacks().OnError(
@@ -266,7 +266,7 @@
                          sb << *stream_id;
                        });
         ctx_->callbacks().OnStreamsResetPerformed(current_request_->streams());
-        current_request_ = absl::nullopt;
+        current_request_ = std::nullopt;
         retransmission_queue_->CommitResetStreams();
         break;
       case ResponseResult::kInProgress:
@@ -296,20 +296,20 @@
                        });
         ctx_->callbacks().OnStreamsResetFailed(current_request_->streams(),
                                                ToString(resp->result()));
-        current_request_ = absl::nullopt;
+        current_request_ = std::nullopt;
         retransmission_queue_->RollbackResetStreams();
         break;
     }
   }
 }
 
-absl::optional<ReConfigChunk> StreamResetHandler::MakeStreamResetRequest() {
+std::optional<ReConfigChunk> StreamResetHandler::MakeStreamResetRequest() {
   // Only send stream resets if there are streams to reset, and no current
   // ongoing request (there can only be one at a time), and if the stream
   // can be reset.
   if (current_request_.has_value() ||
       !retransmission_queue_->HasStreamsReadyToBeReset()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   current_request_.emplace(retransmission_queue_->last_assigned_tsn(),
diff --git a/net/dcsctp/socket/stream_reset_handler.h b/net/dcsctp/socket/stream_reset_handler.h
index 77e8f3b..ac0deb7 100644
--- a/net/dcsctp/socket/stream_reset_handler.h
+++ b/net/dcsctp/socket/stream_reset_handler.h
@@ -12,13 +12,13 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/functional/bind_front.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/units/time_delta.h"
 #include "net/dcsctp/common/internal_types.h"
@@ -103,10 +103,10 @@
   void ResetStreams(rtc::ArrayView<const StreamID> outgoing_streams);
 
   // Creates a Reset Streams request that must be sent if returned. Will start
-  // the reconfig timer. Will return absl::nullopt if there is no need to
+  // the reconfig timer. Will return std::nullopt if there is no need to
   // create a request (no streams to reset) or if there already is an ongoing
   // stream reset request that hasn't completed yet.
-  absl::optional<ReConfigChunk> MakeStreamResetRequest();
+  std::optional<ReConfigChunk> MakeStreamResetRequest();
 
   // Called when handling and incoming RE-CONFIG chunk.
   void HandleReConfig(ReConfigChunk chunk);
@@ -124,7 +124,7 @@
   class CurrentRequest {
    public:
     CurrentRequest(TSN sender_last_assigned_tsn, std::vector<StreamID> streams)
-        : req_seq_nbr_(absl::nullopt),
+        : req_seq_nbr_(std::nullopt),
           sender_last_assigned_tsn_(sender_last_assigned_tsn),
           streams_(std::move(streams)) {}
 
@@ -152,7 +152,7 @@
     // If the receiver can't apply the request yet (and answered "In Progress"),
     // this will be called to prepare the request to be retransmitted at a later
     // time.
-    void PrepareRetransmission() { req_seq_nbr_ = absl::nullopt; }
+    void PrepareRetransmission() { req_seq_nbr_ = std::nullopt; }
 
     // If the request hasn't been sent yet, this assigns it a request number.
     void PrepareToSend(ReconfigRequestSN new_req_seq_nbr) {
@@ -164,7 +164,7 @@
     // has been prepared, but has not yet been sent. This is typically used when
     // the peer responded "in progress" and the same request (but a different
     // request number) must be sent again.
-    absl::optional<ReconfigRequestSN> req_seq_nbr_;
+    std::optional<ReconfigRequestSN> req_seq_nbr_;
     // The sender's (that's us) last assigned TSN, from the retransmission
     // queue.
     TSN sender_last_assigned_tsn_;
@@ -176,9 +176,9 @@
   bool Validate(const ReConfigChunk& chunk);
 
   // Processes a stream stream reconfiguration chunk and may either return
-  // absl::nullopt (on protocol errors), or a list of responses - either 0, 1
+  // std::nullopt (on protocol errors), or a list of responses - either 0, 1
   // or 2.
-  absl::optional<std::vector<ReconfigurationResponseParameter>> Process(
+  std::optional<std::vector<ReconfigurationResponseParameter>> Process(
       const ReConfigChunk& chunk);
 
   // Creates the actual RE-CONFIG chunk. A request (which set `current_request`)
@@ -226,7 +226,7 @@
   ReconfigRequestSN next_outgoing_req_seq_nbr_;
 
   // The current stream request operation.
-  absl::optional<CurrentRequest> current_request_;
+  std::optional<CurrentRequest> current_request_;
 
   // For incoming requests - last processed request sequence number.
   UnwrappedReconfigRequestSn last_processed_req_seq_nbr_;
diff --git a/net/dcsctp/socket/stream_reset_handler_test.cc b/net/dcsctp/socket/stream_reset_handler_test.cc
index a5a326d..480acbe 100644
--- a/net/dcsctp/socket/stream_reset_handler_test.cc
+++ b/net/dcsctp/socket/stream_reset_handler_test.cc
@@ -12,10 +12,10 @@
 #include <array>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/task_queue/task_queue_base.h"
 #include "net/dcsctp/common/handover_testing.h"
@@ -131,7 +131,7 @@
   void AdvanceTime(TimeDelta duration) {
     callbacks_.AdvanceTime(duration);
     for (;;) {
-      absl::optional<TimeoutID> timeout_id = callbacks_.GetNextExpiredTimeout();
+      std::optional<TimeoutID> timeout_id = callbacks_.GetNextExpiredTimeout();
       if (!timeout_id.has_value()) {
         break;
       }
@@ -152,7 +152,7 @@
     }
 
     std::vector<ReconfigurationResponseParameter> responses;
-    absl::optional<SctpPacket> p = SctpPacket::Parse(payload, DcSctpOptions());
+    std::optional<SctpPacket> p = SctpPacket::Parse(payload, DcSctpOptions());
     if (!p.has_value()) {
       EXPECT_TRUE(false);
       return {};
@@ -161,7 +161,7 @@
       EXPECT_TRUE(false);
       return {};
     }
-    absl::optional<ReConfigChunk> response_chunk =
+    std::optional<ReConfigChunk> response_chunk =
         ReConfigChunk::Parse(p->descriptors()[0].data);
     if (!response_chunk.has_value()) {
       EXPECT_TRUE(false);
@@ -169,7 +169,7 @@
     }
     for (const auto& desc : response_chunk->parameters().descriptors()) {
       if (desc.type == ReconfigurationResponseParameter::kType) {
-        absl::optional<ReconfigurationResponseParameter> response =
+        std::optional<ReconfigurationResponseParameter> response =
             ReconfigurationResponseParameter::Parse(desc.data);
         if (!response.has_value()) {
           EXPECT_TRUE(false);
@@ -482,7 +482,7 @@
   EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
       .WillOnce(Return(std::vector<StreamID>({StreamID(42)})));
 
-  absl::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
+  std::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
   ASSERT_TRUE(reconfig.has_value());
   ASSERT_HAS_VALUE_AND_ASSIGN(
       OutgoingSSNResetRequestParameter req,
@@ -510,7 +510,7 @@
       .WillOnce(Return(
           std::vector<StreamID>({StreamID(40), StreamID(41), StreamID(42),
                                  StreamID(43), StreamID(44)})));
-  absl::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
+  std::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
   ASSERT_TRUE(reconfig.has_value());
   ASSERT_HAS_VALUE_AND_ASSIGN(
       OutgoingSSNResetRequestParameter req,
@@ -546,7 +546,7 @@
   EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
       .WillOnce(Return(std::vector<StreamID>({StreamID(42)})));
 
-  absl::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
+  std::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
   ASSERT_TRUE(reconfig.has_value());
   ASSERT_HAS_VALUE_AND_ASSIGN(
       OutgoingSSNResetRequestParameter req,
@@ -574,7 +574,7 @@
   EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
       .WillOnce(Return(std::vector<StreamID>({StreamID(42)})));
 
-  absl::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
+  std::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
   ASSERT_TRUE(reconfig.has_value());
   ASSERT_HAS_VALUE_AND_ASSIGN(
       OutgoingSSNResetRequestParameter req,
@@ -604,7 +604,7 @@
   EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
       .WillOnce(Return(std::vector<StreamID>({kStreamToReset})));
 
-  absl::optional<ReConfigChunk> reconfig1 = handler_->MakeStreamResetRequest();
+  std::optional<ReConfigChunk> reconfig1 = handler_->MakeStreamResetRequest();
   ASSERT_TRUE(reconfig1.has_value());
   ASSERT_HAS_VALUE_AND_ASSIGN(
       OutgoingSSNResetRequestParameter req1,
@@ -656,7 +656,7 @@
   EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
       .WillOnce(Return(std::vector<StreamID>({StreamID(42)})));
 
-  absl::optional<ReConfigChunk> reconfig1 = handler_->MakeStreamResetRequest();
+  std::optional<ReConfigChunk> reconfig1 = handler_->MakeStreamResetRequest();
   ASSERT_TRUE(reconfig1.has_value());
   ASSERT_HAS_VALUE_AND_ASSIGN(
       OutgoingSSNResetRequestParameter req1,
@@ -671,7 +671,7 @@
   EXPECT_CALL(producer_, PrepareResetStream(StreamID(43)));
   StreamID stream_ids[] = {StreamID(41), StreamID(43)};
   handler_->ResetStreams(stream_ids);
-  EXPECT_EQ(handler_->MakeStreamResetRequest(), absl::nullopt);
+  EXPECT_EQ(handler_->MakeStreamResetRequest(), std::nullopt);
 
   Parameters::Builder builder;
   builder.Add(ReconfigurationResponseParameter(
@@ -691,7 +691,7 @@
   EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
       .WillOnce(Return(std::vector<StreamID>({StreamID(41), StreamID(43)})));
 
-  absl::optional<ReConfigChunk> reconfig2 = handler_->MakeStreamResetRequest();
+  std::optional<ReConfigChunk> reconfig2 = handler_->MakeStreamResetRequest();
   ASSERT_TRUE(reconfig2.has_value());
   ASSERT_HAS_VALUE_AND_ASSIGN(
       OutgoingSSNResetRequestParameter req2,
@@ -811,7 +811,7 @@
   EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
       .WillOnce(Return(std::vector<StreamID>({StreamID(42)})));
 
-  absl::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
+  std::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
   ASSERT_TRUE(reconfig.has_value());
   ASSERT_HAS_VALUE_AND_ASSIGN(
       OutgoingSSNResetRequestParameter req,
diff --git a/net/dcsctp/socket/transmission_control_block.cc b/net/dcsctp/socket/transmission_control_block.cc
index cf62c15..26ca6f6 100644
--- a/net/dcsctp/socket/transmission_control_block.cc
+++ b/net/dcsctp/socket/transmission_control_block.cc
@@ -12,11 +12,11 @@
 #include <algorithm>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/units/time_delta.h"
 #include "net/dcsctp/packet/chunk/data_chunk.h"
 #include "net/dcsctp/packet/chunk/forward_tsn_chunk.h"
@@ -66,7 +66,7 @@
           absl::bind_front(&TransmissionControlBlock::OnRtxTimerExpiry, this),
           TimerOptions(options.rto_initial.ToTimeDelta(),
                        TimerBackoffAlgorithm::kExponential,
-                       /*max_restarts=*/absl::nullopt,
+                       /*max_restarts=*/std::nullopt,
                        options.max_timer_backoff_duration.has_value()
                            ? options.max_timer_backoff_duration->ToTimeDelta()
                            : TimeDelta::PlusInfinity()))),
@@ -233,7 +233,7 @@
             reassembly_queue_.remaining_bytes()));
       }
       MaybeSendForwardTsn(builder, now);
-      absl::optional<ReConfigChunk> reconfig =
+      std::optional<ReConfigChunk> reconfig =
           stream_reset_handler_.MakeStreamResetRequest();
       if (reconfig.has_value()) {
         builder.Add(*reconfig);
diff --git a/net/dcsctp/socket/transmission_control_block.h b/net/dcsctp/socket/transmission_control_block.h
index f8b2445..e4c5821 100644
--- a/net/dcsctp/socket/transmission_control_block.h
+++ b/net/dcsctp/socket/transmission_control_block.h
@@ -120,7 +120,7 @@
 
   // Called when the COOKIE ACK chunk has been received, to allow further
   // packets to be sent.
-  void ClearCookieEchoChunk() { cookie_echo_chunk_ = absl::nullopt; }
+  void ClearCookieEchoChunk() { cookie_echo_chunk_ = std::nullopt; }
 
   bool has_cookie_echo_chunk() const { return cookie_echo_chunk_.has_value(); }
 
@@ -187,7 +187,7 @@
   // including a COOKIE ECHO). So if `cookie_echo_chunk_` is present, the
   // SendBufferedChunks will always only just send one packet, with this chunk
   // as the first chunk in the packet.
-  absl::optional<CookieEchoChunk> cookie_echo_chunk_ = absl::nullopt;
+  std::optional<CookieEchoChunk> cookie_echo_chunk_ = std::nullopt;
 };
 }  // namespace dcsctp
 
diff --git a/net/dcsctp/socket/transmission_control_block_test.cc b/net/dcsctp/socket/transmission_control_block_test.cc
index 6106fbb..472d572 100644
--- a/net/dcsctp/socket/transmission_control_block_test.cc
+++ b/net/dcsctp/socket/transmission_control_block_test.cc
@@ -12,10 +12,10 @@
 #include <array>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <type_traits>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/task_queue/task_queue_base.h"
 #include "net/dcsctp/common/handover_testing.h"
diff --git a/net/dcsctp/testing/BUILD.gn b/net/dcsctp/testing/BUILD.gn
index 573f32a..069d486 100644
--- a/net/dcsctp/testing/BUILD.gn
+++ b/net/dcsctp/testing/BUILD.gn
@@ -22,7 +22,6 @@
     "../packet:data",
     "../public:types",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "data_generator.cc",
diff --git a/net/dcsctp/testing/data_generator.h b/net/dcsctp/testing/data_generator.h
index 52f98dd..f885329 100644
--- a/net/dcsctp/testing/data_generator.h
+++ b/net/dcsctp/testing/data_generator.h
@@ -11,10 +11,10 @@
 #define NET_DCSCTP_TESTING_DATA_GENERATOR_H_
 
 #include <cstdint>
+#include <optional>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/internal_types.h"
 #include "net/dcsctp/packet/data.h"
@@ -23,7 +23,7 @@
 
 struct DataGeneratorOptions {
   StreamID stream_id = StreamID(1);
-  absl::optional<MID> mid = absl::nullopt;
+  std::optional<MID> mid = std::nullopt;
   PPID ppid = PPID(53);
 };
 
diff --git a/net/dcsctp/testing/testing_macros.h b/net/dcsctp/testing/testing_macros.h
index 5cbdfff..dafa76f 100644
--- a/net/dcsctp/testing/testing_macros.h
+++ b/net/dcsctp/testing/testing_macros.h
@@ -17,7 +17,7 @@
 #define DCSCTP_CONCAT_INNER_(x, y) x##y
 #define DCSCTP_CONCAT_(x, y) DCSCTP_CONCAT_INNER_(x, y)
 
-// Similar to ASSERT_OK_AND_ASSIGN, this works with an absl::optional<> instead
+// Similar to ASSERT_OK_AND_ASSIGN, this works with an std::optional<> instead
 // of an absl::StatusOr<>.
 #define ASSERT_HAS_VALUE_AND_ASSIGN(lhs, rexpr)                     \
   auto DCSCTP_CONCAT_(tmp_opt_val__, __LINE__) = rexpr;             \
diff --git a/net/dcsctp/timer/BUILD.gn b/net/dcsctp/timer/BUILD.gn
index d123f64..5b2eb1e 100644
--- a/net/dcsctp/timer/BUILD.gn
+++ b/net/dcsctp/timer/BUILD.gn
@@ -22,7 +22,6 @@
     "../public:types",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "fake_timeout.h",
@@ -66,7 +65,6 @@
       "../../../test:test_support",
       "../../../test/time_controller:time_controller",
       "../public:socket",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
     sources = [
       "task_queue_timeout_test.cc",
diff --git a/net/dcsctp/timer/fake_timeout.h b/net/dcsctp/timer/fake_timeout.h
index cac4928..b94129b 100644
--- a/net/dcsctp/timer/fake_timeout.h
+++ b/net/dcsctp/timer/fake_timeout.h
@@ -14,10 +14,10 @@
 #include <functional>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/units/timestamp.h"
 #include "net/dcsctp/public/timeout.h"
@@ -89,7 +89,7 @@
   // still believes it's running, and it needs to be updated to set
   // Timer::is_running_ to false before you operate on the Timer or Timeout
   // again.
-  absl::optional<TimeoutID> GetNextExpiredTimeout() {
+  std::optional<TimeoutID> GetNextExpiredTimeout() {
     webrtc::Timestamp now = get_time_();
     std::vector<TimeoutID> expired_timers;
     for (auto& timer : timers_) {
@@ -97,7 +97,7 @@
         return timer->timeout_id();
       }
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   webrtc::TimeDelta GetTimeToNextTimeout() const {
diff --git a/net/dcsctp/timer/timer.h b/net/dcsctp/timer/timer.h
index 30b07f9..cfacdda 100644
--- a/net/dcsctp/timer/timer.h
+++ b/net/dcsctp/timer/timer.h
@@ -16,11 +16,11 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/units/time_delta.h"
 #include "net/dcsctp/public/timeout.h"
@@ -45,17 +45,17 @@
       : TimerOptions(duration, TimerBackoffAlgorithm::kExponential) {}
   TimerOptions(webrtc::TimeDelta duration,
                TimerBackoffAlgorithm backoff_algorithm)
-      : TimerOptions(duration, backoff_algorithm, absl::nullopt) {}
+      : TimerOptions(duration, backoff_algorithm, std::nullopt) {}
   TimerOptions(webrtc::TimeDelta duration,
                TimerBackoffAlgorithm backoff_algorithm,
-               absl::optional<int> max_restarts)
+               std::optional<int> max_restarts)
       : TimerOptions(duration,
                      backoff_algorithm,
                      max_restarts,
                      webrtc::TimeDelta::PlusInfinity()) {}
   TimerOptions(webrtc::TimeDelta duration,
                TimerBackoffAlgorithm backoff_algorithm,
-               absl::optional<int> max_restarts,
+               std::optional<int> max_restarts,
                webrtc::TimeDelta max_backoff_duration)
       : TimerOptions(duration,
                      backoff_algorithm,
@@ -64,7 +64,7 @@
                      webrtc::TaskQueueBase::DelayPrecision::kLow) {}
   TimerOptions(webrtc::TimeDelta duration,
                TimerBackoffAlgorithm backoff_algorithm,
-               absl::optional<int> max_restarts,
+               std::optional<int> max_restarts,
                webrtc::TimeDelta max_backoff_duration,
                webrtc::TaskQueueBase::DelayPrecision precision)
       : duration(duration),
@@ -79,8 +79,8 @@
   // restarted. If not set, the same duration will be used.
   const TimerBackoffAlgorithm backoff_algorithm;
   // The maximum number of times that the timer will be automatically restarted,
-  // or absl::nullopt if there is no limit.
-  const absl::optional<int> max_restarts;
+  // or std::nullopt if there is no limit.
+  const std::optional<int> max_restarts;
   // The maximum timeout value for exponential backoff.
   const webrtc::TimeDelta max_backoff_duration;
   // The precision of the webrtc::TaskQueueBase used for scheduling.
diff --git a/net/dcsctp/timer/timer_test.cc b/net/dcsctp/timer/timer_test.cc
index 9a7c029..5d5091e 100644
--- a/net/dcsctp/timer/timer_test.cc
+++ b/net/dcsctp/timer/timer_test.cc
@@ -10,8 +10,8 @@
 #include "net/dcsctp/timer/timer.h"
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/units/time_delta.h"
 #include "net/dcsctp/public/timeout.h"
@@ -39,7 +39,7 @@
     now_ = now_ + duration;
 
     for (;;) {
-      absl::optional<TimeoutID> timeout_id =
+      std::optional<TimeoutID> timeout_id =
           timeout_manager_.GetNextExpiredTimeout();
       if (!timeout_id.has_value()) {
         break;
@@ -396,7 +396,7 @@
   std::unique_ptr<Timer> t1 = manager_.CreateTimer(
       "t1", on_expired_.AsStdFunction(),
       TimerOptions(TimeDelta::Seconds(1), TimerBackoffAlgorithm::kExponential,
-                   /*max_restarts=*/absl::nullopt, TimeDelta::Seconds(5)));
+                   /*max_restarts=*/std::nullopt, TimeDelta::Seconds(5)));
 
   t1->Start();
 
@@ -431,7 +431,7 @@
 
 TEST(TimerManagerTest, TimerManagerPassesPrecisionToCreateTimeoutMethod) {
   FakeTimeoutManager timeout_manager([&]() { return Timestamp::Zero(); });
-  absl::optional<webrtc::TaskQueueBase::DelayPrecision> create_timer_precison;
+  std::optional<webrtc::TaskQueueBase::DelayPrecision> create_timer_precison;
   TimerManager manager([&](webrtc::TaskQueueBase::DelayPrecision precision) {
     create_timer_precison = precision;
     return timeout_manager.CreateTimeout(precision);
@@ -445,7 +445,7 @@
   manager.CreateTimer(
       "test_timer", []() { return TimeDelta::Zero(); },
       TimerOptions(TimeDelta::Millis(123), TimerBackoffAlgorithm::kExponential,
-                   absl::nullopt, TimeDelta::PlusInfinity(),
+                   std::nullopt, TimeDelta::PlusInfinity(),
                    webrtc::TaskQueueBase::DelayPrecision::kHigh));
   EXPECT_EQ(create_timer_precison,
             webrtc::TaskQueueBase::DelayPrecision::kHigh);
@@ -453,7 +453,7 @@
   manager.CreateTimer(
       "test_timer", []() { return TimeDelta::Zero(); },
       TimerOptions(TimeDelta::Millis(123), TimerBackoffAlgorithm::kExponential,
-                   absl::nullopt, TimeDelta::PlusInfinity(),
+                   std::nullopt, TimeDelta::PlusInfinity(),
                    webrtc::TaskQueueBase::DelayPrecision::kLow));
   EXPECT_EQ(create_timer_precison, webrtc::TaskQueueBase::DelayPrecision::kLow);
 }
diff --git a/net/dcsctp/tx/BUILD.gn b/net/dcsctp/tx/BUILD.gn
index b28aa0e..0e21d91 100644
--- a/net/dcsctp/tx/BUILD.gn
+++ b/net/dcsctp/tx/BUILD.gn
@@ -17,7 +17,6 @@
     "../packet:data",
     "../public:socket",
     "../public:types",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [ "send_queue.h" ]
 }
@@ -37,7 +36,6 @@
     "../public:types",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "rr_send_queue.cc",
@@ -62,7 +60,6 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "stream_scheduler.cc",
@@ -114,7 +111,6 @@
     "../public:socket",
     "../public:types",
     "../timer",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "outstanding_data.cc",
@@ -140,7 +136,6 @@
     "../timer",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   sources = [
     "retransmission_queue.cc",
@@ -156,7 +151,6 @@
       "../../../api:array_view",
       "../../../api/units:timestamp",
       "../../../test:test_support",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
     sources = [ "mock_send_queue.h" ]
   }
@@ -192,7 +186,6 @@
       "../testing:data_generator",
       "../testing:testing_macros",
       "../timer",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
     sources = [
       "outstanding_data_test.cc",
diff --git a/net/dcsctp/tx/mock_send_queue.h b/net/dcsctp/tx/mock_send_queue.h
index 3511403..e31c99a 100644
--- a/net/dcsctp/tx/mock_send_queue.h
+++ b/net/dcsctp/tx/mock_send_queue.h
@@ -11,9 +11,9 @@
 #define NET_DCSCTP_TX_MOCK_SEND_QUEUE_H_
 
 #include <cstdint>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/units/timestamp.h"
 #include "net/dcsctp/tx/send_queue.h"
@@ -26,11 +26,11 @@
   MockSendQueue() {
     ON_CALL(*this, Produce)
         .WillByDefault([](webrtc::Timestamp now, size_t max_size) {
-          return absl::nullopt;
+          return std::nullopt;
         });
   }
 
-  MOCK_METHOD(absl::optional<SendQueue::DataToSend>,
+  MOCK_METHOD(std::optional<SendQueue::DataToSend>,
               Produce,
               (webrtc::Timestamp now, size_t max_size),
               (override));
diff --git a/net/dcsctp/tx/outstanding_data.cc b/net/dcsctp/tx/outstanding_data.cc
index ca639ab..b42c77e 100644
--- a/net/dcsctp/tx/outstanding_data.cc
+++ b/net/dcsctp/tx/outstanding_data.cc
@@ -412,7 +412,7 @@
                              outstanding_data_.size());
 }
 
-absl::optional<UnwrappedTSN> OutstandingData::Insert(
+std::optional<UnwrappedTSN> OutstandingData::Insert(
     OutgoingMessageId message_id,
     const Data& data,
     Timestamp time_sent,
@@ -436,7 +436,7 @@
                          << " as expired";
     AbandonAllFor(item);
     RTC_DCHECK(IsConsistent());
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   RTC_DCHECK(IsConsistent());
diff --git a/net/dcsctp/tx/outstanding_data.h b/net/dcsctp/tx/outstanding_data.h
index 2a21497..018b02f 100644
--- a/net/dcsctp/tx/outstanding_data.h
+++ b/net/dcsctp/tx/outstanding_data.h
@@ -12,11 +12,11 @@
 
 #include <deque>
 #include <map>
+#include <optional>
 #include <set>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/units/timestamp.h"
 #include "net/dcsctp/common/internal_types.h"
 #include "net/dcsctp/common/sequence_numbers.h"
@@ -132,8 +132,8 @@
 
   // Schedules `data` to be sent, with the provided partial reliability
   // parameters. Returns the TSN if the item was actually added and scheduled to
-  // be sent, and absl::nullopt if it shouldn't be sent.
-  absl::optional<UnwrappedTSN> Insert(
+  // be sent, and std::nullopt if it shouldn't be sent.
+  std::optional<UnwrappedTSN> Insert(
       OutgoingMessageId message_id,
       const Data& data,
       webrtc::Timestamp time_sent,
diff --git a/net/dcsctp/tx/outstanding_data_test.cc b/net/dcsctp/tx/outstanding_data_test.cc
index e4bdb7c..6048dbe 100644
--- a/net/dcsctp/tx/outstanding_data_test.cc
+++ b/net/dcsctp/tx/outstanding_data_test.cc
@@ -9,9 +9,9 @@
  */
 #include "net/dcsctp/tx/outstanding_data.h"
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "net/dcsctp/common/internal_types.h"
 #include "net/dcsctp/common/math.h"
 #include "net/dcsctp/common/sequence_numbers.h"
diff --git a/net/dcsctp/tx/retransmission_error_counter.h b/net/dcsctp/tx/retransmission_error_counter.h
index 7078c78..589e66b 100644
--- a/net/dcsctp/tx/retransmission_error_counter.h
+++ b/net/dcsctp/tx/retransmission_error_counter.h
@@ -42,7 +42,7 @@
 
  private:
   const absl::string_view log_prefix_;
-  const absl::optional<int> limit_;
+  const std::optional<int> limit_;
   int counter_ = 0;
 };
 }  // namespace dcsctp
diff --git a/net/dcsctp/tx/retransmission_error_counter_test.cc b/net/dcsctp/tx/retransmission_error_counter_test.cc
index 67bbc0b..dc53740 100644
--- a/net/dcsctp/tx/retransmission_error_counter_test.cc
+++ b/net/dcsctp/tx/retransmission_error_counter_test.cc
@@ -74,7 +74,7 @@
 
 TEST(RetransmissionErrorCounterTest, CanBeLimitless) {
   DcSctpOptions options;
-  options.max_retransmissions = absl::nullopt;
+  options.max_retransmissions = std::nullopt;
   RetransmissionErrorCounter counter("log: ", options);
   for (int i = 0; i < 100; ++i) {
     EXPECT_TRUE(counter.Increment("test"));
diff --git a/net/dcsctp/tx/retransmission_queue.cc b/net/dcsctp/tx/retransmission_queue.cc
index 9a24617..604139c 100644
--- a/net/dcsctp/tx/retransmission_queue.cc
+++ b/net/dcsctp/tx/retransmission_queue.cc
@@ -14,6 +14,7 @@
 #include <functional>
 #include <iterator>
 #include <map>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
@@ -21,7 +22,6 @@
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/math.h"
 #include "net/dcsctp/common/sequence_numbers.h"
@@ -106,7 +106,7 @@
     RTC_DLOG(LS_VERBOSE) << log_prefix_
                          << "exit_point=" << *fast_recovery_exit_tsn_->Wrap()
                          << " reached - exiting fast recovery";
-    fast_recovery_exit_tsn_ = absl::nullopt;
+    fast_recovery_exit_tsn_ = std::nullopt;
   }
 }
 
@@ -475,7 +475,7 @@
 
   while (max_bytes > data_chunk_header_size_) {
     RTC_DCHECK(IsDivisibleBy4(max_bytes));
-    absl::optional<SendQueue::DataToSend> chunk_opt =
+    std::optional<SendQueue::DataToSend> chunk_opt =
         send_queue_.Produce(now, max_bytes - data_chunk_header_size_);
     if (!chunk_opt.has_value()) {
       break;
@@ -485,7 +485,7 @@
     max_bytes -= chunk_size;
     rwnd_ -= chunk_size;
 
-    absl::optional<UnwrappedTSN> tsn = outstanding_data_.Insert(
+    std::optional<UnwrappedTSN> tsn = outstanding_data_.Insert(
         chunk_opt->message_id, chunk_opt->data, now,
         partial_reliability_ ? chunk_opt->max_retransmissions
                              : MaxRetransmits::NoLimit(),
diff --git a/net/dcsctp/tx/retransmission_queue.h b/net/dcsctp/tx/retransmission_queue.h
index 1572064..5767c88 100644
--- a/net/dcsctp/tx/retransmission_queue.h
+++ b/net/dcsctp/tx/retransmission_queue.h
@@ -13,13 +13,13 @@
 #include <cstdint>
 #include <functional>
 #include <map>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/sequence_numbers.h"
 #include "net/dcsctp/packet/chunk/forward_tsn_chunk.h"
@@ -243,7 +243,7 @@
 
   // If set, fast recovery is enabled until this TSN has been cumulative
   // acked.
-  absl::optional<UnwrappedTSN> fast_recovery_exit_tsn_ = absl::nullopt;
+  std::optional<UnwrappedTSN> fast_recovery_exit_tsn_ = std::nullopt;
 
   // The send queue.
   SendQueue& send_queue_;
diff --git a/net/dcsctp/tx/retransmission_queue_test.cc b/net/dcsctp/tx/retransmission_queue_test.cc
index 4c802e4..cc68a9b 100644
--- a/net/dcsctp/tx/retransmission_queue_test.cc
+++ b/net/dcsctp/tx/retransmission_queue_test.cc
@@ -13,10 +13,10 @@
 #include <cstdint>
 #include <functional>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/task_queue/task_queue_base.h"
 #include "net/dcsctp/common/handover_testing.h"
@@ -148,7 +148,7 @@
   RetransmissionQueue queue = CreateQueue();
   EXPECT_CALL(producer_, Produce)
       .WillOnce(CreateChunk(OutgoingMessageId(0)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_THAT(GetSentPacketTSNs(queue), testing::ElementsAre(TSN(10)));
 
@@ -161,7 +161,7 @@
   RetransmissionQueue queue = CreateQueue();
   EXPECT_CALL(producer_, Produce)
       .WillOnce(CreateChunk(OutgoingMessageId(0)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_THAT(GetSentPacketTSNs(queue), testing::ElementsAre(TSN(10)));
 
@@ -177,7 +177,7 @@
       .WillOnce(CreateChunk(OutgoingMessageId(0)))
       .WillOnce(CreateChunk(OutgoingMessageId(1)))
       .WillOnce(CreateChunk(OutgoingMessageId(2)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_THAT(GetSentPacketTSNs(queue),
               testing::ElementsAre(TSN(10), TSN(11), TSN(12)));
@@ -200,7 +200,7 @@
       .WillOnce(CreateChunk(OutgoingMessageId(5)))
       .WillOnce(CreateChunk(OutgoingMessageId(6)))
       .WillOnce(CreateChunk(OutgoingMessageId(7)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_THAT(GetSentPacketTSNs(queue),
               testing::ElementsAre(TSN(10), TSN(11), TSN(12), TSN(13), TSN(14),
@@ -231,7 +231,7 @@
       .WillOnce(CreateChunk(OutgoingMessageId(5)))
       .WillOnce(CreateChunk(OutgoingMessageId(6)))
       .WillOnce(CreateChunk(OutgoingMessageId(7)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_THAT(GetSentPacketTSNs(queue),
               testing::ElementsAre(TSN(10), TSN(11), TSN(12), TSN(13), TSN(14),
@@ -243,7 +243,7 @@
   // Send 18
   EXPECT_CALL(producer_, Produce)
       .WillOnce(CreateChunk(OutgoingMessageId(8)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
   EXPECT_THAT(GetSentPacketTSNs(queue), testing::ElementsAre(TSN(18)));
 
   // Ack 12, 14-15, 17-18
@@ -264,7 +264,7 @@
   // Send 19
   EXPECT_CALL(producer_, Produce)
       .WillOnce(CreateChunk(OutgoingMessageId(9)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
   EXPECT_THAT(GetSentPacketTSNs(queue), testing::ElementsAre(TSN(19)));
 
   // Ack 12, 14-15, 17-19
@@ -276,7 +276,7 @@
   // Send 20
   EXPECT_CALL(producer_, Produce)
       .WillOnce(CreateChunk(OutgoingMessageId(10)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
   EXPECT_THAT(GetSentPacketTSNs(queue), testing::ElementsAre(TSN(20)));
 
   // Ack 12, 14-15, 17-20
@@ -323,7 +323,7 @@
       .WillOnce(CreateChunk(OutgoingMessageId(0)))
       .WillOnce(CreateChunk(OutgoingMessageId(1)))
       .WillOnce(CreateChunk(OutgoingMessageId(2)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   static constexpr Timestamp kStartTime = Timestamp::Seconds(100);
   now_ = kStartTime;
@@ -344,7 +344,7 @@
   // Send 13
   EXPECT_CALL(producer_, Produce)
       .WillOnce(CreateChunk(OutgoingMessageId(3)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
   EXPECT_THAT(GetSentPacketTSNs(queue), testing::ElementsAre(TSN(13)));
 
   // Ack 10, 12-13, after 100ms.
@@ -355,7 +355,7 @@
   // Send 14
   EXPECT_CALL(producer_, Produce)
       .WillOnce(CreateChunk(OutgoingMessageId(4)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
   EXPECT_THAT(GetSentPacketTSNs(queue), testing::ElementsAre(TSN(14)));
 
   // Ack 10, 12-14, after 100 ms.
@@ -407,7 +407,7 @@
         return SendQueue::DataToSend(OutgoingMessageId(1),
                                      gen_.Ordered({1, 2, 3, 4}, "BE"));
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   std::vector<std::pair<TSN, Data>> chunks_to_send =
       queue.GetChunksToSend(now_, 1000);
@@ -426,7 +426,7 @@
         return SendQueue::DataToSend(OutgoingMessageId(0),
                                      gen_.Ordered({1, 2, 3, 4}, "BE"));
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_FALSE(queue.ShouldSendForwardTsn(now_));
   std::vector<std::pair<TSN, Data>> chunks_to_send =
@@ -466,7 +466,7 @@
         dts.max_retransmissions = MaxRetransmits(0);
         return dts;
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_FALSE(queue.ShouldSendForwardTsn(now_));
   std::vector<std::pair<TSN, Data>> chunks_to_send =
@@ -495,7 +495,7 @@
         dts.max_retransmissions = MaxRetransmits(0);
         return dts;
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_FALSE(queue.ShouldSendForwardTsn(now_));
   std::vector<std::pair<TSN, Data>> chunks_to_send =
@@ -536,7 +536,7 @@
         dts.max_retransmissions = MaxRetransmits(3);
         return dts;
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_FALSE(queue.ShouldSendForwardTsn(now_));
   std::vector<std::pair<TSN, Data>> chunks_to_send =
@@ -588,7 +588,7 @@
         return SendQueue::DataToSend(OutgoingMessageId(0),
                                      gen_.Ordered(payload, "BE"));
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   std::vector<std::pair<TSN, Data>> chunks_to_send =
       queue.GetChunksToSend(now_, 1500);
@@ -637,7 +637,7 @@
         dts.max_retransmissions = MaxRetransmits(0);
         return dts;
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   // Send and ack first chunk (TSN 10)
   std::vector<std::pair<TSN, Data>> chunks_to_send =
@@ -693,7 +693,7 @@
         dts.max_retransmissions = MaxRetransmits(0);
         return dts;
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   // Send and ack first chunk (TSN 10)
   std::vector<std::pair<TSN, Data>> chunks_to_send =
@@ -763,7 +763,7 @@
         dts.max_retransmissions = MaxRetransmits(0);
         return dts;
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   std::vector<std::pair<TSN, Data>> chunks_to_send =
       queue.GetChunksToSend(now_, 1000);
@@ -858,7 +858,7 @@
         dts.max_retransmissions = MaxRetransmits(0);
         return dts;
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   std::vector<std::pair<TSN, Data>> chunks_to_send =
       queue.GetChunksToSend(now_, 1000);
@@ -890,7 +890,7 @@
       .WillOnce(CreateChunk(OutgoingMessageId(5)))
       .WillOnce(CreateChunk(OutgoingMessageId(6)))
       .WillOnce(CreateChunk(OutgoingMessageId(7)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_THAT(GetSentPacketTSNs(queue),
               testing::ElementsAre(TSN(10), TSN(11), TSN(12), TSN(13), TSN(14),
@@ -920,7 +920,7 @@
       .WillOnce(CreateChunk(OutgoingMessageId(5)))
       .WillOnce(CreateChunk(OutgoingMessageId(6)))
       .WillOnce(CreateChunk(OutgoingMessageId(7)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_THAT(GetSentPacketTSNs(queue),
               testing::ElementsAre(TSN(10), TSN(11), TSN(12), TSN(13), TSN(14),
@@ -967,7 +967,7 @@
       .WillOnce(CreateChunk(OutgoingMessageId(5)))
       .WillOnce(CreateChunk(OutgoingMessageId(6)))
       .WillOnce(CreateChunk(OutgoingMessageId(7)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_THAT(GetSentPacketTSNs(queue),
               testing::ElementsAre(TSN(10), TSN(11), TSN(12), TSN(13), TSN(14),
@@ -1036,7 +1036,7 @@
         dts.max_retransmissions = MaxRetransmits(0);
         return dts;
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   // Send and ack first chunk (TSN 10)
   std::vector<std::pair<TSN, Data>> chunks_to_send =
@@ -1098,7 +1098,7 @@
         dts.expires_at = Timestamp(test_start + TimeDelta::Millis(10));
         return dts;
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   std::vector<std::pair<TSN, Data>> chunks_to_send =
       queue.GetChunksToSend(now_, 24);
@@ -1151,7 +1151,7 @@
         dts.expires_at = Timestamp(test_start + TimeDelta::Millis(10));
         return dts;
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
   EXPECT_CALL(producer_, Discard(StreamID(1), OutgoingMessageId(44)))
       .WillOnce(Return(true));
 
@@ -1186,7 +1186,7 @@
       .WillOnce(CreateChunk(OutgoingMessageId(0)))
       .WillOnce(CreateChunk(OutgoingMessageId(1)))
       .WillOnce(CreateChunk(OutgoingMessageId(2)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_FALSE(queue.ShouldSendForwardTsn(now_));
 
@@ -1262,7 +1262,7 @@
       .WillOnce(CreateChunk(OutgoingMessageId(6)))
       .WillOnce(CreateChunk(OutgoingMessageId(7)))
       .WillOnce(CreateChunk(OutgoingMessageId(8)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_FALSE(queue.ShouldSendForwardTsn(now_));
 
@@ -1392,7 +1392,7 @@
         return SendQueue::DataToSend(OutgoingMessageId(0),
                                      gen_.Ordered(payload, "BE"));
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   std::vector<std::pair<TSN, Data>> chunks_to_send =
       queue.GetChunksToSend(now_, 1500);
@@ -1409,7 +1409,7 @@
   RetransmissionQueue queue = CreateQueue();
   EXPECT_CALL(producer_, Produce)
       .WillOnce(CreateChunk(OutgoingMessageId(0)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   EXPECT_THAT(GetSentPacketTSNs(queue), SizeIs(1));
   EXPECT_EQ(
@@ -1432,7 +1432,7 @@
       .WillOnce(CreateChunk(OutgoingMessageId(5)))
       .WillOnce(CreateChunk(OutgoingMessageId(6)))
       .WillOnce(CreateChunk(OutgoingMessageId(7)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
   EXPECT_THAT(GetSentPacketTSNs(queue), SizeIs(8));
   EXPECT_EQ(
       queue.GetHandoverReadiness(),
@@ -1445,7 +1445,7 @@
   // Send 18
   EXPECT_CALL(producer_, Produce)
       .WillOnce(CreateChunk(OutgoingMessageId(8)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
   EXPECT_THAT(GetSentPacketTSNs(queue), SizeIs(1));
 
   // Ack 12, 14-15, 17-18
@@ -1457,7 +1457,7 @@
   // Send 19
   EXPECT_CALL(producer_, Produce)
       .WillOnce(CreateChunk(OutgoingMessageId(9)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
   EXPECT_THAT(GetSentPacketTSNs(queue), SizeIs(1));
 
   // Ack 12, 14-15, 17-19
@@ -1469,7 +1469,7 @@
   // Send 20
   EXPECT_CALL(producer_, Produce)
       .WillOnce(CreateChunk(OutgoingMessageId(10)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
   EXPECT_THAT(GetSentPacketTSNs(queue), SizeIs(1));
 
   // Ack 12, 14-15, 17-20
@@ -1505,7 +1505,7 @@
   EXPECT_CALL(producer_, Produce)
       .WillOnce(CreateChunk(OutgoingMessageId(0)))
       .WillOnce(CreateChunk(OutgoingMessageId(1)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
   EXPECT_THAT(GetSentPacketTSNs(queue), SizeIs(2));
   queue.HandleSack(now_, SackChunk(TSN(11), kArwnd, {}, {}));
 
@@ -1516,7 +1516,7 @@
       .WillOnce(CreateChunk(OutgoingMessageId(2)))
       .WillOnce(CreateChunk(OutgoingMessageId(3)))
       .WillOnce(CreateChunk(OutgoingMessageId(4)))
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
   EXPECT_THAT(GetSentPacketTSNs(*handedover_queue),
               testing::ElementsAre(TSN(12), TSN(13), TSN(14)));
 
@@ -1554,7 +1554,7 @@
         return SendQueue::DataToSend(OutgoingMessageId(0),
                                      gen_.Ordered(payload, "E"));
       })
-      .WillRepeatedly([](Timestamp, size_t) { return absl::nullopt; });
+      .WillRepeatedly([](Timestamp, size_t) { return std::nullopt; });
 
   // Produce all chunks and put them in the retransmission queue.
   std::vector<std::pair<TSN, Data>> chunks_to_send =
diff --git a/net/dcsctp/tx/rr_send_queue.cc b/net/dcsctp/tx/rr_send_queue.cc
index 2193880..2016ede 100644
--- a/net/dcsctp/tx/rr_send_queue.cc
+++ b/net/dcsctp/tx/rr_send_queue.cc
@@ -13,12 +13,12 @@
 #include <deque>
 #include <limits>
 #include <map>
+#include <optional>
 #include <set>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/internal_types.h"
 #include "net/dcsctp/packet/data.h"
@@ -136,7 +136,7 @@
   RTC_DCHECK(IsConsistent());
 }
 
-absl::optional<SendQueue::DataToSend> RRSendQueue::OutgoingStream::Produce(
+std::optional<SendQueue::DataToSend> RRSendQueue::OutgoingStream::Produce(
     Timestamp now,
     size_t max_size) {
   RTC_DCHECK(pause_state_ != PauseState::kPaused &&
@@ -218,7 +218,7 @@
     return chunk;
   }
   RTC_DCHECK(IsConsistent());
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void RRSendQueue::OutgoingStream::HandleMessageExpired(
@@ -331,8 +331,8 @@
                                             item.remaining_size);
     item.remaining_offset = 0;
     item.remaining_size = item.message.payload().size();
-    item.mid = absl::nullopt;
-    item.ssn = absl::nullopt;
+    item.mid = std::nullopt;
+    item.ssn = std::nullopt;
     item.current_fsn = FSN(0);
     if (old_pause_state == PauseState::kPaused ||
         old_pause_state == PauseState::kResetting) {
@@ -381,8 +381,8 @@
   return total_buffered_amount() == 0;
 }
 
-absl::optional<SendQueue::DataToSend> RRSendQueue::Produce(Timestamp now,
-                                                           size_t max_size) {
+std::optional<SendQueue::DataToSend> RRSendQueue::Produce(Timestamp now,
+                                                          size_t max_size) {
   return scheduler_.Produce(now, max_size);
 }
 
diff --git a/net/dcsctp/tx/rr_send_queue.h b/net/dcsctp/tx/rr_send_queue.h
index 1a370a2..19c30e1 100644
--- a/net/dcsctp/tx/rr_send_queue.h
+++ b/net/dcsctp/tx/rr_send_queue.h
@@ -14,13 +14,13 @@
 #include <deque>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/common/internal_types.h"
 #include "net/dcsctp/public/dcsctp_message.h"
@@ -75,8 +75,8 @@
            const SendOptions& send_options = {});
 
   // Implementation of `SendQueue`.
-  absl::optional<DataToSend> Produce(webrtc::Timestamp now,
-                                     size_t max_size) override;
+  std::optional<DataToSend> Produce(webrtc::Timestamp now,
+                                    size_t max_size) override;
   bool Discard(StreamID stream_id, OutgoingMessageId message_id) override;
   void PrepareResetStream(StreamID streams) override;
   bool HasStreamsReadyToBeReset() const override;
@@ -154,8 +154,8 @@
     void Add(DcSctpMessage message, MessageAttributes attributes);
 
     // Implementing `StreamScheduler::StreamProducer`.
-    absl::optional<SendQueue::DataToSend> Produce(webrtc::Timestamp now,
-                                                  size_t max_size) override;
+    std::optional<SendQueue::DataToSend> Produce(webrtc::Timestamp now,
+                                                 size_t max_size) override;
     size_t bytes_to_send_in_next_message() const override;
 
     const ThresholdWatcher& buffered_amount() const { return buffered_amount_; }
@@ -235,8 +235,8 @@
       size_t remaining_size;
       // If set, an allocated Message ID and SSN. Will be allocated when the
       // first fragment is sent.
-      absl::optional<MID> mid = absl::nullopt;
-      absl::optional<SSN> ssn = absl::nullopt;
+      std::optional<MID> mid = std::nullopt;
+      std::optional<SSN> ssn = std::nullopt;
       // The current Fragment Sequence Number, incremented for each fragment.
       FSN current_fsn = FSN(0);
     };
@@ -263,7 +263,7 @@
 
   bool IsConsistent() const;
   OutgoingStream& GetOrCreateStreamInfo(StreamID stream_id);
-  absl::optional<DataToSend> Produce(
+  std::optional<DataToSend> Produce(
       std::map<StreamID, OutgoingStream>::iterator it,
       webrtc::Timestamp now,
       size_t max_size);
diff --git a/net/dcsctp/tx/rr_send_queue_test.cc b/net/dcsctp/tx/rr_send_queue_test.cc
index 9beba95..04f718c 100644
--- a/net/dcsctp/tx/rr_send_queue_test.cc
+++ b/net/dcsctp/tx/rr_send_queue_test.cc
@@ -65,7 +65,7 @@
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, {1, 2, 4, 5, 6}));
 
   EXPECT_FALSE(buf_.IsEmpty());
-  absl::optional<SendQueue::DataToSend> chunk_opt =
+  std::optional<SendQueue::DataToSend> chunk_opt =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_opt.has_value());
   EXPECT_TRUE(chunk_opt->data.is_beginning);
@@ -76,19 +76,19 @@
   std::vector<uint8_t> payload(60);
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload));
 
-  absl::optional<SendQueue::DataToSend> chunk_beg =
+  std::optional<SendQueue::DataToSend> chunk_beg =
       buf_.Produce(kNow, /*max_size=*/20);
   ASSERT_TRUE(chunk_beg.has_value());
   EXPECT_TRUE(chunk_beg->data.is_beginning);
   EXPECT_FALSE(chunk_beg->data.is_end);
 
-  absl::optional<SendQueue::DataToSend> chunk_mid =
+  std::optional<SendQueue::DataToSend> chunk_mid =
       buf_.Produce(kNow, /*max_size=*/20);
   ASSERT_TRUE(chunk_mid.has_value());
   EXPECT_FALSE(chunk_mid->data.is_beginning);
   EXPECT_FALSE(chunk_mid->data.is_end);
 
-  absl::optional<SendQueue::DataToSend> chunk_end =
+  std::optional<SendQueue::DataToSend> chunk_end =
       buf_.Produce(kNow, /*max_size=*/20);
   ASSERT_TRUE(chunk_end.has_value());
   EXPECT_FALSE(chunk_end->data.is_beginning);
@@ -102,7 +102,7 @@
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload));
   buf_.Add(kNow, DcSctpMessage(StreamID(3), PPID(54), payload));
 
-  absl::optional<SendQueue::DataToSend> chunk_one =
+  std::optional<SendQueue::DataToSend> chunk_one =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_one.has_value());
   EXPECT_EQ(chunk_one->data.stream_id, kStreamID);
@@ -110,7 +110,7 @@
   EXPECT_TRUE(chunk_one->data.is_beginning);
   EXPECT_TRUE(chunk_one->data.is_end);
 
-  absl::optional<SendQueue::DataToSend> chunk_two =
+  std::optional<SendQueue::DataToSend> chunk_two =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_two.has_value());
   EXPECT_EQ(chunk_two->data.stream_id, StreamID(3));
@@ -132,14 +132,14 @@
   buf_.Add(kNow, DcSctpMessage(StreamID(5), PPID(55), payload));
   EXPECT_GE(buf_.total_buffered_amount(), 1000u);
 
-  absl::optional<SendQueue::DataToSend> chunk_one = buf_.Produce(kNow, 1000);
+  std::optional<SendQueue::DataToSend> chunk_one = buf_.Produce(kNow, 1000);
   ASSERT_TRUE(chunk_one.has_value());
   EXPECT_EQ(chunk_one->data.stream_id, kStreamID);
   EXPECT_EQ(chunk_one->data.ppid, kPPID);
 
   EXPECT_GE(buf_.total_buffered_amount(), 1000u);
 
-  absl::optional<SendQueue::DataToSend> chunk_two = buf_.Produce(kNow, 1000);
+  std::optional<SendQueue::DataToSend> chunk_two = buf_.Produce(kNow, 1000);
   ASSERT_TRUE(chunk_two.has_value());
   EXPECT_EQ(chunk_two->data.stream_id, StreamID(3));
   EXPECT_EQ(chunk_two->data.ppid, PPID(54));
@@ -147,7 +147,7 @@
   EXPECT_LT(buf_.total_buffered_amount(), 1000u);
   EXPECT_FALSE(buf_.IsEmpty());
 
-  absl::optional<SendQueue::DataToSend> chunk_three = buf_.Produce(kNow, 1000);
+  std::optional<SendQueue::DataToSend> chunk_three = buf_.Produce(kNow, 1000);
   ASSERT_TRUE(chunk_three.has_value());
   EXPECT_EQ(chunk_three->data.stream_id, StreamID(5));
   EXPECT_EQ(chunk_three->data.ppid, PPID(55));
@@ -161,7 +161,7 @@
 
   // Default is ordered
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload));
-  absl::optional<SendQueue::DataToSend> chunk_one =
+  std::optional<SendQueue::DataToSend> chunk_one =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_one.has_value());
   EXPECT_FALSE(chunk_one->data.is_unordered);
@@ -170,7 +170,7 @@
   SendOptions opts;
   opts.unordered = IsUnordered(true);
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload), opts);
-  absl::optional<SendQueue::DataToSend> chunk_two =
+  std::optional<SendQueue::DataToSend> chunk_two =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_two.has_value());
   EXPECT_TRUE(chunk_two->data.is_unordered);
@@ -222,20 +222,20 @@
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload));
   buf_.Add(kNow, DcSctpMessage(StreamID(2), PPID(54), payload));
 
-  absl::optional<SendQueue::DataToSend> chunk_one =
+  std::optional<SendQueue::DataToSend> chunk_one =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_one.has_value());
   EXPECT_FALSE(chunk_one->data.is_end);
   EXPECT_EQ(chunk_one->data.stream_id, kStreamID);
   buf_.Discard(chunk_one->data.stream_id, chunk_one->message_id);
 
-  absl::optional<SendQueue::DataToSend> chunk_two =
+  std::optional<SendQueue::DataToSend> chunk_two =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_two.has_value());
   EXPECT_FALSE(chunk_two->data.is_end);
   EXPECT_EQ(chunk_two->data.stream_id, StreamID(2));
 
-  absl::optional<SendQueue::DataToSend> chunk_three =
+  std::optional<SendQueue::DataToSend> chunk_three =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_three.has_value());
   EXPECT_TRUE(chunk_three->data.is_end);
@@ -268,7 +268,7 @@
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload));
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload));
 
-  absl::optional<SendQueue::DataToSend> chunk_one = buf_.Produce(kNow, 50);
+  std::optional<SendQueue::DataToSend> chunk_one = buf_.Produce(kNow, 50);
   ASSERT_TRUE(chunk_one.has_value());
   EXPECT_EQ(chunk_one->data.stream_id, kStreamID);
   EXPECT_EQ(buf_.total_buffered_amount(), 2 * payload.size() - 50);
@@ -297,7 +297,7 @@
   buf_.CommitResetStreams();
   EXPECT_EQ(buf_.total_buffered_amount(), payload.size());
 
-  absl::optional<SendQueue::DataToSend> chunk_one = buf_.Produce(kNow, 50);
+  std::optional<SendQueue::DataToSend> chunk_one = buf_.Produce(kNow, 50);
   ASSERT_TRUE(chunk_one.has_value());
   EXPECT_EQ(chunk_one->data.stream_id, kStreamID);
   EXPECT_EQ(buf_.total_buffered_amount(), 0u);
@@ -311,7 +311,7 @@
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload));
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload));
 
-  absl::optional<SendQueue::DataToSend> chunk_one =
+  std::optional<SendQueue::DataToSend> chunk_one =
       buf_.Produce(kNow, kFragmentSize);
   ASSERT_TRUE(chunk_one.has_value());
   EXPECT_EQ(chunk_one->data.stream_id, kStreamID);
@@ -322,7 +322,7 @@
   EXPECT_EQ(buf_.total_buffered_amount(), 1 * kPayloadSize - kFragmentSize);
 
   // Should still produce fragments until end of message.
-  absl::optional<SendQueue::DataToSend> chunk_two =
+  std::optional<SendQueue::DataToSend> chunk_two =
       buf_.Produce(kNow, kFragmentSize);
   ASSERT_TRUE(chunk_two.has_value());
   EXPECT_EQ(chunk_two->data.stream_id, kStreamID);
@@ -338,12 +338,12 @@
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload));
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload));
 
-  absl::optional<SendQueue::DataToSend> chunk_one =
+  std::optional<SendQueue::DataToSend> chunk_one =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_one.has_value());
   EXPECT_EQ(chunk_one->data.ssn, SSN(0));
 
-  absl::optional<SendQueue::DataToSend> chunk_two =
+  std::optional<SendQueue::DataToSend> chunk_two =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_two.has_value());
   EXPECT_EQ(chunk_two->data.ssn, SSN(1));
@@ -358,7 +358,7 @@
               UnorderedElementsAre(StreamID(1)));
   buf_.CommitResetStreams();
 
-  absl::optional<SendQueue::DataToSend> chunk_three =
+  std::optional<SendQueue::DataToSend> chunk_three =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_three.has_value());
   EXPECT_EQ(chunk_three->data.ssn, SSN(0));
@@ -396,13 +396,13 @@
   buf_.Add(kNow, DcSctpMessage(StreamID(1), kPPID, payload));
   buf_.Add(kNow, DcSctpMessage(StreamID(3), kPPID, payload));
 
-  absl::optional<SendQueue::DataToSend> chunk_one =
+  std::optional<SendQueue::DataToSend> chunk_one =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_one.has_value());
   EXPECT_EQ(chunk_one->data.stream_id, StreamID(1));
   EXPECT_EQ(chunk_one->data.ssn, SSN(0));
 
-  absl::optional<SendQueue::DataToSend> chunk_two =
+  std::optional<SendQueue::DataToSend> chunk_two =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_two.has_value());
   EXPECT_EQ(chunk_two->data.stream_id, StreamID(3));
@@ -420,13 +420,13 @@
 
   buf_.CommitResetStreams();
 
-  absl::optional<SendQueue::DataToSend> chunk_three =
+  std::optional<SendQueue::DataToSend> chunk_three =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_three.has_value());
   EXPECT_EQ(chunk_three->data.stream_id, StreamID(1));
   EXPECT_EQ(chunk_three->data.ssn, SSN(1));
 
-  absl::optional<SendQueue::DataToSend> chunk_four =
+  std::optional<SendQueue::DataToSend> chunk_four =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_four.has_value());
   EXPECT_EQ(chunk_four->data.stream_id, StreamID(3));
@@ -439,12 +439,12 @@
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload));
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload));
 
-  absl::optional<SendQueue::DataToSend> chunk_one =
+  std::optional<SendQueue::DataToSend> chunk_one =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_one.has_value());
   EXPECT_EQ(chunk_one->data.ssn, SSN(0));
 
-  absl::optional<SendQueue::DataToSend> chunk_two =
+  std::optional<SendQueue::DataToSend> chunk_two =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_two.has_value());
   EXPECT_EQ(chunk_two->data.ssn, SSN(1));
@@ -459,7 +459,7 @@
               UnorderedElementsAre(StreamID(1)));
   buf_.RollbackResetStreams();
 
-  absl::optional<SendQueue::DataToSend> chunk_three =
+  std::optional<SendQueue::DataToSend> chunk_three =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_three.has_value());
   EXPECT_EQ(chunk_three->data.ssn, SSN(2));
@@ -744,7 +744,7 @@
 
   // Drain it a bit - will trigger.
   EXPECT_CALL(callbacks_, OnTotalBufferedAmountLow).Times(1);
-  absl::optional<SendQueue::DataToSend> chunk_two =
+  std::optional<SendQueue::DataToSend> chunk_two =
       buf_.Produce(kNow, kOneFragmentPacketSize);
 }
 
@@ -858,7 +858,7 @@
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload),
            SendOptions{.lifecycle_id = LifecycleId(2)});
 
-  absl::optional<SendQueue::DataToSend> chunk_one = buf_.Produce(kNow, 50);
+  std::optional<SendQueue::DataToSend> chunk_one = buf_.Produce(kNow, 50);
   ASSERT_TRUE(chunk_one.has_value());
   EXPECT_EQ(chunk_one->data.stream_id, kStreamID);
   EXPECT_EQ(buf_.total_buffered_amount(), 2 * payload.size() - 50);
@@ -876,7 +876,7 @@
   buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload),
            SendOptions{.lifecycle_id = LifecycleId(1)});
 
-  absl::optional<SendQueue::DataToSend> chunk_one =
+  std::optional<SendQueue::DataToSend> chunk_one =
       buf_.Produce(kNow, kOneFragmentPacketSize);
   ASSERT_TRUE(chunk_one.has_value());
   EXPECT_FALSE(chunk_one->data.is_end);
diff --git a/net/dcsctp/tx/send_queue.h b/net/dcsctp/tx/send_queue.h
index d0d834c..5f7ca2a 100644
--- a/net/dcsctp/tx/send_queue.h
+++ b/net/dcsctp/tx/send_queue.h
@@ -12,10 +12,10 @@
 
 #include <cstdint>
 #include <limits>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/units/timestamp.h"
 #include "net/dcsctp/common/internal_types.h"
@@ -56,8 +56,8 @@
   //
   // `max_size` refers to how many payload bytes that may be produced, not
   // including any headers.
-  virtual absl::optional<DataToSend> Produce(webrtc::Timestamp now,
-                                             size_t max_size) = 0;
+  virtual std::optional<DataToSend> Produce(webrtc::Timestamp now,
+                                            size_t max_size) = 0;
 
   // Discards a partially sent message identified by the parameters
   // `stream_id` and `message_id`. The `message_id` comes from the returned
diff --git a/net/dcsctp/tx/stream_scheduler.cc b/net/dcsctp/tx/stream_scheduler.cc
index 66c4457..c8984b8 100644
--- a/net/dcsctp/tx/stream_scheduler.cc
+++ b/net/dcsctp/tx/stream_scheduler.cc
@@ -10,9 +10,9 @@
 #include "net/dcsctp/tx/stream_scheduler.h"
 
 #include <algorithm>
+#include <optional>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/data.h"
 #include "net/dcsctp/public/dcsctp_message.h"
@@ -30,7 +30,7 @@
   inverse_weight_ = InverseWeight(priority);
 }
 
-absl::optional<SendQueue::DataToSend> StreamScheduler::Produce(
+std::optional<SendQueue::DataToSend> StreamScheduler::Produce(
     webrtc::Timestamp now,
     size_t max_size) {
   // For non-interleaved streams, avoid rescheduling while still sending a
@@ -50,7 +50,7 @@
 
   RTC_DCHECK(rescheduling || current_stream_ != nullptr);
 
-  absl::optional<SendQueue::DataToSend> data;
+  std::optional<SendQueue::DataToSend> data;
   while (!data.has_value() && !active_streams_.empty()) {
     if (rescheduling) {
       auto it = active_streams_.begin();
@@ -77,7 +77,7 @@
         << "There is no stream with data; Can't produce any data.";
     RTC_DCHECK(IsConsistent());
 
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   RTC_DCHECK(data->data.stream_id == current_stream_->stream_id());
@@ -126,10 +126,10 @@
   return VirtualTime(*current_virtual_time_ + 1);
 }
 
-absl::optional<SendQueue::DataToSend> StreamScheduler::Stream::Produce(
+std::optional<SendQueue::DataToSend> StreamScheduler::Stream::Produce(
     webrtc::Timestamp now,
     size_t max_size) {
-  absl::optional<SendQueue::DataToSend> data = producer_.Produce(now, max_size);
+  std::optional<SendQueue::DataToSend> data = producer_.Produce(now, max_size);
 
   if (data.has_value()) {
     VirtualTime new_current = CalculateFinishTime(data->data.payload.size());
diff --git a/net/dcsctp/tx/stream_scheduler.h b/net/dcsctp/tx/stream_scheduler.h
index 9d76fc6..f5377fa 100644
--- a/net/dcsctp/tx/stream_scheduler.h
+++ b/net/dcsctp/tx/stream_scheduler.h
@@ -15,6 +15,7 @@
 #include <deque>
 #include <map>
 #include <memory>
+#include <optional>
 #include <queue>
 #include <set>
 #include <string>
@@ -23,7 +24,6 @@
 #include "absl/algorithm/container.h"
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "net/dcsctp/packet/chunk/idata_chunk.h"
 #include "net/dcsctp/packet/sctp_packet.h"
@@ -86,9 +86,9 @@
     // as `now` and should be used to skip chunks with expired limited lifetime.
     // The parameter `max_size` specifies the maximum amount of actual payload
     // that may be returned. If these constraints prevents the stream from
-    // sending some data, `absl::nullopt` should be returned.
-    virtual absl::optional<SendQueue::DataToSend> Produce(webrtc::Timestamp now,
-                                                          size_t max_size) = 0;
+    // sending some data, `std::nullopt` should be returned.
+    virtual std::optional<SendQueue::DataToSend> Produce(webrtc::Timestamp now,
+                                                         size_t max_size) = 0;
 
     // Returns the number of payload bytes that is scheduled to be sent in the
     // next enqueued message, or zero if there are no enqueued messages or if
@@ -132,8 +132,8 @@
 
     // Produces a message from this stream. This will only be called on streams
     // that have data.
-    absl::optional<SendQueue::DataToSend> Produce(webrtc::Timestamp now,
-                                                  size_t max_size);
+    std::optional<SendQueue::DataToSend> Produce(webrtc::Timestamp now,
+                                                 size_t max_size);
 
     void MakeActive(size_t bytes_to_send_next);
     void ForceMarkInactive();
@@ -180,9 +180,9 @@
   // Produces a fragment of data to send. The current wall time is specified as
   // `now` and will be used to skip chunks with expired limited lifetime. The
   // parameter `max_size` specifies the maximum amount of actual payload that
-  // may be returned. If no data can be produced, `absl::nullopt` is returned.
-  absl::optional<SendQueue::DataToSend> Produce(webrtc::Timestamp now,
-                                                size_t max_size);
+  // may be returned. If no data can be produced, `std::nullopt` is returned.
+  std::optional<SendQueue::DataToSend> Produce(webrtc::Timestamp now,
+                                               size_t max_size);
 
   std::set<StreamID> ActiveStreamsForTesting() const;
 
diff --git a/net/dcsctp/tx/stream_scheduler_test.cc b/net/dcsctp/tx/stream_scheduler_test.cc
index 42d0b3c..a9b4612 100644
--- a/net/dcsctp/tx/stream_scheduler_test.cc
+++ b/net/dcsctp/tx/stream_scheduler_test.cc
@@ -40,7 +40,7 @@
   return true;
 }
 
-std::function<absl::optional<SendQueue::DataToSend>(Timestamp, size_t)>
+std::function<std::optional<SendQueue::DataToSend>(Timestamp, size_t)>
 CreateChunk(OutgoingMessageId message_id,
             StreamID sid,
             MID mid,
@@ -58,7 +58,7 @@
                                            size_t packets_to_generate) {
   std::map<StreamID, size_t> packet_counts;
   for (size_t i = 0; i < packets_to_generate; ++i) {
-    absl::optional<SendQueue::DataToSend> data = scheduler.Produce(kNow, kMtu);
+    std::optional<SendQueue::DataToSend> data = scheduler.Produce(kNow, kMtu);
     if (data.has_value()) {
       ++packet_counts[data->data.stream_id];
     }
@@ -68,7 +68,7 @@
 
 class MockStreamProducer : public StreamScheduler::StreamProducer {
  public:
-  MOCK_METHOD(absl::optional<SendQueue::DataToSend>,
+  MOCK_METHOD(std::optional<SendQueue::DataToSend>,
               Produce,
               (Timestamp, size_t),
               (override));
@@ -101,7 +101,7 @@
 TEST(StreamSchedulerTest, HasNoActiveStreams) {
   StreamScheduler scheduler("", kMtu);
 
-  EXPECT_EQ(scheduler.Produce(kNow, kMtu), absl::nullopt);
+  EXPECT_EQ(scheduler.Produce(kNow, kMtu), std::nullopt);
 }
 
 // Stream properties can be set and retrieved
@@ -134,7 +134,7 @@
   stream->MaybeMakeActive();
 
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(0)));
-  EXPECT_EQ(scheduler.Produce(kNow, kMtu), absl::nullopt);
+  EXPECT_EQ(scheduler.Produce(kNow, kMtu), std::nullopt);
 }
 
 // Switches between two streams after every packet.
@@ -175,7 +175,7 @@
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(201)));
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(102)));
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(202)));
-  EXPECT_EQ(scheduler.Produce(kNow, kMtu), absl::nullopt);
+  EXPECT_EQ(scheduler.Produce(kNow, kMtu), std::nullopt);
 }
 
 // Switches between two streams after every packet, but keeps producing from the
@@ -241,7 +241,7 @@
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(201)));
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(102)));
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(202)));
-  EXPECT_EQ(scheduler.Produce(kNow, kMtu), absl::nullopt);
+  EXPECT_EQ(scheduler.Produce(kNow, kMtu), std::nullopt);
 }
 
 // Deactivates a stream before it has finished producing all packets.
@@ -265,7 +265,7 @@
 
   // ... but the stream is made inactive before it can be produced.
   stream1->MakeInactive();
-  EXPECT_EQ(scheduler.Produce(kNow, kMtu), absl::nullopt);
+  EXPECT_EQ(scheduler.Produce(kNow, kMtu), std::nullopt);
 }
 
 // Resumes a paused stream - makes a stream active after inactivating it.
@@ -292,10 +292,10 @@
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(101)));
 
   stream1->MakeInactive();
-  EXPECT_EQ(scheduler.Produce(kNow, kMtu), absl::nullopt);
+  EXPECT_EQ(scheduler.Produce(kNow, kMtu), std::nullopt);
   stream1->MaybeMakeActive();
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(102)));
-  EXPECT_EQ(scheduler.Produce(kNow, kMtu), absl::nullopt);
+  EXPECT_EQ(scheduler.Produce(kNow, kMtu), std::nullopt);
 }
 
 // Iterates between streams, where one is suddenly paused and later resumed.
@@ -339,7 +339,7 @@
   stream1->MaybeMakeActive();
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(101)));
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(102)));
-  EXPECT_EQ(scheduler.Produce(kNow, kMtu), absl::nullopt);
+  EXPECT_EQ(scheduler.Produce(kNow, kMtu), std::nullopt);
 }
 
 // Verifies that packet counts are evenly distributed in round robin scheduling.
@@ -439,7 +439,7 @@
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(201)));
   // t = 210
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(202)));
-  EXPECT_EQ(scheduler.Produce(kNow, kMtu), absl::nullopt);
+  EXPECT_EQ(scheduler.Produce(kNow, kMtu), std::nullopt);
 }
 
 // Will do weighted fair queuing with three streams having different priority.
@@ -510,7 +510,7 @@
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(101)));
   // t ~= 240
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(102)));
-  EXPECT_EQ(scheduler.Produce(kNow, kMtu), absl::nullopt);
+  EXPECT_EQ(scheduler.Produce(kNow, kMtu), std::nullopt);
 }
 
 // Will do weighted fair queuing with three streams having different priority
@@ -604,7 +604,7 @@
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(202)));
   // t ~= 11200
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(102)));
-  EXPECT_EQ(scheduler.Produce(kNow, kMtu), absl::nullopt);
+  EXPECT_EQ(scheduler.Produce(kNow, kMtu), std::nullopt);
 }
 TEST(StreamSchedulerTest, WillDistributeWFQPacketsInTwoStreamsByPriority) {
   // A simple test with two streams of different priority, but sending packets
@@ -728,7 +728,7 @@
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(1)));
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(1)));
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(0)));
-  EXPECT_EQ(scheduler.Produce(kNow, kMtu), absl::nullopt);
+  EXPECT_EQ(scheduler.Produce(kNow, kMtu), std::nullopt);
 }
 
 // Sending large messages with large MTU will not fragment messages and will
@@ -759,7 +759,7 @@
   stream2->MaybeMakeActive();
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(1)));
   EXPECT_THAT(scheduler.Produce(kNow, kMtu), HasDataWithMid(MID(0)));
-  EXPECT_EQ(scheduler.Produce(kNow, kMtu), absl::nullopt);
+  EXPECT_EQ(scheduler.Produce(kNow, kMtu), std::nullopt);
 }
 
 }  // namespace
diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn
index 73d5809..5802599 100644
--- a/p2p/BUILD.gn
+++ b/p2p/BUILD.gn
@@ -159,7 +159,6 @@
     "//third_party/abseil-cpp/absl/functional:any_invocable",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -180,7 +179,6 @@
     ":ice_transport_internal",
     ":transport_description",
     "../api:array_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -360,7 +358,6 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/functional:any_invocable",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -372,7 +369,6 @@
   deps = [
     "../api:candidate",
     "../api/units:timestamp",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -472,7 +468,6 @@
     ":ice_transport_internal",
     "../rtc_base:checks",
     "../rtc_base/system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -524,7 +519,6 @@
     "../rtc_base/system:rtc_export",
     "../rtc_base/third_party/sigslot",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -598,13 +592,11 @@
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
 rtc_source_set("p2p_transport_channel_ice_field_trials") {
   sources = [ "base/p2p_transport_channel_ice_field_trials.h" ]
-  deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
 }
 
 rtc_library("packet_transport_internal") {
@@ -624,7 +616,6 @@
     "../rtc_base/system:rtc_export",
     "../rtc_base/third_party/sigslot",
     "//third_party/abseil-cpp/absl/functional:any_invocable",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -679,7 +670,6 @@
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -706,7 +696,6 @@
     "../rtc_base/system:rtc_export",
     "../rtc_base/third_party/sigslot",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -725,7 +714,6 @@
     "../rtc_base:callback_list",
     "../rtc_base:socket_address",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -862,7 +850,6 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -926,7 +913,6 @@
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -975,7 +961,6 @@
     "../rtc_base:macromagic",
     "../rtc_base:threading",
     "../rtc_base:timeutils",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -996,7 +981,6 @@
       "../rtc_base/network:received_packet",
       "//third_party/abseil-cpp/absl/algorithm:container",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -1186,7 +1170,6 @@
       "//third_party/abseil-cpp/absl/algorithm:container",
       "//third_party/abseil-cpp/absl/memory",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
diff --git a/p2p/base/active_ice_controller_interface.h b/p2p/base/active_ice_controller_interface.h
index e54838e..30de264 100644
--- a/p2p/base/active_ice_controller_interface.h
+++ b/p2p/base/active_ice_controller_interface.h
@@ -11,7 +11,8 @@
 #ifndef P2P_BASE_ACTIVE_ICE_CONTROLLER_INTERFACE_H_
 #define P2P_BASE_ACTIVE_ICE_CONTROLLER_INTERFACE_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/array_view.h"
 #include "p2p/base/connection.h"
 #include "p2p/base/ice_switch_reason.h"
diff --git a/p2p/base/basic_ice_controller.cc b/p2p/base/basic_ice_controller.cc
index f5b3eca..64c6971 100644
--- a/p2p/base/basic_ice_controller.cc
+++ b/p2p/base/basic_ice_controller.cc
@@ -32,7 +32,7 @@
 
 bool LocalCandidateUsesPreferredNetwork(
     const cricket::Connection* conn,
-    absl::optional<rtc::AdapterType> network_preference) {
+    std::optional<rtc::AdapterType> network_preference) {
   rtc::AdapterType network_type = conn->network()->type();
   return network_preference.has_value() && (network_type == network_preference);
 }
@@ -40,7 +40,7 @@
 int CompareCandidatePairsByNetworkPreference(
     const cricket::Connection* a,
     const cricket::Connection* b,
-    absl::optional<rtc::AdapterType> network_preference) {
+    std::optional<rtc::AdapterType> network_preference) {
   bool a_uses_preferred_network =
       LocalCandidateUsesPreferredNetwork(a, network_preference);
   bool b_uses_preferred_network =
@@ -420,7 +420,7 @@
   if (!field_trials_->initial_select_dampening.has_value() &&
       !field_trials_->initial_select_dampening_ping_received.has_value()) {
     // experiment not enabled => select connection.
-    return {new_connection, absl::nullopt};
+    return {new_connection, std::nullopt};
   }
 
   int64_t now = rtc::TimeMillis();
@@ -441,7 +441,7 @@
                      << initial_select_timestamp_ms_
                      << " selection delayed by: " << (now - start_wait) << "ms";
     initial_select_timestamp_ms_ = 0;
-    return {new_connection, absl::nullopt};
+    return {new_connection, std::nullopt};
   }
 
   // We are not yet ready to select first connection...
@@ -464,7 +464,7 @@
   }
 
   RTC_LOG(LS_INFO) << "delay initial selection up to " << min_delay << "ms";
-  return {.connection = absl::nullopt,
+  return {.connection = std::nullopt,
           .recheck_event = IceRecheckEvent(
               IceSwitchReason::ICE_CONTROLLER_RECHECK, min_delay)};
 }
@@ -473,7 +473,7 @@
     IceSwitchReason reason,
     const Connection* new_connection) {
   if (!ReadyToSend(new_connection) || selected_connection_ == new_connection) {
-    return {absl::nullopt, absl::nullopt};
+    return {std::nullopt, std::nullopt};
   }
 
   if (selected_connection_ == nullptr) {
@@ -486,17 +486,17 @@
   int compare_a_b_by_networks = CompareCandidatePairNetworks(
       new_connection, selected_connection_, config_.network_preference);
   if (compare_a_b_by_networks == b_is_better && !new_connection->receiving()) {
-    return {absl::nullopt, absl::nullopt};
+    return {std::nullopt, std::nullopt};
   }
 
   bool missed_receiving_unchanged_threshold = false;
-  absl::optional<int64_t> receiving_unchanged_threshold(
+  std::optional<int64_t> receiving_unchanged_threshold(
       rtc::TimeMillis() - config_.receiving_switching_delay_or_default());
   int cmp = CompareConnections(selected_connection_, new_connection,
                                receiving_unchanged_threshold,
                                &missed_receiving_unchanged_threshold);
 
-  absl::optional<IceRecheckEvent> recheck_event;
+  std::optional<IceRecheckEvent> recheck_event;
   if (missed_receiving_unchanged_threshold &&
       config_.receiving_switching_delay_or_default()) {
     // If we do not switch to the connection because it missed the receiving
@@ -508,18 +508,18 @@
   }
 
   if (cmp < 0) {
-    return {new_connection, absl::nullopt};
+    return {new_connection, std::nullopt};
   } else if (cmp > 0) {
-    return {absl::nullopt, recheck_event};
+    return {std::nullopt, recheck_event};
   }
 
   // If everything else is the same, switch only if rtt has improved by
   // a margin.
   if (new_connection->rtt() <= selected_connection_->rtt() - kMinImprovement) {
-    return {new_connection, absl::nullopt};
+    return {new_connection, std::nullopt};
   }
 
-  return {absl::nullopt, recheck_event};
+  return {std::nullopt, recheck_event};
 }
 
 IceControllerInterface::SwitchResult
@@ -531,7 +531,7 @@
   // TODO(honghaiz): Don't sort;  Just use std::max_element in the right places.
   absl::c_stable_sort(
       connections_, [this](const Connection* a, const Connection* b) {
-        int cmp = CompareConnections(a, b, absl::nullopt, nullptr);
+        int cmp = CompareConnections(a, b, std::nullopt, nullptr);
         if (cmp != 0) {
           return cmp > 0;
         }
@@ -575,7 +575,7 @@
 int BasicIceController::CompareConnectionStates(
     const Connection* a,
     const Connection* b,
-    absl::optional<int64_t> receiving_unchanged_threshold,
+    std::optional<int64_t> receiving_unchanged_threshold,
     bool* missed_receiving_unchanged_threshold) const {
   // First, prefer a connection that's writable or presumed writable over
   // one that's not writable.
@@ -693,7 +693,7 @@
 int BasicIceController::CompareConnections(
     const Connection* a,
     const Connection* b,
-    absl::optional<int64_t> receiving_unchanged_threshold,
+    std::optional<int64_t> receiving_unchanged_threshold,
     bool* missed_receiving_unchanged_threshold) const {
   RTC_CHECK(a != nullptr);
   RTC_CHECK(b != nullptr);
@@ -732,7 +732,7 @@
 int BasicIceController::CompareCandidatePairNetworks(
     const Connection* a,
     const Connection* b,
-    absl::optional<rtc::AdapterType> network_preference) const {
+    std::optional<rtc::AdapterType> network_preference) const {
   int compare_a_b_by_network_preference =
       CompareCandidatePairsByNetworkPreference(a, b,
                                                config_.network_preference);
diff --git a/p2p/base/basic_ice_controller.h b/p2p/base/basic_ice_controller.h
index f9f4d45..dfb99ea 100644
--- a/p2p/base/basic_ice_controller.h
+++ b/p2p/base/basic_ice_controller.h
@@ -112,7 +112,7 @@
   int CompareCandidatePairNetworks(
       const Connection* a,
       const Connection* b,
-      absl::optional<rtc::AdapterType> network_preference) const;
+      std::optional<rtc::AdapterType> network_preference) const;
 
   // The methods below return a positive value if `a` is preferable to `b`,
   // a negative value if `b` is preferable, and 0 if they're equally preferable.
@@ -124,7 +124,7 @@
   int CompareConnectionStates(
       const Connection* a,
       const Connection* b,
-      absl::optional<int64_t> receiving_unchanged_threshold,
+      std::optional<int64_t> receiving_unchanged_threshold,
       bool* missed_receiving_unchanged_threshold) const;
   int CompareConnectionCandidates(const Connection* a,
                                   const Connection* b) const;
@@ -135,7 +135,7 @@
   // Returns a positive value if `a` is better than `b`.
   int CompareConnections(const Connection* a,
                          const Connection* b,
-                         absl::optional<int64_t> receiving_unchanged_threshold,
+                         std::optional<int64_t> receiving_unchanged_threshold,
                          bool* missed_receiving_unchanged_threshold) const;
 
   SwitchResult HandleInitialSelectDampening(IceSwitchReason reason,
diff --git a/p2p/base/connection.cc b/p2p/base/connection.cc
index 762b692..bb79096 100644
--- a/p2p/base/connection.cc
+++ b/p2p/base/connection.cc
@@ -15,12 +15,12 @@
 #include <algorithm>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/units/timestamp.h"
 #include "p2p/base/p2p_constants.h"
@@ -387,7 +387,7 @@
   return unwritable_timeout_.value_or(CONNECTION_WRITE_CONNECT_TIMEOUT);
 }
 
-void Connection::set_unwritable_timeout(const absl::optional<int>& value_ms) {
+void Connection::set_unwritable_timeout(const std::optional<int>& value_ms) {
   RTC_DCHECK_RUN_ON(network_thread_);
   unwritable_timeout_ = value_ms;
 }
@@ -397,7 +397,7 @@
   return unwritable_min_checks_.value_or(CONNECTION_WRITE_CONNECT_FAILURES);
 }
 
-void Connection::set_unwritable_min_checks(const absl::optional<int>& value) {
+void Connection::set_unwritable_min_checks(const std::optional<int>& value) {
   RTC_DCHECK_RUN_ON(network_thread_);
   unwritable_min_checks_ = value;
 }
@@ -407,7 +407,7 @@
   return inactive_timeout_.value_or(CONNECTION_WRITE_TIMEOUT);
 }
 
-void Connection::set_inactive_timeout(const absl::optional<int>& value) {
+void Connection::set_inactive_timeout(const std::optional<int>& value) {
   RTC_DCHECK_RUN_ON(network_thread_);
   inactive_timeout_ = value;
 }
@@ -418,7 +418,7 @@
 }
 
 void Connection::set_receiving_timeout(
-    absl::optional<int> receiving_timeout_ms) {
+    std::optional<int> receiving_timeout_ms) {
   RTC_DCHECK_RUN_ON(network_thread_);
   receiving_timeout_ = receiving_timeout_ms;
 }
@@ -1095,7 +1095,7 @@
   return last_ping_response_received_;
 }
 
-const absl::optional<std::string>& Connection::last_ping_id_received() const {
+const std::optional<std::string>& Connection::last_ping_id_received() const {
   RTC_DCHECK_RUN_ON(network_thread_);
   return last_ping_id_received_;
 }
@@ -1113,7 +1113,7 @@
   return last_ping_received_;
 }
 
-void Connection::ReceivedPing(const absl::optional<std::string>& request_id) {
+void Connection::ReceivedPing(const std::optional<std::string>& request_id) {
   RTC_DCHECK_RUN_ON(network_thread_);
   last_ping_received_ = rtc::TimeMillis();
   last_ping_id_received_ = request_id;
@@ -1156,7 +1156,7 @@
 void Connection::ReceivedPingResponse(
     int rtt,
     absl::string_view request_id,
-    const absl::optional<uint32_t>& nomination) {
+    const std::optional<uint32_t>& nomination) {
   RTC_DCHECK_RUN_ON(network_thread_);
   RTC_DCHECK_GE(rtt, 0);
   // We've already validated that this is a STUN binding response with
@@ -1420,7 +1420,7 @@
                       ", rtt="
                    << rtt << ", pings_since_last_response=" << pings;
   }
-  absl::optional<uint32_t> nomination;
+  std::optional<uint32_t> nomination;
   const std::string request_id = request->id();
   auto iter = absl::c_find_if(
       pings_since_last_response_,
@@ -1563,7 +1563,7 @@
   }
   // TODO(deadbeef): A value of '0' for the generation is used for both
   // generation 0 and "generation unknown". It should be changed to an
-  // absl::optional to fix this.
+  // std::optional to fix this.
   if (remote_candidate_.username() == ice_params.ufrag &&
       remote_candidate_.password() == ice_params.pwd &&
       remote_candidate_.generation() == 0) {
@@ -1725,7 +1725,7 @@
 }
 
 bool Connection::TooManyOutstandingPings(
-    const absl::optional<int>& max_outstanding_pings) const {
+    const std::optional<int>& max_outstanding_pings) const {
   RTC_DCHECK_RUN_ON(network_thread_);
   if (!max_outstanding_pings.has_value()) {
     return false;
diff --git a/p2p/base/connection.h b/p2p/base/connection.h
index 583e62e..8079a56 100644
--- a/p2p/base/connection.h
+++ b/p2p/base/connection.h
@@ -16,6 +16,7 @@
 #include <cstdint>
 #include <functional>
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <utility>
@@ -23,7 +24,6 @@
 
 #include "absl/functional/any_invocable.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/candidate.h"
 #include "api/rtc_error.h"
 #include "api/sequence_checker.h"
@@ -121,11 +121,11 @@
   int rtt() const;
 
   int unwritable_timeout() const;
-  void set_unwritable_timeout(const absl::optional<int>& value_ms);
+  void set_unwritable_timeout(const std::optional<int>& value_ms);
   int unwritable_min_checks() const;
-  void set_unwritable_min_checks(const absl::optional<int>& value);
+  void set_unwritable_min_checks(const std::optional<int>& value);
   int inactive_timeout() const;
-  void set_inactive_timeout(const absl::optional<int>& value);
+  void set_inactive_timeout(const std::optional<int>& value);
 
   // Gets the `ConnectionInfo` stats, where `best_connection` has not been
   // populated (default value false).
@@ -186,7 +186,7 @@
   bool nominated() const;
 
   int receiving_timeout() const;
-  void set_receiving_timeout(absl::optional<int> receiving_timeout_ms);
+  void set_receiving_timeout(std::optional<int> receiving_timeout_ms);
 
   // Deletes a `Connection` instance is by calling the `DestroyConnection`
   // method in `Port`.
@@ -219,13 +219,13 @@
   void ReceivedPingResponse(
       int rtt,
       absl::string_view request_id,
-      const absl::optional<uint32_t>& nomination = absl::nullopt);
+      const std::optional<uint32_t>& nomination = std::nullopt);
   std::unique_ptr<IceMessage> BuildPingRequest(
       std::unique_ptr<StunByteStringAttribute> delta)
       RTC_RUN_ON(network_thread_);
 
   int64_t last_ping_response_received() const;
-  const absl::optional<std::string>& last_ping_id_received() const;
+  const std::optional<std::string>& last_ping_id_received() const;
 
   // Used to check if any STUN ping response has been received.
   int rtt_samples() const;
@@ -235,7 +235,7 @@
   int64_t last_ping_received() const;
 
   void ReceivedPing(
-      const absl::optional<std::string>& request_id = absl::nullopt);
+      const std::optional<std::string>& request_id = std::nullopt);
   // Handles the binding request; sends a response if this is a valid request.
   void HandleStunBindingOrGoogPingRequest(IceMessage* msg);
   // Handles the piggyback acknowledgement of the lastest connectivity check
@@ -297,7 +297,7 @@
   bool stable(int64_t now) const;
 
   // Check if we sent `val` pings without receving a response.
-  bool TooManyOutstandingPings(const absl::optional<int>& val) const;
+  bool TooManyOutstandingPings(const std::optional<int>& val) const;
 
   // Called by Port when the network cost changes.
   void SetLocalCandidateNetworkCost(uint16_t cost);
@@ -355,8 +355,8 @@
   }
 
   void ClearStunDictConsumer() {
-    goog_delta_consumer_ = absl::nullopt;
-    goog_delta_ack_consumer_ = absl::nullopt;
+    goog_delta_consumer_ = std::nullopt;
+    goog_delta_ack_consumer_ = std::nullopt;
   }
 
  protected:
@@ -459,7 +459,7 @@
   // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-totalroundtriptime
   uint64_t total_round_trip_time_ms_ RTC_GUARDED_BY(network_thread_) = 0;
   // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-currentroundtriptime
-  absl::optional<uint32_t> current_round_trip_time_ms_
+  std::optional<uint32_t> current_round_trip_time_ms_
       RTC_GUARDED_BY(network_thread_);
   int64_t last_ping_sent_ RTC_GUARDED_BY(
       network_thread_);  // last time we sent a ping to the other side
@@ -473,21 +473,21 @@
       RTC_GUARDED_BY(network_thread_);
   // Transaction ID of the last connectivity check received. Null if having not
   // received a ping yet.
-  absl::optional<std::string> last_ping_id_received_
+  std::optional<std::string> last_ping_id_received_
       RTC_GUARDED_BY(network_thread_);
 
-  absl::optional<int> unwritable_timeout_ RTC_GUARDED_BY(network_thread_);
-  absl::optional<int> unwritable_min_checks_ RTC_GUARDED_BY(network_thread_);
-  absl::optional<int> inactive_timeout_ RTC_GUARDED_BY(network_thread_);
+  std::optional<int> unwritable_timeout_ RTC_GUARDED_BY(network_thread_);
+  std::optional<int> unwritable_min_checks_ RTC_GUARDED_BY(network_thread_);
+  std::optional<int> inactive_timeout_ RTC_GUARDED_BY(network_thread_);
 
   IceCandidatePairState state_ RTC_GUARDED_BY(network_thread_);
   // Time duration to switch from receiving to not receiving.
-  absl::optional<int> receiving_timeout_ RTC_GUARDED_BY(network_thread_);
+  std::optional<int> receiving_timeout_ RTC_GUARDED_BY(network_thread_);
   const int64_t time_created_ms_ RTC_GUARDED_BY(network_thread_);
   const int64_t delta_internal_unix_epoch_ms_ RTC_GUARDED_BY(network_thread_);
   int num_pings_sent_ RTC_GUARDED_BY(network_thread_) = 0;
 
-  absl::optional<webrtc::IceCandidatePairDescription> log_description_
+  std::optional<webrtc::IceCandidatePairDescription> log_description_
       RTC_GUARDED_BY(network_thread_);
   webrtc::IceEventLog* ice_event_log_ RTC_GUARDED_BY(network_thread_) = nullptr;
 
@@ -495,8 +495,7 @@
   // if configured via field trial, the remote peer supports it (signaled
   // in STUN_BINDING) and if the last STUN BINDING is identical to the one
   // that is about to be sent.
-  absl::optional<bool> remote_support_goog_ping_
-      RTC_GUARDED_BY(network_thread_);
+  std::optional<bool> remote_support_goog_ping_ RTC_GUARDED_BY(network_thread_);
   std::unique_ptr<StunMessage> cached_stun_binding_
       RTC_GUARDED_BY(network_thread_);
 
@@ -504,10 +503,10 @@
   rtc::EventBasedExponentialMovingAverage rtt_estimate_
       RTC_GUARDED_BY(network_thread_);
 
-  absl::optional<std::function<std::unique_ptr<StunAttribute>(
+  std::optional<std::function<std::unique_ptr<StunAttribute>(
       const StunByteStringAttribute*)>>
       goog_delta_consumer_;
-  absl::optional<
+  std::optional<
       std::function<void(webrtc::RTCErrorOr<const StunUInt64Attribute*>)>>
       goog_delta_ack_consumer_;
   absl::AnyInvocable<void(Connection*, const rtc::ReceivedPacket&)>
diff --git a/p2p/base/connection_info.h b/p2p/base/connection_info.h
index e7ed1b4..333c9b1 100644
--- a/p2p/base/connection_info.h
+++ b/p2p/base/connection_info.h
@@ -11,9 +11,9 @@
 #ifndef P2P_BASE_CONNECTION_INFO_H_
 #define P2P_BASE_CONNECTION_INFO_H_
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/candidate.h"
 #include "api/units/timestamp.h"
 
@@ -72,11 +72,11 @@
   // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-totalroundtriptime
   uint64_t total_round_trip_time_ms;
   // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-currentroundtriptime
-  absl::optional<uint32_t> current_round_trip_time_ms;
+  std::optional<uint32_t> current_round_trip_time_ms;
 
   // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-lastpacketreceivedtimestamp
-  absl::optional<webrtc::Timestamp> last_data_received;
-  absl::optional<webrtc::Timestamp> last_data_sent;
+  std::optional<webrtc::Timestamp> last_data_received;
+  std::optional<webrtc::Timestamp> last_data_sent;
 };
 
 // Information about all the candidate pairs of a channel.
diff --git a/p2p/base/dtls_transport.cc b/p2p/base/dtls_transport.cc
index 11ebaf7..27d1849 100644
--- a/p2p/base/dtls_transport.cc
+++ b/p2p/base/dtls_transport.cc
@@ -237,7 +237,7 @@
     absl::string_view digest_alg,
     const uint8_t* digest,
     size_t digest_len,
-    absl::optional<rtc::SSLRole> role) {
+    std::optional<rtc::SSLRole> role) {
   rtc::Buffer remote_fingerprint_value(digest, digest_len);
   bool is_dtls_restart =
       dtls_active_ && remote_fingerprint_value_ != remote_fingerprint_value;
@@ -506,7 +506,7 @@
   return ice_transport_->GetError();
 }
 
-absl::optional<rtc::NetworkRoute> DtlsTransport::network_route() const {
+std::optional<rtc::NetworkRoute> DtlsTransport::network_route() const {
   return ice_transport_->network_route();
 }
 
@@ -759,7 +759,7 @@
 }
 
 void DtlsTransport::OnNetworkRouteChanged(
-    absl::optional<rtc::NetworkRoute> network_route) {
+    std::optional<rtc::NetworkRoute> network_route) {
   RTC_DCHECK_RUN_ON(&thread_checker_);
   SignalNetworkRouteChanged(network_route);
 }
@@ -872,7 +872,7 @@
 
 void DtlsTransport::ConfigureHandshakeTimeout() {
   RTC_DCHECK(dtls_);
-  absl::optional<int> rtt = ice_transport_->GetRttEstimate();
+  std::optional<int> rtt = ice_transport_->GetRttEstimate();
   if (rtt) {
     // Limit the timeout to a reasonable range in case the ICE RTT takes
     // extreme values.
diff --git a/p2p/base/dtls_transport.h b/p2p/base/dtls_transport.h
index ceeaa84..02249c2 100644
--- a/p2p/base/dtls_transport.h
+++ b/p2p/base/dtls_transport.h
@@ -143,7 +143,7 @@
       absl::string_view digest_alg,
       const uint8_t* digest,
       size_t digest_len,
-      absl::optional<rtc::SSLRole> role) override;
+      std::optional<rtc::SSLRole> role) override;
 
   // Called to send a packet (via DTLS, if turned on).
   int SendPacket(const char* data,
@@ -198,7 +198,7 @@
 
   int GetError() override;
 
-  absl::optional<rtc::NetworkRoute> network_route() const override;
+  std::optional<rtc::NetworkRoute> network_route() const override;
 
   int SetOption(rtc::Socket::Option opt, int value) override;
 
@@ -222,7 +222,7 @@
   void OnReadyToSend(rtc::PacketTransportInternal* transport);
   void OnReceivingState(rtc::PacketTransportInternal* transport);
   void OnDtlsEvent(int sig, int err);
-  void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route);
+  void OnNetworkRouteChanged(std::optional<rtc::NetworkRoute> network_route);
   bool SetupDtls();
   void MaybeStartDtls();
   bool HandleDtlsPacket(rtc::ArrayView<const uint8_t> payload);
@@ -246,7 +246,7 @@
   const std::vector<int> srtp_ciphers_;  // SRTP ciphers to use with DTLS.
   bool dtls_active_ = false;
   rtc::scoped_refptr<rtc::RTCCertificate> local_certificate_;
-  absl::optional<rtc::SSLRole> dtls_role_;
+  std::optional<rtc::SSLRole> dtls_role_;
   const rtc::SSLProtocolVersion ssl_max_version_;
   rtc::Buffer remote_fingerprint_value_;
   std::string remote_fingerprint_algorithm_;
diff --git a/p2p/base/dtls_transport_internal.h b/p2p/base/dtls_transport_internal.h
index cbcd2bd..548f59d 100644
--- a/p2p/base/dtls_transport_internal.h
+++ b/p2p/base/dtls_transport_internal.h
@@ -106,7 +106,7 @@
       absl::string_view digest_alg,
       const uint8_t* digest,
       size_t digest_len,
-      absl::optional<rtc::SSLRole> role) = 0;
+      std::optional<rtc::SSLRole> role) = 0;
 
   ABSL_DEPRECATED("Set the max version via construction.")
   bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) {
diff --git a/p2p/base/dtls_transport_unittest.cc b/p2p/base/dtls_transport_unittest.cc
index 9e2d069..767fc4d 100644
--- a/p2p/base/dtls_transport_unittest.cc
+++ b/p2p/base/dtls_transport_unittest.cc
@@ -66,7 +66,7 @@
           ->SetRemoteParameters(
               fingerprint->algorithm,
               reinterpret_cast<const uint8_t*>(fingerprint->digest.data()),
-              fingerprint->digest.size(), absl::nullopt)
+              fingerprint->digest.size(), std::nullopt)
           .ok());
 }
 
diff --git a/p2p/base/fake_dtls_transport.h b/p2p/base/fake_dtls_transport.h
index a088030..bbcbe43 100644
--- a/p2p/base/fake_dtls_transport.h
+++ b/p2p/base/fake_dtls_transport.h
@@ -152,7 +152,7 @@
   webrtc::RTCError SetRemoteParameters(absl::string_view alg,
                                        const uint8_t* digest,
                                        size_t digest_len,
-                                       absl::optional<rtc::SSLRole> role) {
+                                       std::optional<rtc::SSLRole> role) {
     if (role) {
       SetDtlsRole(*role);
     }
@@ -210,7 +210,7 @@
     }
     return false;
   }
-  void SetSslCipherSuite(absl::optional<int> cipher_suite) {
+  void SetSslCipherSuite(std::optional<int> cipher_suite) {
     ssl_cipher_suite_ = cipher_suite;
   }
   uint16_t GetSslPeerSignatureAlgorithm() const override { return 0; }
@@ -266,7 +266,7 @@
   }
   int GetError() override { return ice_transport_->GetError(); }
 
-  absl::optional<rtc::NetworkRoute> network_route() const override {
+  std::optional<rtc::NetworkRoute> network_route() const override {
     return ice_transport_->network_route();
   }
 
@@ -295,7 +295,7 @@
     SignalWritableState(this);
   }
 
-  void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
+  void OnNetworkRouteChanged(std::optional<rtc::NetworkRoute> network_route) {
     SignalNetworkRouteChanged(network_route);
   }
 
@@ -309,9 +309,9 @@
   bool do_dtls_ = false;
   rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12;
   rtc::SSLFingerprint dtls_fingerprint_;
-  absl::optional<rtc::SSLRole> dtls_role_;
+  std::optional<rtc::SSLRole> dtls_role_;
   int crypto_suite_ = rtc::kSrtpAes128CmSha1_80;
-  absl::optional<int> ssl_cipher_suite_;
+  std::optional<int> ssl_cipher_suite_;
 
   webrtc::DtlsTransportState dtls_state_ = webrtc::DtlsTransportState::kNew;
 
diff --git a/p2p/base/fake_ice_transport.h b/p2p/base/fake_ice_transport.h
index 788299b..cc7ccc1 100644
--- a/p2p/base/fake_ice_transport.h
+++ b/p2p/base/fake_ice_transport.h
@@ -13,12 +13,12 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/ice_transport_interface.h"
 #include "api/task_queue/pending_task_safety_flag.h"
 #include "api/units/time_delta.h"
@@ -270,12 +270,11 @@
     return true;
   }
 
-  absl::optional<int> GetRttEstimate() override { return absl::nullopt; }
+  std::optional<int> GetRttEstimate() override { return std::nullopt; }
 
   const Connection* selected_connection() const override { return nullptr; }
-  absl::optional<const CandidatePair> GetSelectedCandidatePair()
-      const override {
-    return absl::nullopt;
+  std::optional<const CandidatePair> GetSelectedCandidatePair() const override {
+    return std::nullopt;
   }
 
   // Fake PacketTransportInternal implementation.
@@ -345,11 +344,11 @@
     return last_sent_packet_;
   }
 
-  absl::optional<rtc::NetworkRoute> network_route() const override {
+  std::optional<rtc::NetworkRoute> network_route() const override {
     RTC_DCHECK_RUN_ON(network_thread_);
     return network_route_;
   }
-  void SetNetworkRoute(absl::optional<rtc::NetworkRoute> network_route) {
+  void SetNetworkRoute(std::optional<rtc::NetworkRoute> network_route) {
     RTC_DCHECK_RUN_ON(network_thread_);
     network_route_ = network_route;
     SendTask(network_thread_, [this] {
@@ -402,9 +401,9 @@
   IceParameters remote_ice_parameters_ RTC_GUARDED_BY(network_thread_);
   IceMode remote_ice_mode_ RTC_GUARDED_BY(network_thread_) = ICEMODE_FULL;
   size_t connection_count_ RTC_GUARDED_BY(network_thread_) = 0;
-  absl::optional<webrtc::IceTransportState> transport_state_
+  std::optional<webrtc::IceTransportState> transport_state_
       RTC_GUARDED_BY(network_thread_);
-  absl::optional<IceTransportState> legacy_transport_state_
+  std::optional<IceTransportState> legacy_transport_state_
       RTC_GUARDED_BY(network_thread_);
   IceGatheringState gathering_state_ RTC_GUARDED_BY(network_thread_) =
       kIceGatheringNew;
@@ -413,7 +412,7 @@
   bool receiving_ RTC_GUARDED_BY(network_thread_) = false;
   bool combine_outgoing_packets_ RTC_GUARDED_BY(network_thread_) = false;
   rtc::CopyOnWriteBuffer send_packet_ RTC_GUARDED_BY(network_thread_);
-  absl::optional<rtc::NetworkRoute> network_route_
+  std::optional<rtc::NetworkRoute> network_route_
       RTC_GUARDED_BY(network_thread_);
   std::map<rtc::Socket::Option, int> socket_options_
       RTC_GUARDED_BY(network_thread_);
diff --git a/p2p/base/fake_packet_transport.h b/p2p/base/fake_packet_transport.h
index a7388f5..e747af5 100644
--- a/p2p/base/fake_packet_transport.h
+++ b/p2p/base/fake_packet_transport.h
@@ -91,10 +91,10 @@
 
   const CopyOnWriteBuffer* last_sent_packet() { return &last_sent_packet_; }
 
-  absl::optional<NetworkRoute> network_route() const override {
+  std::optional<NetworkRoute> network_route() const override {
     return network_route_;
   }
-  void SetNetworkRoute(absl::optional<NetworkRoute> network_route) {
+  void SetNetworkRoute(std::optional<NetworkRoute> network_route) {
     network_route_ = network_route;
     SignalNetworkRouteChanged(network_route);
   }
@@ -141,7 +141,7 @@
   std::map<Socket::Option, int> options_;
   int error_ = 0;
 
-  absl::optional<NetworkRoute> network_route_;
+  std::optional<NetworkRoute> network_route_;
 };
 
 }  // namespace rtc
diff --git a/p2p/base/ice_controller_interface.h b/p2p/base/ice_controller_interface.h
index fb421cf..011ca85 100644
--- a/p2p/base/ice_controller_interface.h
+++ b/p2p/base/ice_controller_interface.h
@@ -11,11 +11,11 @@
 #ifndef P2P_BASE_ICE_CONTROLLER_INTERFACE_H_
 #define P2P_BASE_ICE_CONTROLLER_INTERFACE_H_
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "p2p/base/connection.h"
 #include "p2p/base/ice_switch_reason.h"
 #include "p2p/base/ice_transport_internal.h"
@@ -64,10 +64,10 @@
   // This represents the result of a switch call.
   struct SwitchResult {
     // Connection that we should (optionally) switch to.
-    absl::optional<const Connection*> connection;
+    std::optional<const Connection*> connection;
 
     // An optional recheck event for when a Switch() should be attempted again.
-    absl::optional<IceRecheckEvent> recheck_event;
+    std::optional<IceRecheckEvent> recheck_event;
 
     // A vector with connection to run ForgetLearnedState on.
     std::vector<const Connection*> connections_to_forget_state_on;
@@ -76,12 +76,12 @@
   // This represents the result of a call to SelectConnectionToPing.
   struct PingResult {
     PingResult(const Connection* conn, int _recheck_delay_ms)
-        : connection(conn ? absl::optional<const Connection*>(conn)
-                          : absl::nullopt),
+        : connection(conn ? std::optional<const Connection*>(conn)
+                          : std::nullopt),
           recheck_delay_ms(_recheck_delay_ms) {}
 
     // Connection that we should (optionally) ping.
-    const absl::optional<const Connection*> connection;
+    const std::optional<const Connection*> connection;
 
     // The delay before P2PTransportChannel shall call SelectConnectionToPing()
     // again.
diff --git a/p2p/base/ice_transport_internal.h b/p2p/base/ice_transport_internal.h
index b2a4690..ade567c 100644
--- a/p2p/base/ice_transport_internal.h
+++ b/p2p/base/ice_transport_internal.h
@@ -13,12 +13,12 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/candidate.h"
 #include "api/rtc_error.h"
 #include "api/transport/enums.h"
@@ -103,16 +103,16 @@
 webrtc::RTCError VerifyCandidates(const Candidates& candidates);
 
 // Information about ICE configuration.
-// TODO(deadbeef): Use absl::optional to represent unset values, instead of
+// TODO(deadbeef): Use std::optional to represent unset values, instead of
 // -1.
 //
 // TODO(bugs.webrtc.org/15609): Define a public API for this.
 struct RTC_EXPORT IceConfig {
   // The ICE connection receiving timeout value in milliseconds.
-  absl::optional<int> receiving_timeout;
+  std::optional<int> receiving_timeout;
   // Time interval in milliseconds to ping a backup connection when the ICE
   // channel is strongly connected.
-  absl::optional<int> backup_connection_ping_interval;
+  std::optional<int> backup_connection_ping_interval;
 
   ContinualGatheringPolicy continual_gathering_policy = GATHER_ONCE;
 
@@ -125,7 +125,7 @@
   bool prioritize_most_likely_candidate_pairs = false;
 
   // Writable connections are pinged at a slower rate once stablized.
-  absl::optional<int> stable_writable_connection_ping_interval;
+  std::optional<int> stable_writable_connection_ping_interval;
 
   // If set to true, this means the ICE transport should presume TURN-to-TURN
   // candidate pairs will succeed, even before a binding response is received.
@@ -140,12 +140,12 @@
 
   // Interval to check on all networks and to perform ICE regathering on any
   // active network having no connection on it.
-  absl::optional<int> regather_on_failed_networks_interval;
+  std::optional<int> regather_on_failed_networks_interval;
 
   // The time period in which we will not switch the selected connection
   // when a new connection becomes receiving but the selected connection is not
   // in case that the selected connection may become receiving soon.
-  absl::optional<int> receiving_switching_delay;
+  std::optional<int> receiving_switching_delay;
 
   // TODO(honghaiz): Change the default to regular nomination.
   // Default nomination mode if the remote does not support renomination.
@@ -155,12 +155,12 @@
   // for a candidate pair when it is both writable and receiving (strong
   // connectivity). This parameter overrides the default value given by
   // `STRONG_PING_INTERVAL` in p2ptransport.h if set.
-  absl::optional<int> ice_check_interval_strong_connectivity;
+  std::optional<int> ice_check_interval_strong_connectivity;
   // The interval in milliseconds at which ICE checks (STUN pings) will be sent
   // for a candidate pair when it is either not writable or not receiving (weak
   // connectivity). This parameter overrides the default value given by
   // `WEAK_PING_INTERVAL` in p2ptransport.h if set.
-  absl::optional<int> ice_check_interval_weak_connectivity;
+  std::optional<int> ice_check_interval_weak_connectivity;
   // ICE checks (STUN pings) will not be sent at higher rate (lower interval)
   // than this, no matter what other settings there are.
   // Measure in milliseconds.
@@ -168,30 +168,30 @@
   // Note that this parameter overrides both the above check intervals for
   // candidate pairs with strong or weak connectivity, if either of the above
   // interval is shorter than the min interval.
-  absl::optional<int> ice_check_min_interval;
+  std::optional<int> ice_check_min_interval;
   // The min time period for which a candidate pair must wait for response to
   // connectivity checks before it becomes unwritable. This parameter
   // overrides the default value given by `CONNECTION_WRITE_CONNECT_TIMEOUT`
   // in port.h if set, when determining the writability of a candidate pair.
-  absl::optional<int> ice_unwritable_timeout;
+  std::optional<int> ice_unwritable_timeout;
 
   // The min number of connectivity checks that a candidate pair must sent
   // without receiving response before it becomes unwritable. This parameter
   // overrides the default value given by `CONNECTION_WRITE_CONNECT_FAILURES` in
   // port.h if set, when determining the writability of a candidate pair.
-  absl::optional<int> ice_unwritable_min_checks;
+  std::optional<int> ice_unwritable_min_checks;
 
   // The min time period for which a candidate pair must wait for response to
   // connectivity checks it becomes inactive. This parameter overrides the
   // default value given by `CONNECTION_WRITE_TIMEOUT` in port.h if set, when
   // determining the writability of a candidate pair.
-  absl::optional<int> ice_inactive_timeout;
+  std::optional<int> ice_inactive_timeout;
 
   // The interval in milliseconds at which STUN candidates will resend STUN
   // binding requests to keep NAT bindings open.
-  absl::optional<int> stun_keepalive_interval;
+  std::optional<int> stun_keepalive_interval;
 
-  absl::optional<rtc::AdapterType> network_preference;
+  std::optional<rtc::AdapterType> network_preference;
 
   webrtc::VpnPreference vpn_preference = webrtc::VpnPreference::kDefault;
 
@@ -208,7 +208,7 @@
 
   // Helper getters for parameters with implementation-specific default value.
   // By convention, parameters with default value are represented by
-  // absl::optional and setting a parameter to null restores its default value.
+  // std::optional and setting a parameter to null restores its default value.
   int receiving_timeout_or_default() const;
   int backup_connection_ping_interval_or_default() const;
   int stable_writable_connection_ping_interval_or_default() const;
@@ -291,20 +291,20 @@
   virtual bool GetStats(IceTransportStats* ice_transport_stats) = 0;
 
   // Returns RTT estimate over the currently active connection, or an empty
-  // absl::optional if there is none.
-  virtual absl::optional<int> GetRttEstimate() = 0;
+  // std::optional if there is none.
+  virtual std::optional<int> GetRttEstimate() = 0;
 
   // TODO(qingsi): Remove this method once Chrome does not depend on it anymore.
   virtual const Connection* selected_connection() const = 0;
 
-  // Returns the selected candidate pair, or an empty absl::optional if there is
+  // Returns the selected candidate pair, or an empty std::optional if there is
   // none.
-  virtual absl::optional<const CandidatePair> GetSelectedCandidatePair()
+  virtual std::optional<const CandidatePair> GetSelectedCandidatePair()
       const = 0;
 
-  virtual absl::optional<std::reference_wrapper<StunDictionaryWriter>>
+  virtual std::optional<std::reference_wrapper<StunDictionaryWriter>>
   GetDictionaryWriter() {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   void AddGatheringStateCallback(
diff --git a/p2p/base/mock_ice_transport.h b/p2p/base/mock_ice_transport.h
index b7b986e..a9046e1 100644
--- a/p2p/base/mock_ice_transport.h
+++ b/p2p/base/mock_ice_transport.h
@@ -63,11 +63,10 @@
   void SetRemoteIceParameters(const IceParameters& ice_params) override {}
   void SetRemoteIceMode(IceMode mode) override {}
   void SetIceConfig(const IceConfig& config) override {}
-  absl::optional<int> GetRttEstimate() override { return absl::nullopt; }
+  std::optional<int> GetRttEstimate() override { return std::nullopt; }
   const Connection* selected_connection() const override { return nullptr; }
-  absl::optional<const CandidatePair> GetSelectedCandidatePair()
-      const override {
-    return absl::nullopt;
+  std::optional<const CandidatePair> GetSelectedCandidatePair() const override {
+    return std::nullopt;
   }
   void MaybeStartGathering() override {}
   void AddRemoteCandidate(const Candidate& candidate) override {}
diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc
index 2116a3f..e194b9f 100644
--- a/p2p/base/p2p_transport_channel.cc
+++ b/p2p/base/p2p_transport_channel.cc
@@ -350,21 +350,21 @@
   return gathering_state_;
 }
 
-absl::optional<int> P2PTransportChannel::GetRttEstimate() {
+std::optional<int> P2PTransportChannel::GetRttEstimate() {
   RTC_DCHECK_RUN_ON(network_thread_);
   if (selected_connection_ != nullptr &&
       selected_connection_->rtt_samples() > 0) {
     return selected_connection_->rtt();
   } else {
-    return absl::nullopt;
+    return std::nullopt;
   }
 }
 
-absl::optional<const CandidatePair>
+std::optional<const CandidatePair>
 P2PTransportChannel::GetSelectedCandidatePair() const {
   RTC_DCHECK_RUN_ON(network_thread_);
   if (selected_connection_ == nullptr) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   CandidatePair pair;
@@ -492,9 +492,9 @@
   remote_ice_mode_ = mode;
 }
 
-// TODO(qingsi): We apply the convention that setting a absl::optional parameter
+// TODO(qingsi): We apply the convention that setting a std::optional parameter
 // to null restores its default value in the implementation. However, some
-// absl::optional parameters are only processed below if non-null, e.g.,
+// std::optional parameters are only processed below if non-null, e.g.,
 // regather_on_failed_networks_interval, and thus there is no way to restore the
 // defaults. Fix this issue later for consistency.
 void P2PTransportChannel::SetIceConfig(const IceConfig& config) {
@@ -1631,7 +1631,7 @@
   return true;
 }
 
-absl::optional<rtc::NetworkRoute> P2PTransportChannel::network_route() const {
+std::optional<rtc::NetworkRoute> P2PTransportChannel::network_route() const {
   RTC_DCHECK_RUN_ON(network_thread_);
   return network_route_;
 }
diff --git a/p2p/base/p2p_transport_channel.h b/p2p/base/p2p_transport_channel.h
index 2750af1..e1f5066 100644
--- a/p2p/base/p2p_transport_channel.h
+++ b/p2p/base/p2p_transport_channel.h
@@ -26,6 +26,7 @@
 #include <algorithm>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
@@ -33,7 +34,6 @@
 
 #include "absl/base/attributes.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/async_dns_resolver.h"
 #include "api/candidate.h"
@@ -144,7 +144,7 @@
   // only update the parameter if it is considered set in `config`. For example,
   // a negative value of receiving_timeout will be considered "not set" and we
   // will not use it to update the respective parameter in `config_`.
-  // TODO(deadbeef): Use absl::optional instead of negative values.
+  // TODO(deadbeef): Use std::optional instead of negative values.
   void SetIceConfig(const IceConfig& config) override;
   const IceConfig& config() const;
   static webrtc::RTCError ValidateIceConfig(const IceConfig& config);
@@ -158,9 +158,9 @@
   bool GetOption(rtc::Socket::Option opt, int* value) override;
   int GetError() override;
   bool GetStats(IceTransportStats* ice_transport_stats) override;
-  absl::optional<int> GetRttEstimate() override;
+  std::optional<int> GetRttEstimate() override;
   const Connection* selected_connection() const override;
-  absl::optional<const CandidatePair> GetSelectedCandidatePair() const override;
+  std::optional<const CandidatePair> GetSelectedCandidatePair() const override;
 
   // From IceAgentInterface
   void OnStartedPinging() override;
@@ -205,7 +205,7 @@
 
   void PruneAllPorts();
   int check_receiving_interval() const;
-  absl::optional<rtc::NetworkRoute> network_route() const override;
+  std::optional<rtc::NetworkRoute> network_route() const override;
 
   void RemoveConnection(Connection* connection);
 
@@ -245,7 +245,7 @@
     return ss.Release();
   }
 
-  absl::optional<std::reference_wrapper<StunDictionaryWriter>>
+  std::optional<std::reference_wrapper<StunDictionaryWriter>>
   GetDictionaryWriter() override {
     return stun_dict_writer_;
   }
@@ -460,7 +460,7 @@
   bool has_been_writable_ RTC_GUARDED_BY(network_thread_) =
       false;  // if writable_ has ever been true
 
-  absl::optional<rtc::NetworkRoute> network_route_
+  std::optional<rtc::NetworkRoute> network_route_
       RTC_GUARDED_BY(network_thread_);
   webrtc::IceEventLog ice_event_log_ RTC_GUARDED_BY(network_thread_);
 
diff --git a/p2p/base/p2p_transport_channel_ice_field_trials.h b/p2p/base/p2p_transport_channel_ice_field_trials.h
index 96a7756..f5573b1 100644
--- a/p2p/base/p2p_transport_channel_ice_field_trials.h
+++ b/p2p/base/p2p_transport_channel_ice_field_trials.h
@@ -11,7 +11,7 @@
 #ifndef P2P_BASE_P2P_TRANSPORT_CHANNEL_ICE_FIELD_TRIALS_H_
 #define P2P_BASE_P2P_TRANSPORT_CHANNEL_ICE_FIELD_TRIALS_H_
 
-#include "absl/types/optional.h"
+#include <optional>
 
 namespace cricket {
 
@@ -23,17 +23,17 @@
   // TODO(jonaso) : Consider how members of this struct can be made const.
 
   bool skip_relay_to_non_relay_connections = false;
-  absl::optional<int> max_outstanding_pings;
+  std::optional<int> max_outstanding_pings;
 
   // Wait X ms before selecting a connection when having none.
   // This will make media slower, but will give us chance to find
   // a better connection before starting.
-  absl::optional<int> initial_select_dampening;
+  std::optional<int> initial_select_dampening;
 
   // If the connection has recevied a ping-request, delay by
   // maximum this delay. This will make media slower, but will
   // give us chance to find a better connection before starting.
-  absl::optional<int> initial_select_dampening_ping_received;
+  std::optional<int> initial_select_dampening_ping_received;
 
   // Announce GOOG_PING support in STUN_BINDING_RESPONSE if requested
   // by peer.
@@ -66,7 +66,7 @@
   bool stop_gather_on_strongly_connected = true;
 
   // DSCP taging.
-  absl::optional<int> override_dscp;
+  std::optional<int> override_dscp;
 
   bool piggyback_ice_check_acknowledgement = false;
   bool extra_ice_ping = false;
diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc
index cad0a08..fb0eae3 100644
--- a/p2p/base/p2p_transport_channel_unittest.cc
+++ b/p2p/base/p2p_transport_channel_unittest.cc
@@ -137,7 +137,7 @@
 cricket::IceConfig CreateIceConfig(
     int receiving_timeout,
     cricket::ContinualGatheringPolicy continual_gathering_policy,
-    absl::optional<int> backup_ping_interval = absl::nullopt) {
+    std::optional<int> backup_ping_interval = std::nullopt) {
   cricket::IceConfig config;
   config.receiving_timeout = receiving_timeout;
   config.continual_gathering_policy = continual_gathering_policy;
@@ -541,8 +541,8 @@
                   const SocketAddress& addr,
                   absl::string_view ifname,
                   rtc::AdapterType adapter_type,
-                  absl::optional<rtc::AdapterType> underlying_vpn_adapter_type =
-                      absl::nullopt) {
+                  std::optional<rtc::AdapterType> underlying_vpn_adapter_type =
+                      std::nullopt) {
     GetEndpoint(endpoint)->network_manager_.AddInterface(
         addr, ifname, adapter_type, underlying_vpn_adapter_type);
   }
@@ -793,7 +793,7 @@
     }
   }
 
-  void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
+  void OnNetworkRouteChanged(std::optional<rtc::NetworkRoute> network_route) {
     // If the `network_route` is unset, don't count. This is used in the case
     // when the network on remote side is down, the signal will be fired with an
     // unset network route and it shouldn't trigger a connection switch.
@@ -3392,7 +3392,7 @@
     conn->SignalNominated(conn);
   }
 
-  void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
+  void OnNetworkRouteChanged(std::optional<rtc::NetworkRoute> network_route) {
     last_network_route_ = network_route;
     if (last_network_route_) {
       last_sent_packet_id_ = last_network_route_->last_sent_packet_id;
@@ -3405,7 +3405,7 @@
       absl::string_view remote_ufrag,
       int priority,
       uint32_t nomination,
-      const absl::optional<std::string>& piggyback_ping_id) {
+      const std::optional<std::string>& piggyback_ping_id) {
     IceMessage msg(STUN_BINDING_REQUEST);
     msg.AddAttribute(std::make_unique<StunByteStringAttribute>(
         STUN_ATTR_USERNAME,
@@ -3434,7 +3434,7 @@
                                int priority,
                                uint32_t nomination = 0) {
     ReceivePingOnConnection(conn, remote_ufrag, priority, nomination,
-                            absl::nullopt);
+                            std::nullopt);
   }
 
   void OnReadyToSend(rtc::PacketTransportInternal* transport) {
@@ -3509,9 +3509,9 @@
   int selected_candidate_pair_switches_ = 0;
   int last_sent_packet_id_ = -1;
   bool channel_ready_to_send_ = false;
-  absl::optional<CandidatePairChangeEvent> last_candidate_change_event_;
+  std::optional<CandidatePairChangeEvent> last_candidate_change_event_;
   IceTransportState channel_state_ = IceTransportState::STATE_INIT;
-  absl::optional<rtc::NetworkRoute> last_network_route_;
+  std::optional<rtc::NetworkRoute> last_network_route_;
 };
 
 TEST_F(P2PTransportChannelPingTest, TestTriggeredChecks) {
diff --git a/p2p/base/packet_transport_internal.cc b/p2p/base/packet_transport_internal.cc
index 36f797a..f1053b3 100644
--- a/p2p/base/packet_transport_internal.cc
+++ b/p2p/base/packet_transport_internal.cc
@@ -23,8 +23,8 @@
   return false;
 }
 
-absl::optional<NetworkRoute> PacketTransportInternal::network_route() const {
-  return absl::optional<NetworkRoute>();
+std::optional<NetworkRoute> PacketTransportInternal::network_route() const {
+  return std::optional<NetworkRoute>();
 }
 
 void PacketTransportInternal::RegisterReceivedPacketCallback(
diff --git a/p2p/base/packet_transport_internal.h b/p2p/base/packet_transport_internal.h
index 54d7f07..3a9a871 100644
--- a/p2p/base/packet_transport_internal.h
+++ b/p2p/base/packet_transport_internal.h
@@ -11,12 +11,12 @@
 #ifndef P2P_BASE_PACKET_TRANSPORT_INTERNAL_H_
 #define P2P_BASE_PACKET_TRANSPORT_INTERNAL_H_
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/functional/any_invocable.h"
-#include "absl/types/optional.h"
 #include "p2p/base/port.h"
 #include "rtc_base/async_packet_socket.h"
 #include "rtc_base/callback_list.h"
@@ -67,7 +67,7 @@
 
   // Returns the current network route with transport overhead.
   // TODO(zhihuang): Make it pure virtual once the Chrome/remoting is updated.
-  virtual absl::optional<NetworkRoute> network_route() const;
+  virtual std::optional<NetworkRoute> network_route() const;
 
   // Emitted when the writable state, represented by `writable()`, changes.
   sigslot::signal1<PacketTransportInternal*> SignalWritableState;
@@ -95,7 +95,7 @@
       SignalSentPacket;
 
   // Signalled when the current network route has changed.
-  sigslot::signal1<absl::optional<rtc::NetworkRoute>> SignalNetworkRouteChanged;
+  sigslot::signal1<std::optional<rtc::NetworkRoute>> SignalNetworkRouteChanged;
 
   // Signalled when the transport is closed.
   void SetOnCloseCallback(absl::AnyInvocable<void() &&> callback);
diff --git a/p2p/base/packet_transport_internal_unittest.cc b/p2p/base/packet_transport_internal_unittest.cc
index 25492ea..178c273 100644
--- a/p2p/base/packet_transport_internal_unittest.cc
+++ b/p2p/base/packet_transport_internal_unittest.cc
@@ -35,7 +35,7 @@
                       rtc::ReceivedPacket::kDtlsDecrypted);
           });
   packet_transport.NotifyPacketReceived(rtc::ReceivedPacket(
-      {}, rtc::SocketAddress(), absl::nullopt, rtc::EcnMarking::kNotEct,
+      {}, rtc::SocketAddress(), std::nullopt, rtc::EcnMarking::kNotEct,
       rtc::ReceivedPacket::kDtlsDecrypted));
 
   packet_transport.DeregisterReceivedPacketCallback(&receiver);
diff --git a/p2p/base/port.cc b/p2p/base/port.cc
index 25105dc..d7ba32f 100644
--- a/p2p/base/port.cc
+++ b/p2p/base/port.cc
@@ -80,13 +80,13 @@
   return PROTO_NAMES[proto];
 }
 
-absl::optional<ProtocolType> StringToProto(absl::string_view proto_name) {
+std::optional<ProtocolType> StringToProto(absl::string_view proto_name) {
   for (size_t i = 0; i <= PROTO_LAST; ++i) {
     if (absl::EqualsIgnoreCase(PROTO_NAMES[i], proto_name)) {
       return static_cast<ProtocolType>(i);
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // RFC 6544, TCP candidate encoding rules.
diff --git a/p2p/base/port.h b/p2p/base/port.h
index 2df1d35..f4c87c6 100644
--- a/p2p/base/port.h
+++ b/p2p/base/port.h
@@ -17,6 +17,7 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <type_traits>
@@ -25,7 +26,6 @@
 
 #include "absl/base/attributes.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/candidate.h"
 #include "api/field_trials_view.h"
 #include "api/packet_socket_factory.h"
@@ -102,7 +102,7 @@
   CandidateStats(const CandidateStats&) = default;
   CandidateStats(CandidateStats&&) = default;
   CandidateStats(Candidate candidate,
-                 absl::optional<StunStats> stats = absl::nullopt)
+                 std::optional<StunStats> stats = std::nullopt)
       : candidate_(std::move(candidate)), stun_stats_(std::move(stats)) {}
   ~CandidateStats() = default;
 
@@ -110,18 +110,18 @@
 
   const Candidate& candidate() const { return candidate_; }
 
-  const absl::optional<StunStats>& stun_stats() const { return stun_stats_; }
+  const std::optional<StunStats>& stun_stats() const { return stun_stats_; }
 
  private:
   Candidate candidate_;
   // STUN port stats if this candidate is a STUN candidate.
-  absl::optional<StunStats> stun_stats_;
+  std::optional<StunStats> stun_stats_;
 };
 
 typedef std::vector<CandidateStats> CandidateStatsList;
 
 const char* ProtoToString(ProtocolType proto);
-absl::optional<ProtocolType> StringToProto(absl::string_view proto_name);
+std::optional<ProtocolType> StringToProto(absl::string_view proto_name);
 
 struct ProtocolAddress {
   rtc::SocketAddress address;
@@ -363,7 +363,7 @@
 
   int16_t network_cost() const override { return network_cost_; }
 
-  void GetStunStats(absl::optional<StunStats>* stats) override {}
+  void GetStunStats(std::optional<StunStats>* stats) override {}
 
  protected:
   void UpdateNetworkCost() override;
diff --git a/p2p/base/port_allocator.cc b/p2p/base/port_allocator.cc
index 5694007..6eab1d3 100644
--- a/p2p/base/port_allocator.cc
+++ b/p2p/base/port_allocator.cc
@@ -126,7 +126,7 @@
     int candidate_pool_size,
     bool prune_turn_ports,
     webrtc::TurnCustomizer* turn_customizer,
-    const absl::optional<int>& stun_candidate_keepalive_interval) {
+    const std::optional<int>& stun_candidate_keepalive_interval) {
   webrtc::PortPrunePolicy turn_port_prune_policy =
       prune_turn_ports ? webrtc::PRUNE_BASED_ON_PRIORITY : webrtc::NO_PRUNE;
   return SetConfiguration(stun_servers, turn_servers, candidate_pool_size,
@@ -140,7 +140,7 @@
     int candidate_pool_size,
     webrtc::PortPrunePolicy turn_port_prune_policy,
     webrtc::TurnCustomizer* turn_customizer,
-    const absl::optional<int>& stun_candidate_keepalive_interval) {
+    const std::optional<int>& stun_candidate_keepalive_interval) {
   RTC_DCHECK_GE(candidate_pool_size, 0);
   RTC_DCHECK_LE(candidate_pool_size, static_cast<int>(UINT16_MAX));
   CheckRunOnValidThreadIfInitialized();
diff --git a/p2p/base/port_allocator.h b/p2p/base/port_allocator.h
index 5aba5f2..880d3ae 100644
--- a/p2p/base/port_allocator.h
+++ b/p2p/base/port_allocator.h
@@ -15,11 +15,11 @@
 
 #include <deque>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/candidate.h"
 #include "api/sequence_checker.h"
 #include "api/transport/enums.h"
@@ -254,7 +254,7 @@
   // The default value of the interval in implementation is restored if a null
   // optional value is passed.
   virtual void SetStunKeepaliveIntervalForReadyPorts(
-      const absl::optional<int>& stun_keepalive_interval) {}
+      const std::optional<int>& stun_keepalive_interval) {}
   // Another way of getting the information provided by the signals below.
   //
   // Ports and candidates are not guaranteed to be in the same order as the
@@ -368,15 +368,15 @@
                         int candidate_pool_size,
                         bool prune_turn_ports,
                         webrtc::TurnCustomizer* turn_customizer = nullptr,
-                        const absl::optional<int>&
-                            stun_candidate_keepalive_interval = absl::nullopt);
+                        const std::optional<int>&
+                            stun_candidate_keepalive_interval = std::nullopt);
   bool SetConfiguration(const ServerAddresses& stun_servers,
                         const std::vector<RelayServerConfig>& turn_servers,
                         int candidate_pool_size,
                         webrtc::PortPrunePolicy turn_port_prune_policy,
                         webrtc::TurnCustomizer* turn_customizer = nullptr,
-                        const absl::optional<int>&
-                            stun_candidate_keepalive_interval = absl::nullopt);
+                        const std::optional<int>&
+                            stun_candidate_keepalive_interval = std::nullopt);
 
   const ServerAddresses& stun_servers() const {
     CheckRunOnValidThreadIfInitialized();
@@ -393,7 +393,7 @@
     return candidate_pool_size_;
   }
 
-  const absl::optional<int>& stun_candidate_keepalive_interval() const {
+  const std::optional<int>& stun_candidate_keepalive_interval() const {
     CheckRunOnValidThreadIfInitialized();
     return stun_candidate_keepalive_interval_;
   }
@@ -630,7 +630,7 @@
   // all TurnPort(s) created.
   webrtc::TurnCustomizer* turn_customizer_ = nullptr;
 
-  absl::optional<int> stun_candidate_keepalive_interval_;
+  std::optional<int> stun_candidate_keepalive_interval_;
 
   // If true, TakePooledSession() will only return sessions that has same ice
   // credentials as requested.
diff --git a/p2p/base/port_interface.h b/p2p/base/port_interface.h
index 34f835d..0d89a9e 100644
--- a/p2p/base/port_interface.h
+++ b/p2p/base/port_interface.h
@@ -12,12 +12,12 @@
 #define P2P_BASE_PORT_INTERFACE_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/candidate.h"
 #include "api/field_trials_view.h"
 #include "api/packet_socket_factory.h"
@@ -139,7 +139,7 @@
 
   virtual std::string ToString() const = 0;
 
-  virtual void GetStunStats(absl::optional<StunStats>* stats) = 0;
+  virtual void GetStunStats(std::optional<StunStats>* stats) = 0;
 
   // Removes and deletes a connection object. `DestroyConnection` will
   // delete the connection object directly whereas `DestroyConnectionAsync`
diff --git a/p2p/base/port_unittest.cc b/p2p/base/port_unittest.cc
index 48d52da..9b05282 100644
--- a/p2p/base/port_unittest.cc
+++ b/p2p/base/port_unittest.cc
@@ -16,13 +16,13 @@
 #include <limits>
 #include <list>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/candidate.h"
 #include "api/packet_socket_factory.h"
@@ -260,13 +260,13 @@
   ASSERT_TRUE_WAIT(lport->last_stun_msg(), kDefaultTimeout);
   ASSERT_GT(lport->last_stun_buf().size(), 0u);
   rconn->OnReadPacket(rtc::ReceivedPacket(lport->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
 
   clock->AdvanceTime(webrtc::TimeDelta::Millis(ms));
   ASSERT_TRUE_WAIT(rport->last_stun_msg(), kDefaultTimeout);
   ASSERT_GT(rport->last_stun_buf().size(), 0u);
   lconn->OnReadPacket(rtc::ReceivedPacket(rport->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
 }
 
 class TestChannel : public sigslot::has_slots<> {
@@ -541,7 +541,7 @@
                                  .ice_username_fragment = username_,
                                  .ice_password = password_,
                                  .field_trials = &field_trials_},
-                                0, 0, true, absl::nullopt);
+                                0, 0, true, std::nullopt);
     port->SetIceTiebreaker(kTiebreakerDefault);
     return port;
   }
@@ -557,7 +557,7 @@
          .ice_username_fragment = username_,
          .ice_password = password_,
          .field_trials = &field_trials_},
-        0, 0, true, absl::nullopt);
+        0, 0, true, std::nullopt);
     port->SetIceTiebreaker(kTiebreakerDefault);
     return port;
   }
@@ -587,7 +587,7 @@
                                   .ice_username_fragment = username_,
                                   .ice_password = password_,
                                   .field_trials = &field_trials_},
-                                 0, 0, stun_servers, absl::nullopt);
+                                 0, 0, stun_servers, std::nullopt);
     port->SetIceTiebreaker(kTiebreakerDefault);
     return port;
   }
@@ -1097,7 +1097,7 @@
  private:
   AsyncPacketSocket* next_udp_socket_;
   AsyncListenSocket* next_server_tcp_socket_;
-  absl::optional<AsyncPacketSocket*> next_client_tcp_socket_;
+  std::optional<AsyncPacketSocket*> next_client_tcp_socket_;
 };
 
 class FakeAsyncPacketSocket : public AsyncPacketSocket {
@@ -1513,7 +1513,7 @@
   IceMessage* msg = lport->last_stun_msg();
   EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
   conn->OnReadPacket(rtc::ReceivedPacket(lport->last_stun_buf(),
-                                         rtc::SocketAddress(), absl::nullopt));
+                                         rtc::SocketAddress(), std::nullopt));
   ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
   msg = lport->last_stun_msg();
   EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
@@ -1582,7 +1582,7 @@
   EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
   // Send rport binding request to lport.
   lconn->OnReadPacket(rtc::ReceivedPacket(rport->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
 
   ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
   EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
@@ -1915,13 +1915,13 @@
 
   // Receive the BINDING-REQUEST and respond with BINDING-RESPONSE.
   rconn->OnReadPacket(rtc::ReceivedPacket(lport->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
   msg = rport->last_stun_msg();
   ASSERT_TRUE(msg != NULL);
   EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
   // Received a BINDING-RESPONSE.
   lconn->OnReadPacket(rtc::ReceivedPacket(rport->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
 
   // Verify the STUN Stats.
   EXPECT_EQ(1U, lconn->stats().sent_ping_requests_total);
@@ -2002,11 +2002,11 @@
   // Respond with a BINDING-RESPONSE.
   request = CopyStunMessage(*msg);
   lconn->OnReadPacket(rtc::ReceivedPacket(rport->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
   msg = lport->last_stun_msg();
   // Receive the BINDING-RESPONSE.
   rconn->OnReadPacket(rtc::ReceivedPacket(lport->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
 
   // Verify the Stun ping stats.
   EXPECT_EQ(3U, rconn->stats().sent_ping_requests_total);
@@ -2058,7 +2058,7 @@
   ASSERT_TRUE_WAIT(lport->last_stun_msg(), kDefaultTimeout);
   ASSERT_GT(lport->last_stun_buf().size(), 0u);
   rconn->OnReadPacket(rtc::ReceivedPacket(lport->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
 
   EXPECT_EQ(nomination, rconn->remote_nomination());
   EXPECT_FALSE(lconn->nominated());
@@ -2071,7 +2071,7 @@
   ASSERT_TRUE_WAIT(rport->last_stun_msg(), kDefaultTimeout);
   ASSERT_GT(rport->last_stun_buf().size(), 0u);
   lconn->OnReadPacket(rtc::ReceivedPacket(rport->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
 
   EXPECT_EQ(nomination, lconn->acked_nomination());
   EXPECT_TRUE(lconn->nominated());
@@ -2199,7 +2199,7 @@
   EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
   // Pass the binding request to rport.
   rconn->OnReadPacket(rtc::ReceivedPacket(lport->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
 
   // Wait until rport sends the response and then check the remote network cost.
   ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
@@ -2530,7 +2530,7 @@
   lconn->Ping(0);
   ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
   rconn->OnReadPacket(rtc::ReceivedPacket(lport->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
 
   // Intercept request and add comprehension required attribute.
   ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
@@ -2618,7 +2618,7 @@
   EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
   // Send rport binding request to lport.
   lconn->OnReadPacket(rtc::ReceivedPacket(rport->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
 
   ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
   EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
@@ -3128,7 +3128,7 @@
 
   // Feeding the respone message from litemode to the full mode connection.
   ch1.conn()->OnReadPacket(rtc::ReceivedPacket(
-      ice_lite_port->last_stun_buf(), rtc::SocketAddress(), absl::nullopt));
+      ice_lite_port->last_stun_buf(), rtc::SocketAddress(), std::nullopt));
 
   // Verifying full mode connection becomes writable from the response.
   EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
@@ -3149,17 +3149,17 @@
 namespace {
 
 // Utility function for testing goog ping.
-absl::optional<int> GetSupportedGoogPingVersion(const StunMessage* msg) {
+std::optional<int> GetSupportedGoogPingVersion(const StunMessage* msg) {
   auto goog_misc = msg->GetUInt16List(STUN_ATTR_GOOG_MISC_INFO);
   if (goog_misc == nullptr) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (msg->type() == STUN_BINDING_REQUEST) {
     if (goog_misc->Size() <
         static_cast<int>(cricket::IceGoogMiscInfoBindingRequestAttributeIndex::
                              SUPPORT_GOOG_PING_VERSION)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     return goog_misc->GetType(
@@ -3171,14 +3171,14 @@
     if (goog_misc->Size() <
         static_cast<int>(cricket::IceGoogMiscInfoBindingResponseAttributeIndex::
                              SUPPORT_GOOG_PING_VERSION)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     return goog_misc->GetType(
         static_cast<int>(cricket::IceGoogMiscInfoBindingResponseAttributeIndex::
                              SUPPORT_GOOG_PING_VERSION));
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace
@@ -3246,7 +3246,7 @@
 
   // Feeding the respone message back.
   ch1.conn()->OnReadPacket(rtc::ReceivedPacket(
-      port2->last_stun_buf(), rtc::SocketAddress(), absl::nullopt));
+      port2->last_stun_buf(), rtc::SocketAddress(), std::nullopt));
 
   port1->Reset();
   port2->Reset();
@@ -3503,7 +3503,7 @@
 
   // Feeding the respone message back.
   ch1.conn()->OnReadPacket(rtc::ReceivedPacket(
-      port2->last_stun_buf(), rtc::SocketAddress(), absl::nullopt));
+      port2->last_stun_buf(), rtc::SocketAddress(), std::nullopt));
 
   port1->Reset();
   port2->Reset();
@@ -3588,7 +3588,7 @@
 
   // Feeding the respone message back.
   ch1.conn()->OnReadPacket(rtc::ReceivedPacket(
-      port2->last_stun_buf(), rtc::SocketAddress(), absl::nullopt));
+      port2->last_stun_buf(), rtc::SocketAddress(), std::nullopt));
 
   port1->Reset();
   port2->Reset();
@@ -3854,7 +3854,7 @@
     ASSERT_TRUE_WAIT(lport->last_stun_msg(), kDefaultTimeout);
     ASSERT_GT(lport->last_stun_buf().size(), 0u);
     rconn->OnReadPacket(rtc::ReceivedPacket(
-        lport->last_stun_buf(), rtc::SocketAddress(), absl::nullopt));
+        lport->last_stun_buf(), rtc::SocketAddress(), std::nullopt));
 
     clock_.AdvanceTime(webrtc::TimeDelta::Millis(ms));
     ASSERT_TRUE_WAIT(rport->last_stun_msg(), kDefaultTimeout);
@@ -3869,7 +3869,7 @@
     SendPingAndCaptureReply(lconn, rconn, ms, &reply);
 
     lconn->OnReadPacket(
-        rtc::ReceivedPacket(reply, rtc::SocketAddress(), absl::nullopt));
+        rtc::ReceivedPacket(reply, rtc::SocketAddress(), std::nullopt));
   }
 
   void OnConnectionStateChange(Connection* connection) { num_state_changes_++; }
@@ -3931,7 +3931,7 @@
   EXPECT_FALSE(lconn->receiving());
 
   lconn->OnReadPacket(
-      rtc::ReceivedPacket(reply, rtc::SocketAddress(), absl::nullopt));
+      rtc::ReceivedPacket(reply, rtc::SocketAddress(), std::nullopt));
 
   // That reply was discarded due to the ForgetLearnedState() while it was
   // outstanding.
@@ -4004,14 +4004,14 @@
   ASSERT_TRUE_WAIT(lport_->last_stun_msg(), kDefaultTimeout);
   ASSERT_GT(lport_->last_stun_buf().size(), 0u);
   rconn->OnReadPacket(rtc::ReceivedPacket(lport_->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
   EXPECT_TRUE(received_goog_delta);
 
   clock_.AdvanceTime(webrtc::TimeDelta::Millis(ms));
   ASSERT_TRUE_WAIT(rport_->last_stun_msg(), kDefaultTimeout);
   ASSERT_GT(rport_->last_stun_buf().size(), 0u);
   lconn->OnReadPacket(rtc::ReceivedPacket(rport_->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
 
   EXPECT_TRUE(received_goog_delta_ack);
 }
@@ -4042,13 +4042,13 @@
   ASSERT_TRUE_WAIT(lport_->last_stun_msg(), kDefaultTimeout);
   ASSERT_GT(lport_->last_stun_buf().size(), 0u);
   rconn->OnReadPacket(rtc::ReceivedPacket(lport_->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
 
   clock_.AdvanceTime(webrtc::TimeDelta::Millis(ms));
   ASSERT_TRUE_WAIT(rport_->last_stun_msg(), kDefaultTimeout);
   ASSERT_GT(rport_->last_stun_buf().size(), 0u);
   lconn->OnReadPacket(rtc::ReceivedPacket(rport_->last_stun_buf(),
-                                          rtc::SocketAddress(), absl::nullopt));
+                                          rtc::SocketAddress(), std::nullopt));
   EXPECT_TRUE(received_goog_delta_ack_error);
 }
 
diff --git a/p2p/base/regathering_controller.h b/p2p/base/regathering_controller.h
index a0dfb80..8f704c1 100644
--- a/p2p/base/regathering_controller.h
+++ b/p2p/base/regathering_controller.h
@@ -74,7 +74,7 @@
   void OnIceTransportStateChanged(cricket::IceTransportInternal*) {}
   void OnIceTransportWritableState(rtc::PacketTransportInternal*) {}
   void OnIceTransportReceivingState(rtc::PacketTransportInternal*) {}
-  void OnIceTransportNetworkRouteChanged(absl::optional<rtc::NetworkRoute>) {}
+  void OnIceTransportNetworkRouteChanged(std::optional<rtc::NetworkRoute>) {}
   // Schedules delayed and repeated regathering of local candidates on failed
   // networks, where the delay in milliseconds is given by the config. Each
   // repetition is separated by the same delay. When scheduled, all previous
diff --git a/p2p/base/stun_dictionary.cc b/p2p/base/stun_dictionary.cc
index 4ace826..b234f98 100644
--- a/p2p/base/stun_dictionary.cc
+++ b/p2p/base/stun_dictionary.cc
@@ -87,7 +87,7 @@
 
 const StunAttribute* StunDictionaryView::GetOrNull(
     int key,
-    absl::optional<StunAttributeValueType> type) const {
+    std::optional<StunAttributeValueType> type) const {
   const auto it = attrs_.find(key);
   if (it == attrs_.end()) {
     return nullptr;
diff --git a/p2p/base/stun_dictionary.h b/p2p/base/stun_dictionary.h
index f93a1f1..3442a91 100644
--- a/p2p/base/stun_dictionary.h
+++ b/p2p/base/stun_dictionary.h
@@ -81,7 +81,7 @@
 
   const StunAttribute* GetOrNull(
       int key,
-      absl::optional<StunAttributeValueType> = absl::nullopt) const;
+      std::optional<StunAttributeValueType> = std::nullopt) const;
   size_t GetLength(int key) const;
   static webrtc::RTCErrorOr<
       std::pair<uint64_t, std::deque<std::unique_ptr<StunAttribute>>>>
diff --git a/p2p/base/stun_port.cc b/p2p/base/stun_port.cc
index bdd8830..5a9906d 100644
--- a/p2p/base/stun_port.cc
+++ b/p2p/base/stun_port.cc
@@ -341,11 +341,11 @@
   return PROTO_UDP;
 }
 
-void UDPPort::GetStunStats(absl::optional<StunStats>* stats) {
+void UDPPort::GetStunStats(std::optional<StunStats>* stats) {
   *stats = stats_;
 }
 
-void UDPPort::set_stun_keepalive_delay(const absl::optional<int>& delay) {
+void UDPPort::set_stun_keepalive_delay(const std::optional<int>& delay) {
   stun_keepalive_delay_ = delay.value_or(STUN_KEEPALIVE_INTERVAL);
 }
 
@@ -614,7 +614,7 @@
     uint16_t min_port,
     uint16_t max_port,
     const ServerAddresses& servers,
-    absl::optional<int> stun_keepalive_interval) {
+    std::optional<int> stun_keepalive_interval) {
   // Using `new` to access a non-public constructor.
   auto port = absl::WrapUnique(new StunPort(args, min_port, max_port, servers));
   port->set_stun_keepalive_delay(stun_keepalive_interval);
@@ -633,7 +633,7 @@
     absl::string_view username,
     absl::string_view password,
     const ServerAddresses& servers,
-    absl::optional<int> stun_keepalive_interval,
+    std::optional<int> stun_keepalive_interval,
     const webrtc::FieldTrialsView* field_trials) {
   return Create({.network_thread = thread,
                  .socket_factory = factory,
diff --git a/p2p/base/stun_port.h b/p2p/base/stun_port.h
index 3133a41..89617f0 100644
--- a/p2p/base/stun_port.h
+++ b/p2p/base/stun_port.h
@@ -39,7 +39,7 @@
       const PortParametersRef& args,
       rtc::AsyncPacketSocket* socket,
       bool emit_local_for_anyaddress,
-      absl::optional<int> stun_keepalive_interval) {
+      std::optional<int> stun_keepalive_interval) {
     // Using `new` to access a non-public constructor.
     auto port =
         absl::WrapUnique(new UDPPort(args, webrtc::IceCandidateType::kHost,
@@ -59,7 +59,7 @@
              absl::string_view username,
              absl::string_view password,
              bool emit_local_for_anyaddress,
-             absl::optional<int> stun_keepalive_interval,
+             std::optional<int> stun_keepalive_interval,
              const webrtc::FieldTrialsView* field_trials = nullptr) {
     return Create({.network_thread = thread,
                    .socket_factory = factory,
@@ -75,7 +75,7 @@
       uint16_t min_port,
       uint16_t max_port,
       bool emit_local_for_anyaddress,
-      absl::optional<int> stun_keepalive_interval) {
+      std::optional<int> stun_keepalive_interval) {
     // Using `new` to access a non-public constructor.
     auto port = absl::WrapUnique(
         new UDPPort(args, webrtc::IceCandidateType::kHost, min_port, max_port,
@@ -96,7 +96,7 @@
              absl::string_view username,
              absl::string_view password,
              bool emit_local_for_anyaddress,
-             absl::optional<int> stun_keepalive_interval,
+             std::optional<int> stun_keepalive_interval,
              const webrtc::FieldTrialsView* field_trials = nullptr) {
     return Create({.network_thread = thread,
                    .socket_factory = factory,
@@ -133,9 +133,9 @@
   bool SupportsProtocol(absl::string_view protocol) const override;
   ProtocolType GetProtocol() const override;
 
-  void GetStunStats(absl::optional<StunStats>* stats) override;
+  void GetStunStats(std::optional<StunStats>* stats) override;
 
-  void set_stun_keepalive_delay(const absl::optional<int>& delay);
+  void set_stun_keepalive_delay(const std::optional<int>& delay);
   int stun_keepalive_delay() const { return stun_keepalive_delay_; }
 
   // Visible for testing.
@@ -290,7 +290,7 @@
       uint16_t min_port,
       uint16_t max_port,
       const ServerAddresses& servers,
-      absl::optional<int> stun_keepalive_interval);
+      std::optional<int> stun_keepalive_interval);
   [[deprecated("Pass arguments using PortParametersRef")]] static std::
       unique_ptr<StunPort>
       Create(webrtc::TaskQueueBase* thread,
@@ -301,7 +301,7 @@
              absl::string_view username,
              absl::string_view password,
              const ServerAddresses& servers,
-             absl::optional<int> stun_keepalive_interval,
+             std::optional<int> stun_keepalive_interval,
              const webrtc::FieldTrialsView* field_trials);
   void PrepareAddress() override;
 
diff --git a/p2p/base/stun_port_unittest.cc b/p2p/base/stun_port_unittest.cc
index 08c224a..0f8ecde 100644
--- a/p2p/base/stun_port_unittest.cc
+++ b/p2p/base/stun_port_unittest.cc
@@ -144,7 +144,7 @@
          .ice_username_fragment = rtc::CreateRandomString(16),
          .ice_password = rtc::CreateRandomString(22),
          .field_trials = field_trials},
-        0, 0, stun_servers, absl::nullopt);
+        0, 0, stun_servers, std::nullopt);
     stun_port_->SetIceTiebreaker(kTiebreakerDefault);
     stun_port_->set_stun_keepalive_delay(stun_keepalive_delay_);
     // If `stun_keepalive_lifetime_` is negative, let the stun port
@@ -181,7 +181,7 @@
          .ice_username_fragment = rtc::CreateRandomString(16),
          .ice_password = rtc::CreateRandomString(22),
          .field_trials = field_trials},
-        socket_.get(), false, absl::nullopt);
+        socket_.get(), false, std::nullopt);
     ASSERT_TRUE(stun_port_ != NULL);
     stun_port_->SetIceTiebreaker(kTiebreakerDefault);
     ServerAddresses stun_servers;
diff --git a/p2p/base/transport_description.cc b/p2p/base/transport_description.cc
index f3b1fbb..8f4ec01 100644
--- a/p2p/base/transport_description.cc
+++ b/p2p/base/transport_description.cc
@@ -109,7 +109,7 @@
   return RTCError::OK();
 }
 
-absl::optional<ConnectionRole> StringToConnectionRole(
+std::optional<ConnectionRole> StringToConnectionRole(
     absl::string_view role_str) {
   const char* const roles[] = {
       CONNECTIONROLE_ACTIVE_STR, CONNECTIONROLE_PASSIVE_STR,
@@ -120,7 +120,7 @@
       return static_cast<ConnectionRole>(CONNECTIONROLE_ACTIVE + i);
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool ConnectionRoleToString(const ConnectionRole& role, std::string* role_str) {
diff --git a/p2p/base/transport_description.h b/p2p/base/transport_description.h
index 53a1804..d1c161e 100644
--- a/p2p/base/transport_description.h
+++ b/p2p/base/transport_description.h
@@ -12,12 +12,12 @@
 #define P2P_BASE_TRANSPORT_DESCRIPTION_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/rtc_error.h"
 #include "p2p/base/p2p_constants.h"
 #include "rtc_base/ssl_fingerprint.h"
@@ -87,7 +87,7 @@
 constexpr auto* ICE_OPTION_TRICKLE = "trickle";
 constexpr auto* ICE_OPTION_RENOMINATION = "renomination";
 
-absl::optional<ConnectionRole> StringToConnectionRole(
+std::optional<ConnectionRole> StringToConnectionRole(
     absl::string_view role_str);
 bool ConnectionRoleToString(const ConnectionRole& role, std::string* role_str);
 
diff --git a/p2p/base/turn_port.cc b/p2p/base/turn_port.cc
index 4dba2a5..f52e1f2 100644
--- a/p2p/base/turn_port.cc
+++ b/p2p/base/turn_port.cc
@@ -13,13 +13,13 @@
 #include <cstdint>
 #include <functional>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/task_queue/pending_task_safety_flag.h"
 #include "api/transport/stun.h"
 #include "api/turn_customizer.h"
diff --git a/p2p/base/turn_port_unittest.cc b/p2p/base/turn_port_unittest.cc
index b0f3124..6c16a9d 100644
--- a/p2p/base/turn_port_unittest.cc
+++ b/p2p/base/turn_port_unittest.cc
@@ -19,10 +19,10 @@
 
 #include <list>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/units/time_delta.h"
 #include "p2p/base/basic_packet_socket_factory.h"
 #include "p2p/base/connection.h"
@@ -372,7 +372,7 @@
                                  .ice_username_fragment = kIceUfrag2,
                                  .ice_password = kIcePwd2,
                                  .field_trials = &field_trials_},
-                                0, 0, false, absl::nullopt);
+                                0, 0, false, std::nullopt);
     // UDP port will be controlled.
     udp_port_->SetIceRole(ICEROLE_CONTROLLED);
     udp_port_->SetIceTiebreaker(kTiebreakerDefault);
diff --git a/p2p/base/wrapping_active_ice_controller.h b/p2p/base/wrapping_active_ice_controller.h
index 449c0f0..bf5b8ea 100644
--- a/p2p/base/wrapping_active_ice_controller.h
+++ b/p2p/base/wrapping_active_ice_controller.h
@@ -12,8 +12,8 @@
 #define P2P_BASE_WRAPPING_ACTIVE_ICE_CONTROLLER_H_
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/task_queue/pending_task_safety_flag.h"
 #include "p2p/base/active_ice_controller_interface.h"
 #include "p2p/base/connection.h"
diff --git a/p2p/client/basic_port_allocator.cc b/p2p/client/basic_port_allocator.cc
index c8b293a..3e8ddf4 100644
--- a/p2p/client/basic_port_allocator.cc
+++ b/p2p/client/basic_port_allocator.cc
@@ -494,7 +494,7 @@
   for (auto* port : ports) {
     auto candidates = port->Candidates();
     for (const auto& candidate : candidates) {
-      absl::optional<StunStats> stun_stats;
+      std::optional<StunStats> stun_stats;
       port->GetStunStats(&stun_stats);
       CandidateStats candidate_stats(allocator_->SanitizeCandidate(candidate),
                                      std::move(stun_stats));
@@ -504,7 +504,7 @@
 }
 
 void BasicPortAllocatorSession::SetStunKeepaliveIntervalForReadyPorts(
-    const absl::optional<int>& stun_keepalive_interval) {
+    const std::optional<int>& stun_keepalive_interval) {
   RTC_DCHECK_RUN_ON(network_thread_);
   auto ports = ReadyPorts();
   for (PortInterface* port : ports) {
diff --git a/p2p/client/basic_port_allocator.h b/p2p/client/basic_port_allocator.h
index 25201fd..3c275c9 100644
--- a/p2p/client/basic_port_allocator.h
+++ b/p2p/client/basic_port_allocator.h
@@ -151,7 +151,7 @@
   void GetCandidateStatsFromReadyPorts(
       CandidateStatsList* candidate_stats_list) const override;
   void SetStunKeepaliveIntervalForReadyPorts(
-      const absl::optional<int>& stun_keepalive_interval) override;
+      const std::optional<int>& stun_keepalive_interval) override;
   void PruneAllPorts() override;
   static std::vector<const rtc::Network*> SelectIPv6Networks(
       std::vector<const rtc::Network*>& all_ipv6_networks,
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index fd94772..f16e2c1 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -108,7 +108,6 @@
     "../rtc_base/third_party/sigslot",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -142,7 +141,6 @@
     "../rtc_base:checks",
     "../rtc_base:logging",
     "../rtc_base:ssl_adapter",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -169,7 +167,6 @@
     "../rtc_base:ssl_adapter",
     "../rtc_base:threading",
     "../rtc_base/synchronization:mutex",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -251,7 +248,6 @@
     "../rtc_base:ssl_adapter",
     "../rtc_base:stringutils",
     "../rtc_base:threading",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -339,7 +335,6 @@
     "../rtc_base/third_party/sigslot",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/functional:any_invocable",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -394,7 +389,6 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -485,7 +479,6 @@
     "../api:scoped_refptr",
     "../api/crypto:frame_decryptor_interface",
     "../api/transport/rtp:rtp_source",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -528,7 +521,6 @@
     "../rtc_base/network:received_packet",
     "../rtc_base/network:sent_packet",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -571,7 +563,6 @@
     "../rtc_base:macromagic",
     "../rtc_base:threading",
     "../rtc_base/third_party/sigslot",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -595,7 +586,6 @@
     "../rtc_base:copy_on_write_buffer",
     "../rtc_base:logging",
     "../rtc_base:ssl_adapter",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 rtc_source_set("srtp_session") {
@@ -659,7 +649,6 @@
     "../rtc_base:zero_memory",
     "../rtc_base/third_party/base64",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -707,7 +696,6 @@
     "../api/video:recordable_encoded_frame",
     "../api/video:video_frame",
     "../rtc_base:threading",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -802,7 +790,6 @@
     "../rtc_base/containers:flat_set",
     "../rtc_base/system:no_unique_address",
     "../rtc_base/system:unused",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -881,7 +868,6 @@
     "../rtc_base:threading",
     "../rtc_base:weak_ptr",
     "//third_party/abseil-cpp/absl/algorithm:container",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -898,7 +884,6 @@
     "../api/audio:audio_device",
     "../call:call_interfaces",
     "../modules/audio_device",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -970,7 +955,6 @@
     "../rtc_base/synchronization:mutex",
     "//third_party/abseil-cpp/absl/functional:bind_front",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -984,7 +968,6 @@
     "../api:rtc_stats_api",
     "../api:scoped_refptr",
     "../rtc_base:checks",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1073,7 +1056,6 @@
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 rtc_source_set("jsep_ice_candidate") {
@@ -1195,7 +1177,6 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1215,7 +1196,6 @@
     "../rtc_base:stringutils",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 rtc_source_set("sdp_utils") {
@@ -1281,7 +1261,6 @@
     "../rtc_base:threading",
     "../rtc_base:timeutils",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 rtc_source_set("stream_collection") {
@@ -1307,7 +1286,6 @@
     "../rtc_base:checks",
     "../rtc_base:refcount",
     "../rtc_base:threading",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 rtc_source_set("webrtc_sdp") {
@@ -1360,7 +1338,6 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 rtc_source_set("webrtc_session_description_factory") {
@@ -1392,7 +1369,6 @@
     "../rtc_base:weak_ptr",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/functional:any_invocable",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1580,7 +1556,6 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1619,7 +1594,6 @@
     "../rtc_base:ssl",
     "../rtc_base:threading",
     "../rtc_base:weak_ptr",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1640,7 +1614,6 @@
     "../rtc_base:checks",
     "../rtc_base:macromagic",
     "../rtc_base/system:no_unique_address",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1666,7 +1639,6 @@
     "../rtc_base:checks",
     "../rtc_base:logging",
     "../rtc_base:threading",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1698,7 +1670,6 @@
     "../rtc_base:macromagic",
     "../rtc_base:threading",
     "../rtc_base/system:no_unique_address",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1732,7 +1703,6 @@
     "../rtc_base:macromagic",
     "../rtc_base:threading",
     "../rtc_base/system:no_unique_address",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1787,7 +1757,6 @@
     "../rtc_base:macromagic",
     "../rtc_base:threading",
     "../rtc_base/system:no_unique_address",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1810,7 +1779,6 @@
     "../rtc_base:safe_conversions",
     "../rtc_base:safe_minmax",
     "../rtc_base/system:no_unique_address",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1835,7 +1803,6 @@
     "../rtc_base:stringutils",
     "../rtc_base/synchronization:mutex",
     "//third_party/abseil-cpp/absl/algorithm:container",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1873,7 +1840,6 @@
     "../rtc_base/synchronization:mutex",
     "../rtc_base/third_party/sigslot",
     "//third_party/abseil-cpp/absl/algorithm:container",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1896,7 +1862,6 @@
     "../rtc_base:checks",
     "../rtc_base:logging",
     "../rtc_base:stringutils",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1952,7 +1917,6 @@
     "../rtc_base:macromagic",
     "../rtc_base/system:no_unique_address",
     "../rtc_base/system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -2111,7 +2075,6 @@
       "//third_party/abseil-cpp/absl/memory",
       "//third_party/abseil-cpp/absl/strings",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
 
     include_dirs = []
@@ -2185,7 +2148,6 @@
       "../rtc_base:threading",
       "../system_wrappers",
       "../test:test_support",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -2210,7 +2172,6 @@
       "../rtc_base:gunit_helpers",
       "../rtc_base:logging",
       "../test:test_support",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -2240,7 +2201,6 @@
       "../test/time_controller:time_controller",
       "//third_party/abseil-cpp/absl/algorithm:container",
       "//third_party/abseil-cpp/absl/strings",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -2466,7 +2426,6 @@
       "//third_party/abseil-cpp/absl/algorithm:container",
       "//third_party/abseil-cpp/absl/memory",
       "//third_party/abseil-cpp/absl/strings",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
 
     if (is_android) {
@@ -2681,7 +2640,6 @@
       "//third_party/abseil-cpp/absl/algorithm:container",
       "//third_party/abseil-cpp/absl/memory",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -2819,7 +2777,6 @@
       "../test:test_support",
       "//third_party/abseil-cpp/absl/algorithm:container",
       "//third_party/abseil-cpp/absl/strings",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
diff --git a/pc/audio_rtp_receiver.cc b/pc/audio_rtp_receiver.cc
index 0f395a7..705ec1b 100644
--- a/pc/audio_rtp_receiver.cc
+++ b/pc/audio_rtp_receiver.cc
@@ -165,7 +165,7 @@
   track_->internal()->set_ended();
 }
 
-void AudioRtpReceiver::RestartMediaChannel(absl::optional<uint32_t> ssrc) {
+void AudioRtpReceiver::RestartMediaChannel(std::optional<uint32_t> ssrc) {
   RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
   bool enabled = track_->internal()->enabled();
   MediaSourceInterface::SourceState state = source_->state();
@@ -177,7 +177,7 @@
 }
 
 void AudioRtpReceiver::RestartMediaChannel_w(
-    absl::optional<uint32_t> ssrc,
+    std::optional<uint32_t> ssrc,
     bool track_enabled,
     MediaSourceInterface::SourceState state) {
   RTC_DCHECK_RUN_ON(worker_thread_);
@@ -212,10 +212,10 @@
 
 void AudioRtpReceiver::SetupUnsignaledMediaChannel() {
   RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
-  RestartMediaChannel(absl::nullopt);
+  RestartMediaChannel(std::nullopt);
 }
 
-absl::optional<uint32_t> AudioRtpReceiver::ssrc() const {
+std::optional<uint32_t> AudioRtpReceiver::ssrc() const {
   RTC_DCHECK_RUN_ON(worker_thread_);
   if (!signaled_ssrc_.has_value() && media_channel_) {
     return media_channel_->GetUnsignaledSsrc();
@@ -314,7 +314,7 @@
 }
 
 void AudioRtpReceiver::SetJitterBufferMinimumDelay(
-    absl::optional<double> delay_seconds) {
+    std::optional<double> delay_seconds) {
   RTC_DCHECK_RUN_ON(worker_thread_);
   delay_.Set(delay_seconds);
   if (media_channel_ && signaled_ssrc_)
diff --git a/pc/audio_rtp_receiver.h b/pc/audio_rtp_receiver.h
index d0433c3..628690f 100644
--- a/pc/audio_rtp_receiver.h
+++ b/pc/audio_rtp_receiver.h
@@ -13,10 +13,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/crypto/frame_decryptor_interface.h"
 #include "api/dtls_transport_interface.h"
 #include "api/frame_transformer_interface.h"
@@ -100,7 +100,7 @@
   void Stop() override;
   void SetupMediaChannel(uint32_t ssrc) override;
   void SetupUnsignaledMediaChannel() override;
-  absl::optional<uint32_t> ssrc() const override;
+  std::optional<uint32_t> ssrc() const override;
   void NotifyFirstPacketReceived() override;
   void set_stream_ids(std::vector<std::string> stream_ids) override;
   void set_transport(
@@ -110,7 +110,7 @@
   void SetObserver(RtpReceiverObserverInterface* observer) override;
 
   void SetJitterBufferMinimumDelay(
-      absl::optional<double> delay_seconds) override;
+      std::optional<double> delay_seconds) override;
 
   void SetMediaChannel(
       cricket::MediaReceiveChannelInterface* media_channel) override;
@@ -121,9 +121,9 @@
       rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) override;
 
  private:
-  void RestartMediaChannel(absl::optional<uint32_t> ssrc)
+  void RestartMediaChannel(std::optional<uint32_t> ssrc)
       RTC_RUN_ON(&signaling_thread_checker_);
-  void RestartMediaChannel_w(absl::optional<uint32_t> ssrc,
+  void RestartMediaChannel_w(std::optional<uint32_t> ssrc,
                              bool track_enabled,
                              MediaSourceInterface::SourceState state)
       RTC_RUN_ON(worker_thread_);
@@ -137,7 +137,7 @@
   const rtc::scoped_refptr<AudioTrackProxyWithInternal<AudioTrack>> track_;
   cricket::VoiceMediaReceiveChannelInterface* media_channel_
       RTC_GUARDED_BY(worker_thread_) = nullptr;
-  absl::optional<uint32_t> signaled_ssrc_ RTC_GUARDED_BY(worker_thread_);
+  std::optional<uint32_t> signaled_ssrc_ RTC_GUARDED_BY(worker_thread_);
   std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams_
       RTC_GUARDED_BY(&signaling_thread_checker_);
   bool cached_track_enabled_ RTC_GUARDED_BY(&signaling_thread_checker_);
diff --git a/pc/channel.cc b/pc/channel.cc
index 483b2ce..af130f8 100644
--- a/pc/channel.cc
+++ b/pc/channel.cc
@@ -170,7 +170,7 @@
   rtp_transport_->SubscribeReadyToSend(
       this, [this](bool ready) { OnTransportReadyToSend(ready); });
   rtp_transport_->SubscribeNetworkRouteChanged(
-      this, [this](absl::optional<rtc::NetworkRoute> route) {
+      this, [this](std::optional<rtc::NetworkRoute> route) {
         OnNetworkRouteChanged(route);
       });
   rtp_transport_->SubscribeWritableState(
@@ -335,7 +335,7 @@
 }
 
 void BaseChannel::OnNetworkRouteChanged(
-    absl::optional<rtc::NetworkRoute> network_route) {
+    std::optional<rtc::NetworkRoute> network_route) {
   RTC_DCHECK_RUN_ON(network_thread());
   RTC_DCHECK(network_initialized());
 
@@ -449,7 +449,7 @@
 
 bool BaseChannel::MaybeUpdateDemuxerAndRtpExtensions_w(
     bool update_demuxer,
-    absl::optional<RtpHeaderExtensions> extensions,
+    std::optional<RtpHeaderExtensions> extensions,
     std::string& error_desc) {
   if (extensions) {
     if (rtp_header_extensions_ == extensions) {
@@ -911,8 +911,8 @@
   bool success = MaybeUpdateDemuxerAndRtpExtensions_w(
       criteria_modified,
       update_header_extensions
-          ? absl::optional<RtpHeaderExtensions>(std::move(header_extensions))
-          : absl::nullopt,
+          ? std::optional<RtpHeaderExtensions>(std::move(header_extensions))
+          : std::nullopt,
       error_desc);
 
   RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(1);
@@ -1056,7 +1056,7 @@
       }
 
       if (may_ignore_packetization) {
-        send_codec.packetization = absl::nullopt;
+        send_codec.packetization = std::nullopt;
         needs_send_params_update = true;
       } else if (!has_matching_packetization) {
         error_desc = StringFormat(
@@ -1113,8 +1113,8 @@
   bool success = MaybeUpdateDemuxerAndRtpExtensions_w(
       criteria_modified,
       update_header_extensions
-          ? absl::optional<RtpHeaderExtensions>(std::move(header_extensions))
-          : absl::nullopt,
+          ? std::optional<RtpHeaderExtensions>(std::move(header_extensions))
+          : std::nullopt,
       error_desc);
 
   RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(1);
@@ -1170,7 +1170,7 @@
       }
 
       if (may_ignore_packetization) {
-        recv_codec.packetization = absl::nullopt;
+        recv_codec.packetization = std::nullopt;
         needs_recv_params_update = true;
       } else if (!has_matching_packetization) {
         error_desc = StringFormat(
diff --git a/pc/channel.h b/pc/channel.h
index c933091..9a1b0a7 100644
--- a/pc/channel.h
+++ b/pc/channel.h
@@ -15,12 +15,12 @@
 
 #include <functional>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/crypto/crypto_options.h"
 #include "api/jsep.h"
 #include "api/media_types.h"
@@ -228,7 +228,7 @@
   // From RtpTransportInternal
   void OnWritableState(bool writable);
 
-  void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route);
+  void OnNetworkRouteChanged(std::optional<rtc::NetworkRoute> network_route);
 
   bool SendPacket(bool rtcp,
                   rtc::CopyOnWriteBuffer* packet,
@@ -295,7 +295,7 @@
   // failed, which needs to be treated as an error.
   bool MaybeUpdateDemuxerAndRtpExtensions_w(
       bool update_demuxer,
-      absl::optional<RtpHeaderExtensions> extensions,
+      std::optional<RtpHeaderExtensions> extensions,
       std::string& error_desc) RTC_RUN_ON(worker_thread());
 
   bool RegisterRtpDemuxerSink_w() RTC_RUN_ON(worker_thread());
diff --git a/pc/channel_unittest.cc b/pc/channel_unittest.cc
index a651391..e4ab8fd 100644
--- a/pc/channel_unittest.cc
+++ b/pc/channel_unittest.cc
@@ -936,7 +936,7 @@
       rtc::NetworkRoute network_route;
       // The transport channel becomes disconnected.
       fake_rtp_dtls_transport1_->ice_transport()->SignalNetworkRouteChanged(
-          absl::optional<rtc::NetworkRoute>(network_route));
+          std::optional<rtc::NetworkRoute>(network_route));
     });
     WaitForThreads();
     EXPECT_EQ(1, media_send_channel1_impl->num_network_route_changes());
@@ -955,7 +955,7 @@
       // The transport channel becomes connected.
       fake_rtp_dtls_transport1_->ice_transport()->SignalNetworkRouteChanged(
 
-          absl::optional<rtc::NetworkRoute>(network_route));
+          std::optional<rtc::NetworkRoute>(network_route));
     });
     WaitForThreads();
     EXPECT_EQ(1, media_send_channel1_impl->num_network_route_changes());
@@ -1331,7 +1331,7 @@
     return channel1_->SetRemoteContent(&content, SdpType::kOffer, NULL);
   }
 
-  webrtc::RtpParameters BitrateLimitedParameters(absl::optional<int> limit) {
+  webrtc::RtpParameters BitrateLimitedParameters(std::optional<int> limit) {
     webrtc::RtpParameters parameters;
     webrtc::RtpEncodingParameters encoding;
     encoding.max_bitrate_bps = limit;
@@ -1340,7 +1340,7 @@
   }
 
   void VerifyMaxBitrate(const webrtc::RtpParameters& parameters,
-                        absl::optional<int> expected_bitrate) {
+                        std::optional<int> expected_bitrate) {
     EXPECT_EQ(1UL, parameters.encodings.size());
     EXPECT_EQ(expected_bitrate, parameters.encodings[0].max_bitrate_bps);
   }
@@ -1352,7 +1352,7 @@
                                            SdpType::kOffer, err));
     EXPECT_EQ(media_send_channel1_impl()->max_bps(), -1);
     VerifyMaxBitrate(media_send_channel1()->GetRtpSendParameters(kSsrc1),
-                     absl::nullopt);
+                     std::nullopt);
   }
 
   // Test that when a channel gets new RtpTransport with a call to
@@ -2113,7 +2113,7 @@
   EXPECT_TRUE(
       media_receive_channel1_impl()->recv_codecs()[0].Matches(kVp8Codec));
   EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[0].packetization,
-            absl::nullopt);
+            std::nullopt);
   EXPECT_TRUE(
       media_receive_channel1_impl()->recv_codecs()[1].Matches(vp9_codec));
   EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[1].packetization,
@@ -2136,7 +2136,7 @@
   ASSERT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(2));
   EXPECT_TRUE(media_send_channel1_impl()->send_codecs()[0].Matches(kVp8Codec));
   EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization,
-            absl::nullopt);
+            std::nullopt);
   EXPECT_TRUE(media_send_channel1_impl()->send_codecs()[1].Matches(vp9_codec));
   EXPECT_EQ(media_send_channel1_impl()->send_codecs()[1].packetization,
             cricket::kPacketizationParamRaw);
@@ -2160,7 +2160,7 @@
   EXPECT_TRUE(
       media_receive_channel1_impl()->recv_codecs()[0].Matches(kVp8Codec));
   EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[0].packetization,
-            absl::nullopt);
+            std::nullopt);
   EXPECT_TRUE(
       media_receive_channel1_impl()->recv_codecs()[1].Matches(vp9_codec));
   EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[1].packetization,
@@ -2168,7 +2168,7 @@
   EXPECT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(2));
   EXPECT_TRUE(media_send_channel1_impl()->send_codecs()[0].Matches(kVp8Codec));
   EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization,
-            absl::nullopt);
+            std::nullopt);
   EXPECT_TRUE(media_send_channel1_impl()->send_codecs()[1].Matches(vp9_codec));
   EXPECT_EQ(media_send_channel1_impl()->send_codecs()[1].packetization,
             cricket::kPacketizationParamRaw);
@@ -2190,10 +2190,10 @@
   EXPECT_TRUE(channel1_->SetLocalContent(&local_video, SdpType::kAnswer, err));
   ASSERT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::SizeIs(1));
   EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[0].packetization,
-            absl::nullopt);
+            std::nullopt);
   ASSERT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(1));
   EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization,
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST_F(VideoChannelSingleThreadTest, TestSetRemoteAnswerWithoutPacketization) {
@@ -2213,10 +2213,10 @@
       channel1_->SetRemoteContent(&remote_video, SdpType::kAnswer, err));
   ASSERT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::SizeIs(1));
   EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[0].packetization,
-            absl::nullopt);
+            std::nullopt);
   ASSERT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(1));
   EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization,
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST_F(VideoChannelSingleThreadTest,
@@ -2264,7 +2264,7 @@
   EXPECT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::IsEmpty());
   ASSERT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(1));
   EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization,
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST_F(VideoChannelSingleThreadTest,
@@ -2294,13 +2294,13 @@
                   AllOf(Field(&cricket::Codec::id, 97),
                         Field(&cricket::Codec::packetization, "bar")),
                   AllOf(Field(&cricket::Codec::id, 99),
-                        Field(&cricket::Codec::packetization, absl::nullopt))));
+                        Field(&cricket::Codec::packetization, std::nullopt))));
   EXPECT_THAT(
       media_send_channel1_impl()->send_codecs(),
       ElementsAre(AllOf(Field(&cricket::Codec::id, 96),
                         Field(&cricket::Codec::packetization, "foo")),
                   AllOf(Field(&cricket::Codec::id, 98),
-                        Field(&cricket::Codec::packetization, absl::nullopt))));
+                        Field(&cricket::Codec::packetization, std::nullopt))));
 }
 
 TEST_F(VideoChannelSingleThreadTest,
@@ -2328,7 +2328,7 @@
       ElementsAre(AllOf(Field(&cricket::Codec::id, 96),
                         Field(&cricket::Codec::packetization, "foo")),
                   AllOf(Field(&cricket::Codec::id, 98),
-                        Field(&cricket::Codec::packetization, absl::nullopt))));
+                        Field(&cricket::Codec::packetization, std::nullopt))));
   EXPECT_THAT(
       media_send_channel1_impl()->send_codecs(),
       ElementsAre(AllOf(Field(&cricket::Codec::id, 96),
@@ -2336,7 +2336,7 @@
                   AllOf(Field(&cricket::Codec::id, 97),
                         Field(&cricket::Codec::packetization, "bar")),
                   AllOf(Field(&cricket::Codec::id, 99),
-                        Field(&cricket::Codec::packetization, absl::nullopt))));
+                        Field(&cricket::Codec::packetization, std::nullopt))));
 }
 
 TEST_F(VideoChannelSingleThreadTest,
@@ -2358,7 +2358,7 @@
   EXPECT_THAT(
       media_receive_channel1_impl()->recv_codecs(),
       ElementsAre(AllOf(Field(&cricket::Codec::id, 96),
-                        Field(&cricket::Codec::packetization, absl::nullopt)),
+                        Field(&cricket::Codec::packetization, std::nullopt)),
                   AllOf(Field(&cricket::Codec::id, 97),
                         Field(&cricket::Codec::packetization,
                               cricket::kPacketizationParamRaw))));
@@ -2368,7 +2368,7 @@
                         Field(&cricket::Codec::packetization,
                               cricket::kPacketizationParamRaw)),
                   AllOf(Field(&cricket::Codec::id, 96),
-                        Field(&cricket::Codec::packetization, absl::nullopt))));
+                        Field(&cricket::Codec::packetization, std::nullopt))));
 }
 
 TEST_F(VideoChannelSingleThreadTest,
@@ -2393,11 +2393,11 @@
                         Field(&cricket::Codec::packetization,
                               cricket::kPacketizationParamRaw)),
                   AllOf(Field(&cricket::Codec::id, 96),
-                        Field(&cricket::Codec::packetization, absl::nullopt))));
+                        Field(&cricket::Codec::packetization, std::nullopt))));
   EXPECT_THAT(
       media_send_channel1_impl()->send_codecs(),
       ElementsAre(AllOf(Field(&cricket::Codec::id, 96),
-                        Field(&cricket::Codec::packetization, absl::nullopt)),
+                        Field(&cricket::Codec::packetization, std::nullopt)),
                   AllOf(Field(&cricket::Codec::id, 97),
                         Field(&cricket::Codec::packetization,
                               cricket::kPacketizationParamRaw))));
diff --git a/pc/data_channel_controller.cc b/pc/data_channel_controller.cc
index e252e8f..3445e89 100644
--- a/pc/data_channel_controller.cc
+++ b/pc/data_channel_controller.cc
@@ -11,10 +11,10 @@
 #include "pc/data_channel_controller.h"
 
 #include <cstdint>
+#include <optional>
 #include <utility>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/peer_connection_interface.h"
 #include "api/priority.h"
 #include "api/rtc_error.h"
@@ -300,8 +300,8 @@
 
 // RTC_RUN_ON(network_thread())
 RTCError DataChannelController::ReserveOrAllocateSid(
-    absl::optional<StreamId>& sid,
-    absl::optional<rtc::SSLRole> fallback_ssl_role) {
+    std::optional<StreamId>& sid,
+    std::optional<rtc::SSLRole> fallback_ssl_role) {
   if (sid.has_value()) {
     return sid_allocator_.ReserveSid(*sid)
                ? RTCError::OK()
@@ -309,7 +309,7 @@
   }
 
   // Attempt to allocate an ID based on the negotiated role.
-  absl::optional<rtc::SSLRole> role = pc_->GetSctpSslRole_n();
+  std::optional<rtc::SSLRole> role = pc_->GetSctpSslRole_n();
   if (!role)
     role = fallback_ssl_role;
   if (role) {
@@ -327,7 +327,7 @@
 RTCErrorOr<rtc::scoped_refptr<SctpDataChannel>>
 DataChannelController::CreateDataChannel(const std::string& label,
                                          InternalDataChannelInit& config) {
-  absl::optional<StreamId> sid = absl::nullopt;
+  std::optional<StreamId> sid = std::nullopt;
   if (config.id != -1) {
     if (config.id < 0 || config.id > cricket::kMaxSctpSid) {
       return RTCError(RTCErrorType::INVALID_RANGE, "StreamId out of range.");
@@ -413,7 +413,7 @@
   for (auto it = sctp_data_channels_n_.begin();
        it != sctp_data_channels_n_.end();) {
     if (!(*it)->sid_n().has_value()) {
-      absl::optional<StreamId> sid = sid_allocator_.AllocateSid(role);
+      std::optional<StreamId> sid = sid_allocator_.AllocateSid(role);
       if (sid.has_value()) {
         (*it)->SetSctpSid_n(*sid);
         AddSctpDataStream(*sid, (*it)->priority());
diff --git a/pc/data_channel_controller.h b/pc/data_channel_controller.h
index 74e00e0..916eb990 100644
--- a/pc/data_channel_controller.h
+++ b/pc/data_channel_controller.h
@@ -130,8 +130,8 @@
   // will still be unassigned upon return, but will be assigned later.
   // If the pool has been exhausted or a sid has already been reserved, an
   // error will be returned.
-  RTCError ReserveOrAllocateSid(absl::optional<StreamId>& sid,
-                                absl::optional<rtc::SSLRole> fallback_ssl_role)
+  RTCError ReserveOrAllocateSid(std::optional<StreamId>& sid,
+                                std::optional<rtc::SSLRole> fallback_ssl_role)
       RTC_RUN_ON(network_thread());
 
   // Called when all data channels need to be notified of a transport channel
diff --git a/pc/data_channel_controller_unittest.cc b/pc/data_channel_controller_unittest.cc
index f885079..78f914a 100644
--- a/pc/data_channel_controller_unittest.cc
+++ b/pc/data_channel_controller_unittest.cc
@@ -159,8 +159,8 @@
   int channel_id = 0;
 
   ON_CALL(*pc_, GetSctpSslRole_n).WillByDefault([&]() {
-    return absl::optional<rtc::SSLRole>((channel_id & 1) ? rtc::SSL_SERVER
-                                                         : rtc::SSL_CLIENT);
+    return std::optional<rtc::SSLRole>((channel_id & 1) ? rtc::SSL_SERVER
+                                                        : rtc::SSL_CLIENT);
   });
 
   DataChannelControllerForTest dcc(pc_.get(), &transport);
diff --git a/pc/data_channel_integrationtest.cc b/pc/data_channel_integrationtest.cc
index 1a23a17..d779b23 100644
--- a/pc/data_channel_integrationtest.cc
+++ b/pc/data_channel_integrationtest.cc
@@ -12,12 +12,12 @@
 
 #include <cstdlib>
 #include <iterator>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <vector>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/data_channel_interface.h"
 #include "api/dtls_transport_interface.h"
 #include "api/peer_connection_interface.h"
diff --git a/pc/data_channel_unittest.cc b/pc/data_channel_unittest.cc
index c5f6525..f16ed42 100644
--- a/pc/data_channel_unittest.cc
+++ b/pc/data_channel_unittest.cc
@@ -172,7 +172,7 @@
   // Check the non-const part of the configuration.
   EXPECT_EQ(channel_->id(), init_.id);
   network_thread_.BlockingCall(
-      [&]() { EXPECT_EQ(inner_channel_->sid_n(), absl::nullopt); });
+      [&]() { EXPECT_EQ(inner_channel_->sid_n(), std::nullopt); });
 
   SetChannelReady();
   EXPECT_EQ(channel_->id(), 0);
@@ -188,7 +188,7 @@
   EXPECT_TRUE(controller_->IsConnected(dc.get()));
 
   // The sid is not set yet, so it should not have added the streams.
-  absl::optional<StreamId> sid =
+  std::optional<StreamId> sid =
       network_thread_.BlockingCall([&]() { return dc->sid_n(); });
   EXPECT_FALSE(sid.has_value());
 
@@ -636,7 +636,7 @@
   StreamId old_id(1);
   EXPECT_TRUE(allocator_.ReserveSid(old_id));
 
-  absl::optional<StreamId> new_id = allocator_.AllocateSid(rtc::SSL_SERVER);
+  std::optional<StreamId> new_id = allocator_.AllocateSid(rtc::SSL_SERVER);
   EXPECT_TRUE(new_id.has_value());
   EXPECT_NE(old_id, new_id);
 
@@ -654,7 +654,7 @@
   EXPECT_TRUE(allocator_.ReserveSid(odd_id));
   EXPECT_TRUE(allocator_.ReserveSid(even_id));
 
-  absl::optional<StreamId> allocated_id =
+  std::optional<StreamId> allocated_id =
       allocator_.AllocateSid(rtc::SSL_SERVER);
   EXPECT_EQ(odd_id.stream_id_int() + 2, allocated_id->stream_id_int());
 
diff --git a/pc/dtls_srtp_transport.h b/pc/dtls_srtp_transport.h
index 654eb2f..12c2ffc 100644
--- a/pc/dtls_srtp_transport.h
+++ b/pc/dtls_srtp_transport.h
@@ -12,10 +12,10 @@
 #define PC_DTLS_SRTP_TRANSPORT_H_
 
 #include <functional>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/dtls_transport_interface.h"
 #include "api/rtc_error.h"
 #include "p2p/base/dtls_transport_internal.h"
@@ -83,8 +83,8 @@
   cricket::DtlsTransportInternal* rtcp_dtls_transport_ = nullptr;
 
   // The encrypted header extension IDs.
-  absl::optional<std::vector<int>> send_extension_ids_;
-  absl::optional<std::vector<int>> recv_extension_ids_;
+  std::optional<std::vector<int>> send_extension_ids_;
+  std::optional<std::vector<int>> recv_extension_ids_;
 
   bool active_reset_srtp_params_ = false;
   std::function<void(void)> on_dtls_state_change_;
diff --git a/pc/dtls_transport.cc b/pc/dtls_transport.cc
index 4888d9f..f14f51f 100644
--- a/pc/dtls_transport.cc
+++ b/pc/dtls_transport.cc
@@ -10,9 +10,9 @@
 
 #include "pc/dtls_transport.h"
 
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/dtls_transport_interface.h"
 #include "api/make_ref_counted.h"
 #include "api/sequence_checker.h"
@@ -109,7 +109,7 @@
         DtlsTransportState::kConnected) {
       bool success = true;
       rtc::SSLRole internal_role;
-      absl::optional<DtlsTransportTlsRole> role;
+      std::optional<DtlsTransportTlsRole> role;
       int ssl_cipher_suite;
       int tls_version;
       int srtp_cipher;
@@ -136,8 +136,8 @@
         RTC_LOG(LS_ERROR) << "DtlsTransport in connected state has incomplete "
                              "TLS information";
         set_info(DtlsTransportInformation(
-            internal_dtls_transport_->dtls_state(), role, absl::nullopt,
-            absl::nullopt, absl::nullopt,
+            internal_dtls_transport_->dtls_state(), role, std::nullopt,
+            std::nullopt, std::nullopt,
             internal_dtls_transport_->GetRemoteSSLCertChain()));
       }
     } else {
diff --git a/pc/dtls_transport_unittest.cc b/pc/dtls_transport_unittest.cc
index c234176..7d71f1e 100644
--- a/pc/dtls_transport_unittest.cc
+++ b/pc/dtls_transport_unittest.cc
@@ -10,10 +10,10 @@
 
 #include "pc/dtls_transport.h"
 
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/make_ref_counted.h"
 #include "api/rtc_error.h"
 #include "p2p/base/fake_dtls_transport.h"
diff --git a/pc/ice_server_parsing.cc b/pc/ice_server_parsing.cc
index 896305c..dc8122f 100644
--- a/pc/ice_server_parsing.cc
+++ b/pc/ice_server_parsing.cc
@@ -89,7 +89,7 @@
   return {ServiceType::INVALID, ""};
 }
 
-absl::optional<int> ParsePort(absl::string_view in_str) {
+std::optional<int> ParsePort(absl::string_view in_str) {
   // Make sure port only contains digits. StringToNumber doesn't check this.
   for (const char& c : in_str) {
     if (!std::isdigit(static_cast<unsigned char>(c))) {
@@ -123,7 +123,7 @@
     }
     auto colonpos = in_str.find(':', closebracket);
     if (absl::string_view::npos != colonpos) {
-      if (absl::optional<int> opt_port =
+      if (std::optional<int> opt_port =
               ParsePort(in_str.substr(closebracket + 2))) {
         port = *opt_port;
       } else {
@@ -135,7 +135,7 @@
     // IPv4address or reg-name syntax
     auto colonpos = in_str.find(':');
     if (absl::string_view::npos != colonpos) {
-      if (absl::optional<int> opt_port =
+      if (std::optional<int> opt_port =
               ParsePort(in_str.substr(colonpos + 1))) {
         port = *opt_port;
       } else {
@@ -196,7 +196,7 @@
           "ICE server parsing failed: Transport parameter missing value.");
     }
 
-    absl::optional<cricket::ProtocolType> proto =
+    std::optional<cricket::ProtocolType> proto =
         cricket::StringToProto(transport_tokens[1]);
     if (!proto ||
         (*proto != cricket::PROTO_UDP && *proto != cricket::PROTO_TCP)) {
diff --git a/pc/jitter_buffer_delay.cc b/pc/jitter_buffer_delay.cc
index f22b065..a747588 100644
--- a/pc/jitter_buffer_delay.cc
+++ b/pc/jitter_buffer_delay.cc
@@ -22,7 +22,7 @@
 
 namespace webrtc {
 
-void JitterBufferDelay::Set(absl::optional<double> delay_seconds) {
+void JitterBufferDelay::Set(std::optional<double> delay_seconds) {
   RTC_DCHECK_RUN_ON(&worker_thread_checker_);
   cached_delay_seconds_ = delay_seconds;
 }
diff --git a/pc/jitter_buffer_delay.h b/pc/jitter_buffer_delay.h
index caf713b..bc506fe 100644
--- a/pc/jitter_buffer_delay.h
+++ b/pc/jitter_buffer_delay.h
@@ -13,7 +13,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/sequence_checker.h"
 #include "rtc_base/system/no_unique_address.h"
 #include "rtc_base/thread_annotations.h"
@@ -27,13 +28,13 @@
  public:
   JitterBufferDelay() = default;
 
-  void Set(absl::optional<double> delay_seconds);
+  void Set(std::optional<double> delay_seconds);
   int GetMs() const;
 
  private:
   RTC_NO_UNIQUE_ADDRESS SequenceChecker worker_thread_checker_{
       SequenceChecker::kDetached};
-  absl::optional<double> cached_delay_seconds_
+  std::optional<double> cached_delay_seconds_
       RTC_GUARDED_BY(&worker_thread_checker_);
 };
 
diff --git a/pc/jsep_session_description.cc b/pc/jsep_session_description.cc
index 7fae445..a2e3ab8 100644
--- a/pc/jsep_session_description.cc
+++ b/pc/jsep_session_description.cc
@@ -11,9 +11,9 @@
 #include "api/jsep_session_description.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "p2p/base/p2p_constants.h"
 #include "p2p/base/port.h"
 #include "p2p/base/transport_description.h"
@@ -101,7 +101,7 @@
 // TODO(steveanton): Remove this default implementation once Chromium has been
 // updated.
 SdpType SessionDescriptionInterface::GetType() const {
-  absl::optional<SdpType> maybe_type = SdpTypeFromString(type());
+  std::optional<SdpType> maybe_type = SdpTypeFromString(type());
   if (maybe_type) {
     return *maybe_type;
   } else {
@@ -116,7 +116,7 @@
 SessionDescriptionInterface* CreateSessionDescription(const std::string& type,
                                                       const std::string& sdp,
                                                       SdpParseError* error) {
-  absl::optional<SdpType> maybe_type = SdpTypeFromString(type);
+  std::optional<SdpType> maybe_type = SdpTypeFromString(type);
   if (!maybe_type) {
     return nullptr;
   }
@@ -158,7 +158,7 @@
 JsepSessionDescription::JsepSessionDescription(SdpType type) : type_(type) {}
 
 JsepSessionDescription::JsepSessionDescription(const std::string& type) {
-  absl::optional<SdpType> maybe_type = SdpTypeFromString(type);
+  std::optional<SdpType> maybe_type = SdpTypeFromString(type);
   if (maybe_type) {
     type_ = *maybe_type;
   } else {
diff --git a/pc/jsep_transport.cc b/pc/jsep_transport.cc
index 5b2f265..95f7aed 100644
--- a/pc/jsep_transport.cc
+++ b/pc/jsep_transport.cc
@@ -305,16 +305,16 @@
   }
 }
 
-absl::optional<rtc::SSLRole> JsepTransport::GetDtlsRole() const {
+std::optional<rtc::SSLRole> JsepTransport::GetDtlsRole() const {
   RTC_DCHECK_RUN_ON(network_thread_);
   RTC_DCHECK(rtp_dtls_transport_);
   RTC_DCHECK(rtp_dtls_transport_->internal());
   rtc::SSLRole dtls_role;
   if (!rtp_dtls_transport_->internal()->GetDtlsRole(&dtls_role)) {
-    return absl::optional<rtc::SSLRole>();
+    return std::optional<rtc::SSLRole>();
   }
 
-  return absl::optional<rtc::SSLRole>(dtls_role);
+  return std::optional<rtc::SSLRole>(dtls_role);
 }
 
 bool JsepTransport::GetStats(TransportStats* stats) {
@@ -404,7 +404,7 @@
 
 webrtc::RTCError JsepTransport::SetNegotiatedDtlsParameters(
     DtlsTransportInternal* dtls_transport,
-    absl::optional<rtc::SSLRole> dtls_role,
+    std::optional<rtc::SSLRole> dtls_role,
     rtc::SSLFingerprint* remote_fingerprint) {
   RTC_DCHECK(dtls_transport);
   return dtls_transport->SetRemoteParameters(
@@ -475,7 +475,7 @@
                             "without applying any offer.");
   }
   std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint;
-  absl::optional<rtc::SSLRole> negotiated_dtls_role;
+  std::optional<rtc::SSLRole> negotiated_dtls_role;
 
   rtc::SSLFingerprint* local_fp =
       local_description_->transport_desc.identity_fingerprint.get();
@@ -523,7 +523,7 @@
     SdpType local_description_type,
     ConnectionRole local_connection_role,
     ConnectionRole remote_connection_role,
-    absl::optional<rtc::SSLRole>* negotiated_dtls_role) {
+    std::optional<rtc::SSLRole>* negotiated_dtls_role) {
   // From RFC 4145, section-4.1, The following are the values that the
   // 'setup' attribute can take in an offer/answer exchange:
   //       Offer      Answer
diff --git a/pc/jsep_transport.h b/pc/jsep_transport.h
index 3c14f13..005e606 100644
--- a/pc/jsep_transport.h
+++ b/pc/jsep_transport.h
@@ -14,10 +14,10 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/candidate.h"
 #include "api/ice_transport_interface.h"
 #include "api/jsep.h"
@@ -149,9 +149,9 @@
     return needs_ice_restart_;
   }
 
-  // Returns role if negotiated, or empty absl::optional if it hasn't been
+  // Returns role if negotiated, or empty std::optional if it hasn't been
   // negotiated yet.
-  absl::optional<rtc::SSLRole> GetDtlsRole() const;
+  std::optional<rtc::SSLRole> GetDtlsRole() const;
 
   // TODO(deadbeef): Make this const. See comment in transportcontroller.h.
   bool GetStats(TransportStats* stats);
@@ -274,7 +274,7 @@
       webrtc::SdpType local_description_type,
       ConnectionRole local_connection_role,
       ConnectionRole remote_connection_role,
-      absl::optional<rtc::SSLRole>* negotiated_dtls_role);
+      std::optional<rtc::SSLRole>* negotiated_dtls_role);
 
   // Pushes down the ICE parameters from the remote description.
   void SetRemoteIceParameters(const IceParameters& ice_parameters,
@@ -283,7 +283,7 @@
   // Pushes down the DTLS parameters obtained via negotiation.
   static webrtc::RTCError SetNegotiatedDtlsParameters(
       DtlsTransportInternal* dtls_transport,
-      absl::optional<rtc::SSLRole> dtls_role,
+      std::optional<rtc::SSLRole> dtls_role,
       rtc::SSLFingerprint* remote_fingerprint);
 
   bool GetTransportStats(DtlsTransportInternal* dtls_transport,
@@ -324,9 +324,9 @@
   RtcpMuxFilter rtcp_mux_negotiator_ RTC_GUARDED_BY(network_thread_);
 
   // Cache the encrypted header extension IDs for SDES negoitation.
-  absl::optional<std::vector<int>> send_extension_ids_
+  std::optional<std::vector<int>> send_extension_ids_
       RTC_GUARDED_BY(network_thread_);
-  absl::optional<std::vector<int>> recv_extension_ids_
+  std::optional<std::vector<int>> recv_extension_ids_
       RTC_GUARDED_BY(network_thread_);
 
   // This is invoked when RTCP-mux becomes active and
diff --git a/pc/jsep_transport_controller.cc b/pc/jsep_transport_controller.cc
index 05988ec..2780196 100644
--- a/pc/jsep_transport_controller.cc
+++ b/pc/jsep_transport_controller.cc
@@ -204,7 +204,7 @@
   return transport->needs_ice_restart();
 }
 
-absl::optional<rtc::SSLRole> JsepTransportController::GetDtlsRole(
+std::optional<rtc::SSLRole> JsepTransportController::GetDtlsRole(
     const std::string& mid) const {
   // TODO(tommi): Remove this hop. Currently it's called from the signaling
   // thread during negotiations, potentially multiple times.
@@ -217,7 +217,7 @@
 
   const cricket::JsepTransport* t = GetJsepTransportForMid(mid);
   if (!t) {
-    return absl::optional<rtc::SSLRole>();
+    return std::optional<rtc::SSLRole>();
   }
   return t->GetDtlsRole();
 }
diff --git a/pc/jsep_transport_controller.h b/pc/jsep_transport_controller.h
index c4275bd..d18a375 100644
--- a/pc/jsep_transport_controller.h
+++ b/pc/jsep_transport_controller.h
@@ -16,13 +16,13 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <utility>
 #include <vector>
 
 #include "absl/functional/any_invocable.h"
-#include "absl/types/optional.h"
 #include "api/async_dns_resolver.h"
 #include "api/candidate.h"
 #include "api/crypto/crypto_options.h"
@@ -233,7 +233,7 @@
   std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain(
       const std::string& mid) const;
   // Get negotiated role, if one has been negotiated.
-  absl::optional<rtc::SSLRole> GetDtlsRole(const std::string& mid) const;
+  std::optional<rtc::SSLRole> GetDtlsRole(const std::string& mid) const;
 
   // Suggest a payload type for a given codec on a given media section.
   // Media section is indicated by MID.
@@ -511,7 +511,7 @@
   const Config config_;
   bool active_reset_srtp_params_ RTC_GUARDED_BY(network_thread_);
 
-  absl::optional<bool> initial_offerer_;
+  std::optional<bool> initial_offerer_;
 
   cricket::IceConfig ice_config_;
   cricket::IceRole ice_role_ = cricket::ICEROLE_CONTROLLING;
diff --git a/pc/jsep_transport_controller_unittest.cc b/pc/jsep_transport_controller_unittest.cc
index 9e5d58b..0dcc3b2 100644
--- a/pc/jsep_transport_controller_unittest.cc
+++ b/pc/jsep_transport_controller_unittest.cc
@@ -644,7 +644,7 @@
           ->SetLocalDescription(SdpType::kOffer, offer_desc.get(), nullptr)
           .ok());
 
-  absl::optional<rtc::SSLRole> role =
+  std::optional<rtc::SSLRole> role =
       transport_controller_->GetDtlsRole(kAudioMid1);
   // The DTLS role is not decided yet.
   EXPECT_FALSE(role);
diff --git a/pc/jsep_transport_unittest.cc b/pc/jsep_transport_unittest.cc
index 074f8e5..d185b27 100644
--- a/pc/jsep_transport_unittest.cc
+++ b/pc/jsep_transport_unittest.cc
@@ -802,7 +802,7 @@
           .ok());
 
   // Sanity check that role was actually negotiated.
-  absl::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
+  std::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
   ASSERT_TRUE(role);
   EXPECT_EQ(rtc::SSL_CLIENT, *role);
 
@@ -847,7 +847,7 @@
           .ok());
 
   // Sanity check that role was actually negotiated.
-  absl::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
+  std::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
   ASSERT_TRUE(role);
   EXPECT_EQ(rtc::SSL_CLIENT, *role);
 
@@ -898,7 +898,7 @@
           .ok());
 
   // Sanity check that role was actually negotiated.
-  absl::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
+  std::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
   ASSERT_TRUE(role);
   EXPECT_EQ(rtc::SSL_CLIENT, *role);
 
@@ -947,7 +947,7 @@
           ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kAnswer)
           .ok());
 
-  absl::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
+  std::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
   ASSERT_TRUE(role);
   // Since legacy answer omitted setup atribute, and we offered actpass, we
   // should act as passive (server).
diff --git a/pc/legacy_stats_collector.cc b/pc/legacy_stats_collector.cc
index 800f63c..5665fb7 100644
--- a/pc/legacy_stats_collector.cc
+++ b/pc/legacy_stats_collector.cc
@@ -16,12 +16,12 @@
 #include <algorithm>
 #include <cmath>
 #include <list>
+#include <optional>
 #include <set>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/audio/audio_processing_statistics.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/candidate.h"
@@ -902,8 +902,8 @@
 LegacyStatsCollector::SessionStats LegacyStatsCollector::ExtractSessionInfo_n(
     const std::vector<rtc::scoped_refptr<
         RtpTransceiverProxyWithInternal<RtpTransceiver>>>& transceivers,
-    absl::optional<std::string> sctp_transport_name,
-    absl::optional<std::string> sctp_mid) {
+    std::optional<std::string> sctp_transport_name,
+    std::optional<std::string> sctp_mid) {
   TRACE_EVENT0("webrtc", "LegacyStatsCollector::ExtractSessionInfo_n");
   RTC_DCHECK_RUN_ON(pc_->network_thread());
   rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
diff --git a/pc/legacy_stats_collector.h b/pc/legacy_stats_collector.h
index e037163..8980bfd 100644
--- a/pc/legacy_stats_collector.h
+++ b/pc/legacy_stats_collector.h
@@ -20,12 +20,12 @@
 #include <cstdint>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/candidate.h"
 #include "api/field_trials_view.h"
 #include "api/legacy_stats_types.h"
@@ -194,8 +194,8 @@
   SessionStats ExtractSessionInfo_n(
       const std::vector<rtc::scoped_refptr<
           RtpTransceiverProxyWithInternal<RtpTransceiver>>>& transceivers,
-      absl::optional<std::string> sctp_transport_name,
-      absl::optional<std::string> sctp_mid);
+      std::optional<std::string> sctp_transport_name,
+      std::optional<std::string> sctp_mid);
   void ExtractSessionInfo_s(SessionStats& session_stats);
 
   // A collection for all of our stats reports.
diff --git a/pc/legacy_stats_collector_unittest.cc b/pc/legacy_stats_collector_unittest.cc
index f372dca..a792f7a 100644
--- a/pc/legacy_stats_collector_unittest.cc
+++ b/pc/legacy_stats_collector_unittest.cc
@@ -13,9 +13,9 @@
 #include <stdio.h>
 
 #include <cstdint>
+#include <optional>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/audio/audio_processing_statistics.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/candidate.h"
@@ -223,18 +223,18 @@
 // `n` starts from 1 for finding the first report.
 // If either the `n`-th report is not found, or the stat is not present in that
 // report, then nullopt is returned.
-absl::optional<std::string> GetValueInNthReportByType(
+std::optional<std::string> GetValueInNthReportByType(
     const StatsReports& reports,
     StatsReport::StatsType type,
     StatsReport::StatsValueName name,
     int n) {
   const StatsReport* report = FindNthReportByType(reports, type, n);
   if (!report) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   std::string value;
   if (!GetValue(report, name, &value)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return value;
 }
@@ -1889,7 +1889,7 @@
 
   // The SSRC in each SSRC report is different and correspond to the sender
   // SSRC.
-  std::vector<absl::optional<std::string>> ssrcs = {
+  std::vector<std::optional<std::string>> ssrcs = {
       GetValueInNthReportByType(reports, StatsReport::kStatsReportTypeSsrc,
                                 StatsReport::kStatsValueNameSsrc, 1),
       GetValueInNthReportByType(reports, StatsReport::kStatsReportTypeSsrc,
diff --git a/pc/local_audio_source_unittest.cc b/pc/local_audio_source_unittest.cc
index 76d3b36..72cc20b 100644
--- a/pc/local_audio_source_unittest.cc
+++ b/pc/local_audio_source_unittest.cc
@@ -10,7 +10,8 @@
 
 #include "pc/local_audio_source.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "test/gtest.h"
 
 using webrtc::LocalAudioSource;
@@ -26,5 +27,5 @@
 TEST(LocalAudioSourceTest, InitWithNoOptions) {
   rtc::scoped_refptr<LocalAudioSource> source =
       LocalAudioSource::Create(nullptr);
-  EXPECT_EQ(absl::nullopt, source->options().highpass_filter);
+  EXPECT_EQ(std::nullopt, source->options().highpass_filter);
 }
diff --git a/pc/media_session.cc b/pc/media_session.cc
index 9cd1e9b..9287155 100644
--- a/pc/media_session.cc
+++ b/pc/media_session.cc
@@ -15,6 +15,7 @@
 #include <algorithm>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <unordered_map>
 #include <utility>
@@ -23,7 +24,6 @@
 #include "absl/algorithm/container.h"
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/media_types.h"
 #include "api/rtc_error.h"
@@ -452,7 +452,7 @@
   negotiated_codec->packetization =
       (local_codec.packetization == remote_codec.packetization)
           ? local_codec.packetization
-          : absl::nullopt;
+          : std::nullopt;
 }
 
 #ifdef RTC_ENABLE_H265
@@ -461,16 +461,16 @@
                      Codec* negotiated_codec) {
   negotiated_codec->tx_mode = (local_codec.tx_mode == remote_codec.tx_mode)
                                   ? local_codec.tx_mode
-                                  : absl::nullopt;
+                                  : std::nullopt;
 }
 #endif
 
 // Finds a codec in `codecs2` that matches `codec_to_match`, which is
 // a member of `codecs1`. If `codec_to_match` is an RED or RTX codec, both
 // the codecs themselves and their associated codecs must match.
-absl::optional<Codec> FindMatchingCodec(const std::vector<Codec>& codecs1,
-                                        const std::vector<Codec>& codecs2,
-                                        const Codec& codec_to_match) {
+std::optional<Codec> FindMatchingCodec(const std::vector<Codec>& codecs1,
+                                       const std::vector<Codec>& codecs2,
+                                       const Codec& codec_to_match) {
   // `codec_to_match` should be a member of `codecs1`, in order to look up
   // RED/RTX codecs' associated codecs correctly. If not, that's a programming
   // error.
@@ -546,7 +546,7 @@
       return potential_match;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void NegotiateCodecs(const std::vector<Codec>& local_codecs,
@@ -554,7 +554,7 @@
                      std::vector<Codec>* negotiated_codecs,
                      bool keep_offer_order) {
   for (const Codec& ours : local_codecs) {
-    absl::optional<Codec> theirs =
+    std::optional<Codec> theirs =
         FindMatchingCodec(local_codecs, offered_codecs, ours);
     // Note that we intentionally only find one matching codec for each of our
     // local codecs, in case the remote offer contains duplicate codecs.
@@ -715,7 +715,7 @@
       }
       // Find a codec in the offered list that matches the reference codec.
       // Its payload type may be different than the reference codec.
-      absl::optional<Codec> matching_codec = FindMatchingCodec(
+      std::optional<Codec> matching_codec = FindMatchingCodec(
           reference_codecs, *offered_codecs, *associated_codec);
       if (!matching_codec) {
         RTC_LOG(LS_WARNING)
@@ -735,7 +735,7 @@
       const Codec* associated_codec =
           GetAssociatedCodecForRed(reference_codecs, red_codec);
       if (associated_codec) {
-        absl::optional<Codec> matching_codec = FindMatchingCodec(
+        std::optional<Codec> matching_codec = FindMatchingCodec(
             reference_codecs, *offered_codecs, *associated_codec);
         if (!matching_codec) {
           RTC_LOG(LS_WARNING) << "Couldn't find matching "
@@ -787,7 +787,7 @@
         });
 
     if (found_codec != supported_codecs.end()) {
-      absl::optional<Codec> found_codec_with_correct_pt =
+      std::optional<Codec> found_codec_with_correct_pt =
           FindMatchingCodec(supported_codecs, codecs, *found_codec);
       if (found_codec_with_correct_pt) {
         // RED may already have been added if its primary codec is before RED
@@ -1198,7 +1198,7 @@
     }
     // Add other supported codecs.
     for (const Codec& codec : supported_codecs) {
-      absl::optional<Codec> found_codec =
+      std::optional<Codec> found_codec =
           FindMatchingCodec(supported_codecs, codecs, codec);
       if (found_codec &&
           !FindMatchingCodec(supported_codecs, filtered_codecs, codec)) {
@@ -1214,7 +1214,7 @@
           RTC_DCHECK(referenced_codec);
 
           // Find the codec we should be referencing and point to it.
-          absl::optional<Codec> changed_referenced_codec = FindMatchingCodec(
+          std::optional<Codec> changed_referenced_codec = FindMatchingCodec(
               supported_codecs, filtered_codecs, *referenced_codec);
           if (changed_referenced_codec) {
             found_codec->SetParam(kCodecParamAssociatedPayloadType,
@@ -1617,7 +1617,7 @@
         IsMediaContentOfType(offer_content, media_description_options.type));
     RTC_DCHECK(media_description_options.mid == offer_content->name);
     // Get the index of the BUNDLE group that this MID belongs to, if any.
-    absl::optional<size_t> bundle_index;
+    std::optional<size_t> bundle_index;
     for (size_t i = 0; i < offer_bundles.size(); ++i) {
       if (offer_bundles[i]->HasContentName(media_description_options.mid)) {
         bundle_index = i;
diff --git a/pc/media_session_unittest.cc b/pc/media_session_unittest.cc
index c99526f..4ac9a5e 100644
--- a/pc/media_session_unittest.cc
+++ b/pc/media_session_unittest.cc
@@ -16,6 +16,7 @@
 #include <cstdint>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <vector>
@@ -23,7 +24,6 @@
 #include "absl/algorithm/container.h"
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/candidate.h"
 #include "api/rtp_parameters.h"
 #include "media/base/codec.h"
@@ -4142,7 +4142,7 @@
   ASSERT_EQ(1u, answer->contents().size());
   vcd1 = answer->contents()[0].media_description()->as_video();
   ASSERT_EQ(1u, vcd1->codecs().size());
-  EXPECT_EQ(vcd1->codecs()[0].tx_mode, absl::nullopt);
+  EXPECT_EQ(vcd1->codecs()[0].tx_mode, std::nullopt);
 }
 #endif
 
@@ -4215,7 +4215,7 @@
   ASSERT_EQ(1u, answer->contents().size());
   vcd1 = answer->contents()[0].media_description()->as_video();
   ASSERT_EQ(1u, vcd1->codecs().size());
-  EXPECT_EQ(vcd1->codecs()[0].packetization, absl::nullopt);
+  EXPECT_EQ(vcd1->codecs()[0].packetization, std::nullopt);
 }
 
 // Test that the codec preference order per media section is respected in
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index 083d49b..861ad3f 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -15,6 +15,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
@@ -22,7 +23,6 @@
 #include "absl/algorithm/container.h"
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/jsep_ice_candidate.h"
 #include "api/media_types.h"
@@ -175,11 +175,11 @@
   return kIceCandidatePairMax;
 }
 
-absl::optional<int> RTCConfigurationToIceConfigOptionalInt(
+std::optional<int> RTCConfigurationToIceConfigOptionalInt(
     int rtc_configuration_parameter) {
   if (rtc_configuration_parameter ==
       PeerConnectionInterface::RTCConfiguration::kUndefined) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return rtc_configuration_parameter;
 }
@@ -261,7 +261,7 @@
 // set, which is done via SetLocalDescription.
 RTCError ValidateIceCandidatePoolSize(
     int ice_candidate_pool_size,
-    absl::optional<int> previous_ice_candidate_pool_size) {
+    std::optional<int> previous_ice_candidate_pool_size) {
   // Note that this isn't possible through chromium, since it's an unsigned
   // short in WebIDL.
   if (ice_candidate_pool_size < 0 ||
@@ -407,7 +407,7 @@
     bool disable_ipv6_on_wifi;
     int max_ipv6_networks;
     bool disable_link_local_networks;
-    absl::optional<int> screencast_min_bitrate;
+    std::optional<int> screencast_min_bitrate;
     TcpCandidatePolicy tcp_candidate_policy;
     CandidateNetworkPolicy candidate_network_policy;
     int audio_jitter_buffer_max_packets;
@@ -424,27 +424,27 @@
     bool enable_ice_renomination;
     bool redetermine_role_on_ice_restart;
     bool surface_ice_candidates_on_ice_transport_type_changed;
-    absl::optional<int> ice_check_interval_strong_connectivity;
-    absl::optional<int> ice_check_interval_weak_connectivity;
-    absl::optional<int> ice_check_min_interval;
-    absl::optional<int> ice_unwritable_timeout;
-    absl::optional<int> ice_unwritable_min_checks;
-    absl::optional<int> ice_inactive_timeout;
-    absl::optional<int> stun_candidate_keepalive_interval;
+    std::optional<int> ice_check_interval_strong_connectivity;
+    std::optional<int> ice_check_interval_weak_connectivity;
+    std::optional<int> ice_check_min_interval;
+    std::optional<int> ice_unwritable_timeout;
+    std::optional<int> ice_unwritable_min_checks;
+    std::optional<int> ice_inactive_timeout;
+    std::optional<int> stun_candidate_keepalive_interval;
     TurnCustomizer* turn_customizer;
     SdpSemantics sdp_semantics;
-    absl::optional<rtc::AdapterType> network_preference;
+    std::optional<rtc::AdapterType> network_preference;
     bool active_reset_srtp_params;
-    absl::optional<CryptoOptions> crypto_options;
+    std::optional<CryptoOptions> crypto_options;
     bool offer_extmap_allow_mixed;
     std::string turn_logging_id;
     bool enable_implicit_rollback;
-    absl::optional<int> report_usage_pattern_delay_ms;
-    absl::optional<int> stable_writable_connection_ping_interval_ms;
+    std::optional<int> report_usage_pattern_delay_ms;
+    std::optional<int> stable_writable_connection_ping_interval_ms;
     VpnPreference vpn_preference;
     std::vector<rtc::NetworkMask> vpn_list;
     PortAllocatorConfig port_allocator_config;
-    absl::optional<TimeDelta> pacer_burst_interval;
+    std::optional<TimeDelta> pacer_burst_interval;
   };
   static_assert(sizeof(stuff_being_tested_for_equality) == sizeof(*this),
                 "Did you add something to RTCConfiguration and forget to "
@@ -1152,7 +1152,7 @@
   }
 
   auto result =
-      cricket::CheckRtpParametersValues(parameters, codecs, absl::nullopt);
+      cricket::CheckRtpParametersValues(parameters, codecs, std::nullopt);
   if (!result.ok()) {
     if (result.type() == RTCErrorType::INVALID_MODIFICATION) {
       result.set_type(RTCErrorType::UNSUPPORTED_OPERATION);
@@ -1411,18 +1411,18 @@
   return ice_gathering_state_;
 }
 
-absl::optional<bool> PeerConnection::can_trickle_ice_candidates() {
+std::optional<bool> PeerConnection::can_trickle_ice_candidates() {
   RTC_DCHECK_RUN_ON(signaling_thread());
   const SessionDescriptionInterface* description = current_remote_description();
   if (!description) {
     description = pending_remote_description();
   }
   if (!description) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   // TODO(bugs.webrtc.org/7443): Change to retrieve from session-level option.
   if (description->description()->transport_infos().size() < 1) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return description->description()->transport_infos()[0].description.HasOption(
       "trickle");
@@ -1542,8 +1542,8 @@
   RTCError validate_error = ValidateIceCandidatePoolSize(
       configuration.ice_candidate_pool_size,
       has_local_description
-          ? absl::optional<int>(configuration_.ice_candidate_pool_size)
-          : absl::nullopt);
+          ? std::optional<int>(configuration_.ice_candidate_pool_size)
+          : std::nullopt);
   if (!validate_error.ok()) {
     return validate_error;
   }
@@ -2079,7 +2079,7 @@
   RTC_DCHECK(!sctp_mid().has_value() || mid == sctp_mid().value());
   RTC_LOG(LS_INFO) << "Creating data channel, mid=" << mid;
 
-  absl::optional<std::string> transport_name =
+  std::optional<std::string> transport_name =
       network_thread()->BlockingCall([&] {
         RTC_DCHECK_RUN_ON(network_thread());
         return SetupDataChannelTransport_n(mid);
@@ -2180,7 +2180,7 @@
     int candidate_pool_size,
     PortPrunePolicy turn_port_prune_policy,
     TurnCustomizer* turn_customizer,
-    absl::optional<int> stun_candidate_keepalive_interval,
+    std::optional<int> stun_candidate_keepalive_interval,
     bool have_local_description) {
   RTC_DCHECK_RUN_ON(network_thread());
   port_allocator_->SetCandidateFilter(
@@ -2213,10 +2213,10 @@
   env_.event_log().StopLogging();
 }
 
-absl::optional<rtc::SSLRole> PeerConnection::GetSctpSslRole_n() {
+std::optional<rtc::SSLRole> PeerConnection::GetSctpSslRole_n() {
   RTC_DCHECK_RUN_ON(network_thread());
   return sctp_mid_n_ ? transport_controller_->GetDtlsRole(*sctp_mid_n_)
-                     : absl::nullopt;
+                     : std::nullopt;
 }
 
 bool PeerConnection::GetSslRole(const std::string& content_name,
@@ -2261,11 +2261,11 @@
   return data_channel_controller_.GetDataChannelStats();
 }
 
-absl::optional<std::string> PeerConnection::sctp_transport_name() const {
+std::optional<std::string> PeerConnection::sctp_transport_name() const {
   RTC_DCHECK_RUN_ON(signaling_thread());
   if (sctp_mid_s_ && transport_controller_copy_)
     return sctp_transport_name_s_;
-  return absl::optional<std::string>();
+  return std::optional<std::string>();
 }
 
 void PeerConnection::SetSctpTransportName(std::string sctp_transport_name) {
@@ -2274,7 +2274,7 @@
   ClearStatsCache();
 }
 
-absl::optional<std::string> PeerConnection::sctp_mid() const {
+std::optional<std::string> PeerConnection::sctp_mid() const {
   RTC_DCHECK_RUN_ON(signaling_thread());
   return sctp_mid_s_;
 }
@@ -2489,14 +2489,14 @@
   }
 }
 
-absl::optional<AudioDeviceModule::Stats> PeerConnection::GetAudioDeviceStats() {
+std::optional<AudioDeviceModule::Stats> PeerConnection::GetAudioDeviceStats() {
   if (context_->media_engine()) {
     return context_->media_engine()->voice().GetAudioDeviceStats();
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<std::string> PeerConnection::SetupDataChannelTransport_n(
+std::optional<std::string> PeerConnection::SetupDataChannelTransport_n(
     absl::string_view mid) {
   sctp_mid_n_ = std::string(mid);
   DataChannelTransportInterface* transport =
@@ -2505,11 +2505,11 @@
     RTC_LOG(LS_ERROR)
         << "Data channel transport is not available for data channels, mid="
         << mid;
-    sctp_mid_n_ = absl::nullopt;
-    return absl::nullopt;
+    sctp_mid_n_ = std::nullopt;
+    return std::nullopt;
   }
 
-  absl::optional<std::string> transport_name;
+  std::optional<std::string> transport_name;
   cricket::DtlsTransportInternal* dtls_transport =
       transport_controller_->GetDtlsTransport(*sctp_mid_n_);
   if (dtls_transport) {
diff --git a/pc/peer_connection.h b/pc/peer_connection.h
index dcf6eb6..16e43c7 100644
--- a/pc/peer_connection.h
+++ b/pc/peer_connection.h
@@ -16,11 +16,11 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/adaptation/resource.h"
 #include "api/async_dns_resolver.h"
 #include "api/candidate.h"
@@ -185,7 +185,7 @@
   IceConnectionState standardized_ice_connection_state() override;
   PeerConnectionState peer_connection_state() override;
   IceGatheringState ice_gathering_state() override;
-  absl::optional<bool> can_trickle_ice_candidates() override;
+  std::optional<bool> can_trickle_ice_candidates() override;
 
   const SessionDescriptionInterface* local_description() const override;
   const SessionDescriptionInterface* remote_description() const override;
@@ -286,15 +286,15 @@
 
   std::vector<DataChannelStats> GetDataChannelStats() const override;
 
-  absl::optional<std::string> sctp_transport_name() const override;
-  absl::optional<std::string> sctp_mid() const override;
+  std::optional<std::string> sctp_transport_name() const override;
+  std::optional<std::string> sctp_mid() const override;
 
   cricket::CandidateStatsList GetPooledCandidateStats() const override;
   std::map<std::string, cricket::TransportStats> GetTransportStatsByNames(
       const std::set<std::string>& transport_names) override;
   Call::Stats GetCallStats() override;
 
-  absl::optional<AudioDeviceModule::Stats> GetAudioDeviceStats() override;
+  std::optional<AudioDeviceModule::Stats> GetAudioDeviceStats() override;
 
   bool GetLocalCertificate(
       const std::string& transport_name,
@@ -315,7 +315,7 @@
            sdp_handler_->signaling_state() == PeerConnectionInterface::kClosed;
   }
   // Get current SSL role used by SCTP's underlying transport.
-  absl::optional<rtc::SSLRole> GetSctpSslRole_n() override;
+  std::optional<rtc::SSLRole> GetSctpSslRole_n() override;
 
   void OnSctpDataChannelStateChanged(
       int channel_id,
@@ -423,7 +423,7 @@
   // this session.
   bool SrtpRequired() const override;
 
-  absl::optional<std::string> SetupDataChannelTransport_n(absl::string_view mid)
+  std::optional<std::string> SetupDataChannelTransport_n(absl::string_view mid)
       RTC_RUN_ON(network_thread());
   void TeardownDataChannelTransport_n(RTCError error)
       RTC_RUN_ON(network_thread());
@@ -524,7 +524,7 @@
       int candidate_pool_size,
       PortPrunePolicy turn_port_prune_policy,
       TurnCustomizer* turn_customizer,
-      absl::optional<int> stun_candidate_keepalive_interval,
+      std::optional<int> stun_candidate_keepalive_interval,
       bool have_local_description);
 
   // Starts output of an RTC event log to the given output object.
@@ -680,8 +680,8 @@
   // There is one copy on the signaling thread and another copy on the
   // networking thread. Changes are always initiated from the signaling
   // thread, but applied first on the networking thread via an invoke().
-  absl::optional<std::string> sctp_mid_s_ RTC_GUARDED_BY(signaling_thread());
-  absl::optional<std::string> sctp_mid_n_ RTC_GUARDED_BY(network_thread());
+  std::optional<std::string> sctp_mid_s_ RTC_GUARDED_BY(signaling_thread());
+  std::optional<std::string> sctp_mid_n_ RTC_GUARDED_BY(network_thread());
   std::string sctp_transport_name_s_ RTC_GUARDED_BY(signaling_thread());
 
   // The machinery for handling offers and answers. Const after initialization.
diff --git a/pc/peer_connection_adaptation_integrationtest.cc b/pc/peer_connection_adaptation_integrationtest.cc
index 882fa36..93aa1eb 100644
--- a/pc/peer_connection_adaptation_integrationtest.cc
+++ b/pc/peer_connection_adaptation_integrationtest.cc
@@ -11,9 +11,9 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/adaptation/resource.h"
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
diff --git a/pc/peer_connection_crypto_unittest.cc b/pc/peer_connection_crypto_unittest.cc
index 9ba20ca..c808b0a 100644
--- a/pc/peer_connection_crypto_unittest.cc
+++ b/pc/peer_connection_crypto_unittest.cc
@@ -11,6 +11,7 @@
 #include <stddef.h>
 
 #include <memory>
+#include <optional>
 #include <ostream>
 #include <string>
 #include <tuple>
@@ -18,7 +19,6 @@
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/audio/audio_mixer.h"
 #include "api/audio/audio_processing.h"
diff --git a/pc/peer_connection_data_channel_unittest.cc b/pc/peer_connection_data_channel_unittest.cc
index 8682cfa..0368d82 100644
--- a/pc/peer_connection_data_channel_unittest.cc
+++ b/pc/peer_connection_data_channel_unittest.cc
@@ -9,12 +9,12 @@
  */
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/jsep.h"
 #include "api/media_types.h"
 #include "api/peer_connection_interface.h"
@@ -82,11 +82,11 @@
     sctp_transport_factory_ = sctp_transport_factory;
   }
 
-  absl::optional<std::string> sctp_mid() {
+  std::optional<std::string> sctp_mid() {
     return GetInternalPeerConnection()->sctp_mid();
   }
 
-  absl::optional<std::string> sctp_transport_name() {
+  std::optional<std::string> sctp_transport_name() {
     return GetInternalPeerConnection()->sctp_transport_name();
   }
 
diff --git a/pc/peer_connection_encodings_integrationtest.cc b/pc/peer_connection_encodings_integrationtest.cc
index fcbc9fc..9b4bfba 100644
--- a/pc/peer_connection_encodings_integrationtest.cc
+++ b/pc/peer_connection_encodings_integrationtest.cc
@@ -12,6 +12,7 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <string_view>
@@ -19,7 +20,6 @@
 
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
 #include "api/audio_options.h"
@@ -233,14 +233,14 @@
       size_t index,
       const std::string& codec_id) {
     return IsCodecIdDifferentWithScalabilityMode(pc_wrapper, index, codec_id,
-                                                 absl::nullopt);
+                                                 std::nullopt);
   }
 
   bool IsCodecIdDifferentWithScalabilityMode(
       rtc::scoped_refptr<PeerConnectionTestWrapper> pc_wrapper,
       size_t index,
       const std::string& codec_id,
-      absl::optional<std::string> wanted_scalability_mode) {
+      std::optional<std::string> wanted_scalability_mode) {
     rtc::scoped_refptr<const RTCStatsReport> report = GetStats(pc_wrapper);
     std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
         report->GetStatsOfType<RTCOutboundRtpStreamStats>();
@@ -513,7 +513,7 @@
   // `scalability_mode` remains unset because SetParameters() failed.
   parameters = sender->GetParameters();
   ASSERT_EQ(parameters.encodings.size(), 1u);
-  EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(absl::nullopt));
+  EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(std::nullopt));
 
   local_pc_wrapper->WaitForConnection();
   remote_pc_wrapper->WaitForConnection();
@@ -532,7 +532,7 @@
   // GetParameters() confirms `scalability_mode` is still not set.
   parameters = sender->GetParameters();
   ASSERT_EQ(parameters.encodings.size(), 1u);
-  EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(absl::nullopt));
+  EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(std::nullopt));
 }
 
 TEST_F(PeerConnectionEncodingsIntegrationTest,
@@ -626,7 +626,7 @@
   local_pc_wrapper->WaitForConnection();
   remote_pc_wrapper->WaitForConnection();
   // `scalaiblity_mode` is assigned the fallback value "L1T2" which is different
-  // than the default of absl::nullopt.
+  // than the default of std::nullopt.
   parameters = sender->GetParameters();
   ASSERT_EQ(parameters.encodings.size(), 1u);
   EXPECT_THAT(parameters.encodings[0].scalability_mode,
@@ -838,9 +838,9 @@
   parameters.encodings[0].scalability_mode = "L2T2_KEY";
   parameters.encodings[0].scale_resolution_down_by = 2.0;
   parameters.encodings[1].active = false;
-  parameters.encodings[1].scalability_mode = absl::nullopt;
+  parameters.encodings[1].scalability_mode = std::nullopt;
   parameters.encodings[2].active = false;
-  parameters.encodings[2].scalability_mode = absl::nullopt;
+  parameters.encodings[2].scalability_mode = std::nullopt;
   sender->SetParameters(parameters);
 
   // Since the standard API is configuring simulcast we get three outbound-rtps,
@@ -890,7 +890,7 @@
   parameters.encodings[1].scalability_mode = "L1T1";
   parameters.encodings[1].scale_resolution_down_by = 2.0;
   parameters.encodings[2].active = false;
-  parameters.encodings[2].scalability_mode = absl::nullopt;
+  parameters.encodings[2].scalability_mode = std::nullopt;
   EXPECT_TRUE(sender->SetParameters(parameters).ok());
 
   // The original negotiation triggers legacy SVC because we didn't specify
@@ -920,7 +920,7 @@
               Optional(StrEq("L1T3")));
   EXPECT_THAT(parameters.encodings[1].scalability_mode,
               Optional(StrEq("L1T1")));
-  EXPECT_THAT(parameters.encodings[2].scalability_mode, Eq(absl::nullopt));
+  EXPECT_THAT(parameters.encodings[2].scalability_mode, Eq(std::nullopt));
 }
 
 TEST_F(PeerConnectionEncodingsIntegrationTest,
@@ -976,7 +976,7 @@
   // GetParameters() does not report any fallback.
   parameters = sender->GetParameters();
   ASSERT_THAT(parameters.encodings, SizeIs(3));
-  EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(absl::nullopt));
+  EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(std::nullopt));
   EXPECT_THAT(parameters.encodings[1].scalability_mode,
               Optional(StrEq("L1T1")));
   EXPECT_THAT(parameters.encodings[2].scalability_mode,
@@ -984,14 +984,14 @@
 
   // Switch to legacy SVC mode.
   parameters.encodings[0].active = true;
-  parameters.encodings[0].scalability_mode = absl::nullopt;
-  parameters.encodings[0].scale_resolution_down_by = absl::nullopt;
+  parameters.encodings[0].scalability_mode = std::nullopt;
+  parameters.encodings[0].scale_resolution_down_by = std::nullopt;
   parameters.encodings[1].active = true;
-  parameters.encodings[1].scalability_mode = absl::nullopt;
-  parameters.encodings[1].scale_resolution_down_by = absl::nullopt;
+  parameters.encodings[1].scalability_mode = std::nullopt;
+  parameters.encodings[1].scale_resolution_down_by = std::nullopt;
   parameters.encodings[2].active = false;
-  parameters.encodings[2].scalability_mode = absl::nullopt;
-  parameters.encodings[2].scale_resolution_down_by = absl::nullopt;
+  parameters.encodings[2].scalability_mode = std::nullopt;
+  parameters.encodings[2].scale_resolution_down_by = std::nullopt;
 
   EXPECT_TRUE(sender->SetParameters(parameters).ok());
   // Ensure that we are getting VGA at L1T3 from the "f" rid.
@@ -1284,7 +1284,7 @@
           /*audio=*/true, {}, /*video=*/false, {});
   rtc::scoped_refptr<AudioTrackInterface> track = stream->GetAudioTracks()[0];
 
-  absl::optional<RtpCodecCapability> pcmu =
+  std::optional<RtpCodecCapability> pcmu =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_AUDIO,
                                                    "pcmu");
   ASSERT_TRUE(pcmu);
@@ -1325,7 +1325,7 @@
           /*audio=*/false, {}, /*video=*/true, {.width = 1280, .height = 720});
   rtc::scoped_refptr<VideoTrackInterface> track = stream->GetVideoTracks()[0];
 
-  absl::optional<RtpCodecCapability> vp9 =
+  std::optional<RtpCodecCapability> vp9 =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_VIDEO,
                                                    "vp9");
   ASSERT_TRUE(vp9);
@@ -1372,7 +1372,7 @@
           /*audio=*/true, {}, /*video=*/false, {});
   rtc::scoped_refptr<AudioTrackInterface> track = stream->GetAudioTracks()[0];
 
-  absl::optional<RtpCodecCapability> pcmu =
+  std::optional<RtpCodecCapability> pcmu =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_AUDIO,
                                                    "pcmu");
 
@@ -1409,7 +1409,7 @@
           /*audio=*/true, {}, /*video=*/false, {});
   rtc::scoped_refptr<AudioTrackInterface> track = stream->GetAudioTracks()[0];
 
-  absl::optional<RtpCodecCapability> pcmu =
+  std::optional<RtpCodecCapability> pcmu =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_AUDIO,
                                                    "pcmu");
 
@@ -1457,7 +1457,7 @@
           /*audio=*/false, {}, /*video=*/true, {.width = 1280, .height = 720});
   rtc::scoped_refptr<VideoTrackInterface> track = stream->GetVideoTracks()[0];
 
-  absl::optional<RtpCodecCapability> vp9 =
+  std::optional<RtpCodecCapability> vp9 =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_VIDEO,
                                                    "vp9");
 
@@ -1500,7 +1500,7 @@
           /*audio=*/false, {}, /*video=*/true, {.width = 1280, .height = 720});
   rtc::scoped_refptr<VideoTrackInterface> track = stream->GetVideoTracks()[0];
 
-  absl::optional<RtpCodecCapability> vp9 =
+  std::optional<RtpCodecCapability> vp9 =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_VIDEO,
                                                    "vp9");
 
@@ -1635,7 +1635,7 @@
   rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
   ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);
 
-  absl::optional<RtpCodecCapability> opus =
+  std::optional<RtpCodecCapability> opus =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_AUDIO,
                                                    "opus");
   ASSERT_TRUE(opus);
@@ -1674,7 +1674,7 @@
   rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
   ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);
 
-  absl::optional<RtpCodecCapability> opus =
+  std::optional<RtpCodecCapability> opus =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_AUDIO,
                                                    "opus");
   ASSERT_TRUE(opus);
@@ -1736,7 +1736,7 @@
   rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
   ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);
 
-  absl::optional<RtpCodecCapability> vp8 =
+  std::optional<RtpCodecCapability> vp8 =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_VIDEO,
                                                    "vp8");
   ASSERT_TRUE(vp8);
@@ -1775,7 +1775,7 @@
   rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
   ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);
 
-  absl::optional<RtpCodecCapability> vp8 =
+  std::optional<RtpCodecCapability> vp8 =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_VIDEO,
                                                    "vp8");
   ASSERT_TRUE(vp8);
@@ -1837,7 +1837,7 @@
   rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
   ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);
 
-  absl::optional<RtpCodecCapability> opus =
+  std::optional<RtpCodecCapability> opus =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_AUDIO,
                                                    "opus");
   ASSERT_TRUE(opus);
@@ -1890,12 +1890,12 @@
           ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_AUDIO)
           .codecs;
 
-  absl::optional<RtpCodecCapability> opus =
+  std::optional<RtpCodecCapability> opus =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_AUDIO,
                                                    "opus");
   ASSERT_TRUE(opus);
 
-  absl::optional<RtpCodecCapability> red =
+  std::optional<RtpCodecCapability> red =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_AUDIO,
                                                    "red");
   ASSERT_TRUE(red);
@@ -1943,7 +1943,7 @@
        SetParametersRejectsScalabilityModeForSelectedCodec) {
   rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
 
-  absl::optional<RtpCodecCapability> vp8 =
+  std::optional<RtpCodecCapability> vp8 =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_VIDEO,
                                                    "vp8");
   ASSERT_TRUE(vp8);
@@ -1973,7 +1973,7 @@
   rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
   ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);
 
-  absl::optional<RtpCodecCapability> vp8 =
+  std::optional<RtpCodecCapability> vp8 =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_VIDEO,
                                                    "vp8");
   ASSERT_TRUE(vp8);
@@ -2031,11 +2031,11 @@
   rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
   ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);
 
-  absl::optional<RtpCodecCapability> vp8 =
+  std::optional<RtpCodecCapability> vp8 =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_VIDEO,
                                                    "vp8");
   ASSERT_TRUE(vp8);
-  absl::optional<RtpCodecCapability> vp9 =
+  std::optional<RtpCodecCapability> vp9 =
       local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_VIDEO,
                                                    "vp9");
 
diff --git a/pc/peer_connection_end_to_end_unittest.cc b/pc/peer_connection_end_to_end_unittest.cc
index 1fc3d7e..cc57c7b 100644
--- a/pc/peer_connection_end_to_end_unittest.cc
+++ b/pc/peer_connection_end_to_end_unittest.cc
@@ -13,13 +13,13 @@
 #include <cstddef>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/L16/audio_decoder_L16.h"
 #include "api/audio_codecs/L16/audio_encoder_L16.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
@@ -305,7 +305,7 @@
           [real_decoder_factory](
               const webrtc::Environment& env,
               const webrtc::SdpAudioFormat& format,
-              absl::optional<webrtc::AudioCodecPairId> codec_pair_id) {
+              std::optional<webrtc::AudioCodecPairId> codec_pair_id) {
             auto real_decoder =
                 real_decoder_factory->Create(env, format, codec_pair_id);
             return real_decoder
@@ -317,7 +317,7 @@
 
 struct AudioEncoderUnicornSparklesRainbow {
   using Config = webrtc::AudioEncoderL16::Config;
-  static absl::optional<Config> SdpToConfig(webrtc::SdpAudioFormat format) {
+  static std::optional<Config> SdpToConfig(webrtc::SdpAudioFormat format) {
     if (absl::EqualsIgnoreCase(format.name, "UnicornSparklesRainbow")) {
       const webrtc::CodecParameterMap expected_params = {{"num_horns", "1"}};
       EXPECT_EQ(expected_params, format.parameters);
@@ -325,7 +325,7 @@
       format.name = "L16";
       return webrtc::AudioEncoderL16::SdpToConfig(format);
     } else {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
   static void AppendSupportedEncoders(
@@ -345,7 +345,7 @@
   static std::unique_ptr<webrtc::AudioEncoder> MakeAudioEncoder(
       const Config& config,
       int payload_type,
-      absl::optional<webrtc::AudioCodecPairId> codec_pair_id = absl::nullopt) {
+      std::optional<webrtc::AudioCodecPairId> codec_pair_id = std::nullopt) {
     return webrtc::AudioEncoderL16::MakeAudioEncoder(config, payload_type,
                                                      codec_pair_id);
   }
@@ -353,7 +353,7 @@
 
 struct AudioDecoderUnicornSparklesRainbow {
   using Config = webrtc::AudioDecoderL16::Config;
-  static absl::optional<Config> SdpToConfig(webrtc::SdpAudioFormat format) {
+  static std::optional<Config> SdpToConfig(webrtc::SdpAudioFormat format) {
     if (absl::EqualsIgnoreCase(format.name, "UnicornSparklesRainbow")) {
       const webrtc::CodecParameterMap expected_params = {{"num_horns", "1"}};
       EXPECT_EQ(expected_params, format.parameters);
@@ -361,7 +361,7 @@
       format.name = "L16";
       return webrtc::AudioDecoderL16::SdpToConfig(format);
     } else {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
   static void AppendSupportedDecoders(
@@ -377,7 +377,7 @@
   }
   static std::unique_ptr<webrtc::AudioDecoder> MakeAudioDecoder(
       const Config& config,
-      absl::optional<webrtc::AudioCodecPairId> codec_pair_id = absl::nullopt) {
+      std::optional<webrtc::AudioCodecPairId> codec_pair_id = std::nullopt) {
     return webrtc::AudioDecoderL16::MakeAudioDecoder(config, codec_pair_id);
   }
 };
@@ -415,7 +415,7 @@
     std::vector<webrtc::AudioCodecSpec> GetSupportedEncoders() override {
       return fact_->GetSupportedEncoders();
     }
-    absl::optional<webrtc::AudioCodecInfo> QueryAudioEncoder(
+    std::optional<webrtc::AudioCodecInfo> QueryAudioEncoder(
         const webrtc::SdpAudioFormat& format) override {
       return fact_->QueryAudioEncoder(format);
     }
@@ -448,7 +448,7 @@
     std::unique_ptr<webrtc::AudioDecoder> Create(
         const Environment& env,
         const webrtc::SdpAudioFormat& format,
-        absl::optional<webrtc::AudioCodecPairId> codec_pair_id) override {
+        std::optional<webrtc::AudioCodecPairId> codec_pair_id) override {
       EXPECT_TRUE(codec_pair_id.has_value());
       codec_ids_->push_back(*codec_pair_id);
       return fact_->Create(env, format, codec_pair_id);
diff --git a/pc/peer_connection_header_extension_unittest.cc b/pc/peer_connection_header_extension_unittest.cc
index 15b1ae6..61805a7 100644
--- a/pc/peer_connection_header_extension_unittest.cc
+++ b/pc/peer_connection_header_extension_unittest.cc
@@ -9,13 +9,13 @@
  */
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/jsep.h"
 #include "api/media_types.h"
 #include "api/peer_connection_interface.h"
@@ -76,7 +76,7 @@
 
   std::unique_ptr<PeerConnectionWrapper> CreatePeerConnection(
       cricket::MediaType media_type,
-      absl::optional<SdpSemantics> semantics) {
+      std::optional<SdpSemantics> semantics) {
     auto media_engine = std::make_unique<cricket::FakeMediaEngine>();
     if (media_type == cricket::MediaType::MEDIA_TYPE_AUDIO)
       media_engine->fake_voice_engine()->SetRtpHeaderExtensions(extensions_);
diff --git a/pc/peer_connection_histogram_unittest.cc b/pc/peer_connection_histogram_unittest.cc
index 365f58a..0697c67 100644
--- a/pc/peer_connection_histogram_unittest.cc
+++ b/pc/peer_connection_histogram_unittest.cc
@@ -9,12 +9,12 @@
  */
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/jsep.h"
 #include "api/jsep_session_description.h"
 #include "api/peer_connection_interface.h"
@@ -104,18 +104,18 @@
 
   bool HaveDataChannel() { return last_datachannel_ != nullptr; }
 
-  absl::optional<int> interesting_usage_detected() {
+  std::optional<int> interesting_usage_detected() {
     return interesting_usage_detected_;
   }
 
   void ClearInterestingUsageDetector() {
-    interesting_usage_detected_ = absl::optional<int>();
+    interesting_usage_detected_ = std::optional<int>();
   }
 
   bool candidate_gathered() const { return candidate_gathered_; }
 
  private:
-  absl::optional<int> interesting_usage_detected_;
+  std::optional<int> interesting_usage_detected_;
   bool candidate_gathered_ = false;
   RawWrapperPtr candidate_target_;  // Note: Not thread-safe against deletions.
 };
@@ -728,7 +728,7 @@
       (expected_fingerprint |
        static_cast<int>(UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
           ObservedFingerprint());
-  EXPECT_METRIC_EQ(absl::make_optional(ObservedFingerprint()),
+  EXPECT_METRIC_EQ(std::make_optional(ObservedFingerprint()),
                    caller->observer()->interesting_usage_detected());
 }
 
@@ -748,7 +748,7 @@
       (expected_fingerprint |
        static_cast<int>(UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
           ObservedFingerprint());
-  EXPECT_METRIC_EQ(absl::make_optional(ObservedFingerprint()),
+  EXPECT_METRIC_EQ(std::make_optional(ObservedFingerprint()),
                    caller->observer()->interesting_usage_detected());
 }
 
diff --git a/pc/peer_connection_ice_unittest.cc b/pc/peer_connection_ice_unittest.cc
index 59541e5..ecf7da6 100644
--- a/pc/peer_connection_ice_unittest.cc
+++ b/pc/peer_connection_ice_unittest.cc
@@ -12,13 +12,13 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <type_traits>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/audio/audio_mixer.h"
 #include "api/audio/audio_processing.h"
@@ -1473,7 +1473,7 @@
   config.ice_candidate_pool_size = 1;
   CreatePeerConnection(config);
   ASSERT_NE(port_allocator_, nullptr);
-  absl::optional<int> actual_stun_keepalive_interval =
+  std::optional<int> actual_stun_keepalive_interval =
       port_allocator_->stun_candidate_keepalive_interval();
   EXPECT_EQ(actual_stun_keepalive_interval.value_or(-1), 123);
   config.stun_candidate_keepalive_interval = 321;
diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc
index 7bf6b6d..774e08b 100644
--- a/pc/peer_connection_integrationtest.cc
+++ b/pc/peer_connection_integrationtest.cc
@@ -19,6 +19,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <utility>
@@ -27,7 +28,6 @@
 #include "absl/algorithm/container.h"
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/candidate.h"
 #include "api/crypto/crypto_options.h"
 #include "api/dtmf_sender_interface.h"
@@ -2353,7 +2353,7 @@
   ASSERT_EQ(first_candidate_stats.size(), 0u);
 
   // Add a "fake" candidate.
-  absl::optional<RTCError> result;
+  std::optional<RTCError> result;
   caller()->pc()->AddIceCandidate(
       absl::WrapUnique(CreateIceCandidate(
           "", 0,
diff --git a/pc/peer_connection_interface_unittest.cc b/pc/peer_connection_interface_unittest.cc
index 8c17a4a..539b952 100644
--- a/pc/peer_connection_interface_unittest.cc
+++ b/pc/peer_connection_interface_unittest.cc
@@ -13,12 +13,12 @@
 #include <limits.h>
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/str_replace.h"
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/audio/audio_mixer.h"
 #include "api/audio/audio_processing.h"
@@ -1955,7 +1955,7 @@
   EXPECT_FALSE(channel.value()->reliable());
   EXPECT_FALSE(observer_.renegotiation_needed_);
 
-  config.maxRetransmits = absl::nullopt;
+  config.maxRetransmits = std::nullopt;
   config.maxRetransmitTime = 0;
   channel = pc_->CreateDataChannelOrError("4", &config);
   EXPECT_TRUE(channel.ok());
@@ -2223,7 +2223,7 @@
 // require a very complex set of mocks.
 TEST_P(PeerConnectionInterfaceTest, SetConfigurationChangesIceCheckInterval) {
   PeerConnectionInterface::RTCConfiguration config;
-  config.ice_check_min_interval = absl::nullopt;
+  config.ice_check_min_interval = std::nullopt;
   CreatePeerConnection(config);
   config = pc_->GetConfiguration();
   config.ice_check_min_interval = 100;
diff --git a/pc/peer_connection_internal.h b/pc/peer_connection_internal.h
index 75e18f2..f3c4707 100644
--- a/pc/peer_connection_internal.h
+++ b/pc/peer_connection_internal.h
@@ -13,11 +13,11 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/peer_connection_interface.h"
 #include "call/call.h"
@@ -47,7 +47,7 @@
   // bundling, returns false.
   virtual bool NeedsIceRestart(const std::string& content_name) const = 0;
 
-  virtual absl::optional<std::string> sctp_mid() const = 0;
+  virtual std::optional<std::string> sctp_mid() const = 0;
 
   // Functions below this comment are known to only be accessed
   // from SdpOfferAnswerHandler.
@@ -76,7 +76,7 @@
   virtual LegacyStatsCollector* legacy_stats() = 0;
   // Returns the observer. Will crash on CHECK if the observer is removed.
   virtual PeerConnectionObserver* Observer() const = 0;
-  virtual absl::optional<rtc::SSLRole> GetSctpSslRole_n() = 0;
+  virtual std::optional<rtc::SSLRole> GetSctpSslRole_n() = 0;
   virtual PeerConnectionInterface::IceConnectionState
   ice_connection_state_internal() = 0;
   virtual void SetIceConnectionState(
@@ -153,7 +153,7 @@
     return {};
   }
 
-  virtual absl::optional<std::string> sctp_transport_name() const = 0;
+  virtual std::optional<std::string> sctp_transport_name() const = 0;
 
   virtual cricket::CandidateStatsList GetPooledCandidateStats() const = 0;
 
@@ -165,7 +165,7 @@
 
   virtual Call::Stats GetCallStats() = 0;
 
-  virtual absl::optional<AudioDeviceModule::Stats> GetAudioDeviceStats() = 0;
+  virtual std::optional<AudioDeviceModule::Stats> GetAudioDeviceStats() = 0;
 
   virtual bool GetLocalCertificate(
       const std::string& transport_name,
diff --git a/pc/peer_connection_jsep_unittest.cc b/pc/peer_connection_jsep_unittest.cc
index fa033ae..cd1689a 100644
--- a/pc/peer_connection_jsep_unittest.cc
+++ b/pc/peer_connection_jsep_unittest.cc
@@ -13,13 +13,13 @@
 #include <algorithm>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/enable_media_with_defaults.h"
 #include "api/field_trials_view.h"
@@ -331,7 +331,7 @@
 
   auto transceivers = callee->pc()->GetTransceivers();
   ASSERT_EQ(2u, transceivers.size());
-  EXPECT_EQ(absl::nullopt, transceivers[0]->mid());
+  EXPECT_EQ(std::nullopt, transceivers[0]->mid());
   EXPECT_EQ(caller_audio->mid(), transceivers[1]->mid());
 }
 
@@ -349,7 +349,7 @@
 
   auto transceivers = callee->pc()->GetTransceivers();
   ASSERT_EQ(2u, transceivers.size());
-  EXPECT_EQ(absl::nullopt, transceivers[0]->mid());
+  EXPECT_EQ(std::nullopt, transceivers[0]->mid());
   EXPECT_EQ(caller->pc()->GetTransceivers()[0]->mid(), transceivers[1]->mid());
   EXPECT_EQ(MediaStreamTrackInterface::kAudioKind,
             transceivers[1]->receiver()->track()->kind());
@@ -368,7 +368,7 @@
 
   auto transceivers = callee->pc()->GetTransceivers();
   ASSERT_EQ(2u, transceivers.size());
-  EXPECT_EQ(absl::nullopt, transceivers[0]->mid());
+  EXPECT_EQ(std::nullopt, transceivers[0]->mid());
   EXPECT_EQ(caller->pc()->GetTransceivers()[0]->mid(), transceivers[1]->mid());
   EXPECT_EQ(MediaStreamTrackInterface::kAudioKind,
             transceivers[1]->receiver()->track()->kind());
@@ -676,7 +676,7 @@
       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
   EXPECT_TRUE(first_transceiver->stopped());
   // First transceivers are dissociated on caller side.
-  ASSERT_EQ(absl::nullopt, first_transceiver->mid());
+  ASSERT_EQ(std::nullopt, first_transceiver->mid());
   // They are disassociated on callee side.
   ASSERT_EQ(0u, callee->pc()->GetTransceivers().size());
 
@@ -695,7 +695,7 @@
   // associate the new transceivers.
   ASSERT_TRUE(
       caller->SetLocalDescription(CloneSessionDescription(offer.get())));
-  EXPECT_EQ(absl::nullopt, first_transceiver->mid());
+  EXPECT_EQ(std::nullopt, first_transceiver->mid());
   ASSERT_EQ(1u, caller->pc()->GetTransceivers().size());
   EXPECT_EQ(second_mid, caller->pc()->GetTransceivers()[0]->mid());
   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
@@ -814,7 +814,7 @@
   // the MID for the new transceiver.
   ASSERT_TRUE(
       caller->SetLocalDescription(CloneSessionDescription(offer.get())));
-  EXPECT_EQ(absl::nullopt, first_transceiver->mid());
+  EXPECT_EQ(std::nullopt, first_transceiver->mid());
   EXPECT_EQ(second_mid, second_transceiver->mid());
 
   // Setting the remote offer will dissociate the previous transceiver and
@@ -877,7 +877,7 @@
   // the MID for the new transceiver.
   ASSERT_TRUE(
       caller->SetLocalDescription(CloneSessionDescription(offer.get())));
-  EXPECT_EQ(absl::nullopt, caller_first_transceiver->mid());
+  EXPECT_EQ(std::nullopt, caller_first_transceiver->mid());
   EXPECT_EQ(second_mid, caller_second_transceiver->mid());
 
   // Setting the remote offer will dissociate the previous transceiver and
@@ -940,7 +940,7 @@
   // the MID for the new transceiver.
   ASSERT_TRUE(
       callee->SetLocalDescription(CloneSessionDescription(offer.get())));
-  EXPECT_EQ(absl::nullopt, callee_first_transceiver->mid());
+  EXPECT_EQ(std::nullopt, callee_first_transceiver->mid());
   EXPECT_EQ(second_mid, callee_second_transceiver->mid());
 
   // Setting the remote offer will dissociate the previous transceiver and
@@ -1945,7 +1945,7 @@
   // Transceiver can't be removed as track was added to it.
   EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
   // Mid got cleared to make it reusable.
-  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), absl::nullopt);
+  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), std::nullopt);
   // Transceiver should be counted as addTrack-created after rollback.
   EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
   EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
@@ -1973,7 +1973,7 @@
   // Transceiver can't be removed as track was added to it.
   EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
   // Mid got cleared to make it reusable.
-  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), absl::nullopt);
+  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), std::nullopt);
   // Transceiver should be counted as addTrack-created after rollback.
   EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
   EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
@@ -1988,9 +1988,9 @@
   auto offer = callee->CreateOffer();
   EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
   EXPECT_EQ(callee->pc()->GetTransceivers().size(), 1u);
-  EXPECT_NE(callee->pc()->GetTransceivers()[0]->mid(), absl::nullopt);
+  EXPECT_NE(callee->pc()->GetTransceivers()[0]->mid(), std::nullopt);
   EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateRollback()));
-  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), absl::nullopt);
+  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), std::nullopt);
   EXPECT_TRUE(callee->SetLocalDescription(std::move(offer)));
 }
 
@@ -2113,7 +2113,7 @@
   auto initial_mid = callee->pc()->GetTransceivers()[0]->mid();
   EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
   EXPECT_EQ(callee->pc()->GetTransceivers().size(), 2u);
-  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), absl::nullopt);
+  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), std::nullopt);
   EXPECT_EQ(callee->pc()->GetTransceivers()[1]->mid(),
             caller->pc()->GetTransceivers()[0]->mid());
   EXPECT_TRUE(callee->CreateAnswerAndSetAsLocal());  // Go to stable.
@@ -2293,8 +2293,8 @@
   EXPECT_TRUE(callee->observer()->legacy_renegotiation_needed());
   EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());
   EXPECT_EQ(callee->pc()->GetTransceivers().size(), 2u);
-  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), absl::nullopt);
-  EXPECT_EQ(callee->pc()->GetTransceivers()[1]->mid(), absl::nullopt);
+  EXPECT_EQ(callee->pc()->GetTransceivers()[0]->mid(), std::nullopt);
+  EXPECT_EQ(callee->pc()->GetTransceivers()[1]->mid(), std::nullopt);
 }
 
 TEST_F(PeerConnectionJsepTest, NoRollbackNeeded) {
diff --git a/pc/peer_connection_media_unittest.cc b/pc/peer_connection_media_unittest.cc
index 7009624..d9093f4 100644
--- a/pc/peer_connection_media_unittest.cc
+++ b/pc/peer_connection_media_unittest.cc
@@ -17,6 +17,7 @@
 #include <iterator>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <tuple>
@@ -25,7 +26,6 @@
 #include <vector>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/audio_options.h"
 #include "api/jsep.h"
 #include "api/media_types.h"
@@ -614,7 +614,7 @@
   auto* offer_description =
       cricket::GetFirstVideoContentDescription(offer->description());
   for (const auto& codec : offer_description->codecs()) {
-    EXPECT_EQ(codec.packetization, absl::nullopt);
+    EXPECT_EQ(codec.packetization, std::nullopt);
   }
 }
 
@@ -691,7 +691,7 @@
   auto* answer_description =
       cricket::GetFirstVideoContentDescription(answer->description());
   for (const auto& codec : answer_description->codecs()) {
-    EXPECT_EQ(codec.packetization, absl::nullopt);
+    EXPECT_EQ(codec.packetization, std::nullopt);
   }
 
   ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
diff --git a/pc/peer_connection_proxy.h b/pc/peer_connection_proxy.h
index 898f24d..b97a62e 100644
--- a/pc/peer_connection_proxy.h
+++ b/pc/peer_connection_proxy.h
@@ -157,7 +157,7 @@
 PROXY_METHOD0(IceConnectionState, standardized_ice_connection_state)
 PROXY_METHOD0(PeerConnectionState, peer_connection_state)
 PROXY_METHOD0(IceGatheringState, ice_gathering_state)
-PROXY_METHOD0(absl::optional<bool>, can_trickle_ice_candidates)
+PROXY_METHOD0(std::optional<bool>, can_trickle_ice_candidates)
 PROXY_METHOD1(void, AddAdaptationResource, rtc::scoped_refptr<Resource>)
 PROXY_METHOD2(bool,
               StartRtcEventLog,
diff --git a/pc/peer_connection_rampup_tests.cc b/pc/peer_connection_rampup_tests.cc
index e51e5aa..4bea516 100644
--- a/pc/peer_connection_rampup_tests.cc
+++ b/pc/peer_connection_rampup_tests.cc
@@ -9,11 +9,11 @@
  */
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/audio/audio_mixer.h"
 #include "api/audio/audio_processing.h"
diff --git a/pc/peer_connection_rtp_unittest.cc b/pc/peer_connection_rtp_unittest.cc
index bde8e18..ec9f215 100644
--- a/pc/peer_connection_rtp_unittest.cc
+++ b/pc/peer_connection_rtp_unittest.cc
@@ -12,11 +12,11 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/audio/audio_mixer.h"
 #include "api/audio/audio_processing.h"
@@ -959,10 +959,10 @@
   auto caller = CreatePeerConnection();
 
   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
-  EXPECT_EQ(absl::nullopt, transceiver->mid());
+  EXPECT_EQ(std::nullopt, transceiver->mid());
   EXPECT_FALSE(transceiver->stopped());
   EXPECT_EQ(RtpTransceiverDirection::kSendRecv, transceiver->direction());
-  EXPECT_EQ(absl::nullopt, transceiver->current_direction());
+  EXPECT_EQ(std::nullopt, transceiver->current_direction());
 }
 
 // Test that adding a transceiver with the audio kind creates an audio sender
diff --git a/pc/peer_connection_signaling_unittest.cc b/pc/peer_connection_signaling_unittest.cc
index b6ad190..2b85a72 100644
--- a/pc/peer_connection_signaling_unittest.cc
+++ b/pc/peer_connection_signaling_unittest.cc
@@ -16,6 +16,7 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <tuple>
@@ -23,7 +24,6 @@
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/audio/audio_mixer.h"
 #include "api/audio/audio_processing.h"
diff --git a/pc/peer_connection_wrapper.cc b/pc/peer_connection_wrapper.cc
index 557d0c8..b4842c1 100644
--- a/pc/peer_connection_wrapper.cc
+++ b/pc/peer_connection_wrapper.cc
@@ -12,10 +12,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/function_view.h"
 #include "api/set_remote_description_observer_interface.h"
 #include "pc/sdp_utils.h"
@@ -314,7 +314,7 @@
 rtc::scoped_refptr<DataChannelInterface>
 PeerConnectionWrapper::CreateDataChannel(
     const std::string& label,
-    const absl::optional<DataChannelInit>& config) {
+    const std::optional<DataChannelInit>& config) {
   const DataChannelInit* config_ptr = config.has_value() ? &(*config) : nullptr;
   auto result = pc()->CreateDataChannelOrError(label, config_ptr);
   if (!result.ok()) {
diff --git a/pc/peer_connection_wrapper.h b/pc/peer_connection_wrapper.h
index bf40bbc..de8dc47 100644
--- a/pc/peer_connection_wrapper.h
+++ b/pc/peer_connection_wrapper.h
@@ -12,10 +12,10 @@
 #define PC_PEER_CONNECTION_WRAPPER_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/data_channel_interface.h"
 #include "api/function_view.h"
 #include "api/jsep.h"
@@ -171,7 +171,7 @@
   // initialization parameters.
   rtc::scoped_refptr<DataChannelInterface> CreateDataChannel(
       const std::string& label,
-      const absl::optional<DataChannelInit>& config = absl::nullopt);
+      const std::optional<DataChannelInit>& config = std::nullopt);
 
   // Returns the signaling state of the underlying PeerConnection.
   PeerConnectionInterface::SignalingState signaling_state();
diff --git a/pc/remote_audio_source.cc b/pc/remote_audio_source.cc
index a516c57..87095c1 100644
--- a/pc/remote_audio_source.cc
+++ b/pc/remote_audio_source.cc
@@ -72,7 +72,7 @@
 
 void RemoteAudioSource::Start(
     cricket::VoiceMediaReceiveChannelInterface* media_channel,
-    absl::optional<uint32_t> ssrc) {
+    std::optional<uint32_t> ssrc) {
   RTC_DCHECK_RUN_ON(worker_thread_);
 
   // Register for callbacks immediately before AddSink so that we always get
@@ -87,7 +87,7 @@
 
 void RemoteAudioSource::Stop(
     cricket::VoiceMediaReceiveChannelInterface* media_channel,
-    absl::optional<uint32_t> ssrc) {
+    std::optional<uint32_t> ssrc) {
   RTC_DCHECK_RUN_ON(worker_thread_);
   RTC_DCHECK(media_channel);
   ssrc ? media_channel->SetRawAudioSink(*ssrc, nullptr)
@@ -159,7 +159,7 @@
     // absolute capture timestamp.
     sink->OnData(audio.data, 16, audio.sample_rate, audio.channels,
                  audio.samples_per_channel,
-                 /*absolute_capture_timestamp_ms=*/absl::nullopt);
+                 /*absolute_capture_timestamp_ms=*/std::nullopt);
   }
 }
 
diff --git a/pc/remote_audio_source.h b/pc/remote_audio_source.h
index 0fac606..ac4d222 100644
--- a/pc/remote_audio_source.h
+++ b/pc/remote_audio_source.h
@@ -14,9 +14,9 @@
 #include <stdint.h>
 
 #include <list>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/call/audio_sink.h"
 #include "api/media_stream_interface.h"
 #include "api/notifier.h"
@@ -50,9 +50,9 @@
   // Register and unregister remote audio source with the underlying media
   // engine.
   void Start(cricket::VoiceMediaReceiveChannelInterface* media_channel,
-             absl::optional<uint32_t> ssrc);
+             std::optional<uint32_t> ssrc);
   void Stop(cricket::VoiceMediaReceiveChannelInterface* media_channel,
-            absl::optional<uint32_t> ssrc);
+            std::optional<uint32_t> ssrc);
   void SetState(SourceState new_state);
 
   // MediaSourceInterface implementation.
diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc
index 3f6088a..cd9beb2 100644
--- a/pc/rtc_stats_collector.cc
+++ b/pc/rtc_stats_collector.cc
@@ -1053,7 +1053,7 @@
     // Filter mode: RTCStatsCollector::RequestInfo::kReceiverSelector
     if (receiver_selector) {
       // Find the inbound-rtp of the receiver using ssrc lookup.
-      absl::optional<uint32_t> ssrc;
+      std::optional<uint32_t> ssrc;
       worker_thread_->BlockingCall([&] { ssrc = receiver_selector->ssrc(); });
       if (ssrc.has_value()) {
         for (const auto* inbound_rtp :
@@ -1250,7 +1250,7 @@
 
 void RTCStatsCollector::ProducePartialResultsOnNetworkThread(
     Timestamp timestamp,
-    absl::optional<std::string> sctp_transport_name) {
+    std::optional<std::string> sctp_transport_name) {
   TRACE_EVENT0("webrtc",
                "RTCStatsCollector::ProducePartialResultsOnNetworkThread");
   RTC_DCHECK_RUN_ON(network_thread_);
@@ -2136,8 +2136,8 @@
     bool has_audio_receiver = false;
     for (auto& stats : transceiver_stats_infos_) {
       auto transceiver = stats.transceiver;
-      absl::optional<cricket::VoiceMediaInfo> voice_media_info;
-      absl::optional<cricket::VideoMediaInfo> video_media_info;
+      std::optional<cricket::VoiceMediaInfo> voice_media_info;
+      std::optional<cricket::VideoMediaInfo> video_media_info;
       auto channel = transceiver->channel();
       if (channel) {
         cricket::MediaType media_type = transceiver->media_type();
@@ -2175,7 +2175,7 @@
 
     call_stats_ = pc_->GetCallStats();
     audio_device_stats_ =
-        has_audio_receiver ? pc_->GetAudioDeviceStats() : absl::nullopt;
+        has_audio_receiver ? pc_->GetAudioDeviceStats() : std::nullopt;
   });
 
   for (auto& stats : transceiver_stats_infos_) {
diff --git a/pc/rtc_stats_collector.h b/pc/rtc_stats_collector.h
index 1dc84b0..1beef4c 100644
--- a/pc/rtc_stats_collector.h
+++ b/pc/rtc_stats_collector.h
@@ -16,10 +16,10 @@
 #include <cstdint>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/data_channel_interface.h"
 #include "api/media_types.h"
@@ -170,10 +170,10 @@
   struct RtpTransceiverStatsInfo {
     rtc::scoped_refptr<RtpTransceiver> transceiver;
     cricket::MediaType media_type;
-    absl::optional<std::string> mid;
-    absl::optional<std::string> transport_name;
+    std::optional<std::string> mid;
+    std::optional<std::string> transport_name;
     TrackMediaInfoMap track_media_info_map;
-    absl::optional<RtpTransceiverDirection> current_direction;
+    std::optional<RtpTransceiverDirection> current_direction;
   };
 
   void DeliverCachedReport(
@@ -240,7 +240,7 @@
   void ProducePartialResultsOnSignalingThread(Timestamp timestamp);
   void ProducePartialResultsOnNetworkThread(
       Timestamp timestamp,
-      absl::optional<std::string> sctp_transport_name);
+      std::optional<std::string> sctp_transport_name);
   // Merges `network_report_` into `partial_report_` and completes the request.
   // This is a NO-OP if `network_report_` is null.
   void MergeNetworkReport_s();
@@ -293,7 +293,7 @@
 
   Call::Stats call_stats_;
 
-  absl::optional<AudioDeviceModule::Stats> audio_device_stats_;
+  std::optional<AudioDeviceModule::Stats> audio_device_stats_;
 
   // A timestamp, in microseconds, that is based on a timer that is
   // monotonically increasing. That is, even if the system clock is modified the
diff --git a/pc/rtc_stats_collector_unittest.cc b/pc/rtc_stats_collector_unittest.cc
index d43ccb4..b0fec81 100644
--- a/pc/rtc_stats_collector_unittest.cc
+++ b/pc/rtc_stats_collector_unittest.cc
@@ -16,6 +16,7 @@
 #include <algorithm>
 #include <initializer_list>
 #include <memory>
+#include <optional>
 #include <ostream>
 #include <string>
 #include <type_traits>
@@ -23,7 +24,6 @@
 #include <vector>
 
 #include "absl/strings/str_replace.h"
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/audio/audio_processing_statistics.h"
 #include "api/candidate.h"
@@ -289,7 +289,7 @@
 
   // VideoTrackSourceInterface
   bool is_screencast() const override { return false; }
-  absl::optional<bool> needs_denoising() const override { return false; }
+  std::optional<bool> needs_denoising() const override { return false; }
   bool GetStats(VideoTrackSourceInterface::Stats* stats) override {
     stats->input_width = input_width_;
     stats->input_height = input_height_;
@@ -1932,7 +1932,7 @@
   connection_info.sent_total_bytes = 42;
   connection_info.recv_total_bytes = 1234;
   connection_info.total_round_trip_time_ms = 0;
-  connection_info.current_round_trip_time_ms = absl::nullopt;
+  connection_info.current_round_trip_time_ms = std::nullopt;
   connection_info.recv_ping_requests = 2020;
   connection_info.sent_ping_requests_total = 2222;
   connection_info.sent_ping_requests_before_first_response = 2000;
@@ -2200,7 +2200,7 @@
   voice_media_info.receivers[0].relative_packet_arrival_delay_seconds = 16;
   voice_media_info.receivers[0].interruption_count = 7788;
   voice_media_info.receivers[0].total_interruption_duration_ms = 778899;
-  voice_media_info.receivers[0].last_packet_received = absl::nullopt;
+  voice_media_info.receivers[0].last_packet_received = std::nullopt;
   voice_media_info.receivers[0].total_processing_delay_seconds = 0.123;
 
   RtpCodecParameters codec_parameters;
@@ -2342,7 +2342,7 @@
   video_media_info.receivers[0].frames_decoded = 9;
   video_media_info.receivers[0].key_frames_decoded = 3;
   video_media_info.receivers[0].frames_dropped = 13;
-  video_media_info.receivers[0].qp_sum = absl::nullopt;
+  video_media_info.receivers[0].qp_sum = std::nullopt;
   video_media_info.receivers[0].total_decode_time = TimeDelta::Seconds(9);
   video_media_info.receivers[0].total_processing_delay = TimeDelta::Millis(600);
   video_media_info.receivers[0].total_assembly_time = TimeDelta::Millis(500);
@@ -2358,11 +2358,11 @@
   video_media_info.receivers[0].jitter_buffer_target_delay_seconds = 1.1;
   video_media_info.receivers[0].jitter_buffer_minimum_delay_seconds = 0.999;
   video_media_info.receivers[0].jitter_buffer_emitted_count = 13;
-  video_media_info.receivers[0].last_packet_received = absl::nullopt;
+  video_media_info.receivers[0].last_packet_received = std::nullopt;
   video_media_info.receivers[0].content_type = VideoContentType::UNSPECIFIED;
   video_media_info.receivers[0].estimated_playout_ntp_timestamp_ms =
-      absl::nullopt;
-  video_media_info.receivers[0].decoder_implementation_name = absl::nullopt;
+      std::nullopt;
+  video_media_info.receivers[0].decoder_implementation_name = std::nullopt;
   video_media_info.receivers[0].min_playout_delay_ms = 50;
   video_media_info.receivers[0].power_efficient_decoder = false;
   video_media_info.receivers[0].retransmitted_packets_received = 17;
@@ -2629,9 +2629,9 @@
       .quality_limitation_durations_ms[QualityLimitationReason::kBandwidth] =
       300;
   video_media_info.senders[0].quality_limitation_resolution_changes = 56u;
-  video_media_info.senders[0].qp_sum = absl::nullopt;
+  video_media_info.senders[0].qp_sum = std::nullopt;
   video_media_info.senders[0].content_type = VideoContentType::UNSPECIFIED;
-  video_media_info.senders[0].encoder_implementation_name = absl::nullopt;
+  video_media_info.senders[0].encoder_implementation_name = std::nullopt;
   video_media_info.senders[0].power_efficient_encoder = false;
   video_media_info.senders[0].send_frame_width = 200;
   video_media_info.senders[0].send_frame_height = 100;
@@ -3242,7 +3242,7 @@
   void AddSenderInfoAndMediaChannel(
       std::string transport_name,
       const std::vector<ReportBlockData>& report_block_datas,
-      absl::optional<RtpCodecParameters> codec) {
+      std::optional<RtpCodecParameters> codec) {
     switch (media_type_) {
       case cricket::MEDIA_TYPE_AUDIO: {
         cricket::VoiceMediaInfo voice_media_info;
@@ -3319,7 +3319,7 @@
     report_block_datas.push_back(report_block_data);
   }
   AddSenderInfoAndMediaChannel("TransportName", report_block_datas,
-                               absl::nullopt);
+                               std::nullopt);
 
   rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
   for (auto ssrc : ssrcs) {
@@ -3370,7 +3370,7 @@
   report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc);
 
   AddSenderInfoAndMediaChannel("TransportName", {report_block_data},
-                               absl::nullopt);
+                               std::nullopt);
 
   rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
 
@@ -3397,7 +3397,7 @@
   report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc);
 
   AddSenderInfoAndMediaChannel("TransportName", {report_block_data},
-                               absl::nullopt);
+                               std::nullopt);
 
   // Advance time, it should be OK to have fresher reports than report blocks.
   fake_clock_.AdvanceTime(TimeDelta::Micros(1234));
@@ -3474,7 +3474,7 @@
   pc_->SetTransportStats("TransportName", {rtp_transport_channel_stats,
                                            rtcp_transport_channel_stats});
   AddSenderInfoAndMediaChannel("TransportName", {report_block_data},
-                               absl::nullopt);
+                               std::nullopt);
 
   rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
 
@@ -3732,7 +3732,7 @@
   RTCTestStats(const std::string& id, Timestamp timestamp)
       : RTCStats(id, timestamp) {}
 
-  absl::optional<int32_t> dummy_stat;
+  std::optional<int32_t> dummy_stat;
 };
 
 WEBRTC_RTCSTATS_IMPL(RTCTestStats,
diff --git a/pc/rtc_stats_integrationtest.cc b/pc/rtc_stats_integrationtest.cc
index f8b0899..779f06b 100644
--- a/pc/rtc_stats_integrationtest.cc
+++ b/pc/rtc_stats_integrationtest.cc
@@ -12,13 +12,13 @@
 #include <string.h>
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
 #include "api/audio_options.h"
@@ -160,14 +160,14 @@
   }
 
   template <typename T>
-  void MarkAttributeTested(const absl::optional<T>& field,
+  void MarkAttributeTested(const std::optional<T>& field,
                            bool test_successful) {
     untested_attribute_names_.erase(stats_->GetAttribute(field).name());
     all_tests_successful_ &= test_successful;
   }
 
   template <typename T>
-  void TestAttributeIsDefined(const absl::optional<T>& field) {
+  void TestAttributeIsDefined(const std::optional<T>& field) {
     EXPECT_TRUE(field.has_value())
         << stats_->type() << "." << stats_->GetAttribute(field).name() << "["
         << stats_->id() << "] was undefined.";
@@ -175,7 +175,7 @@
   }
 
   template <typename T>
-  void TestAttributeIsUndefined(const absl::optional<T>& field) {
+  void TestAttributeIsUndefined(const std::optional<T>& field) {
     Attribute attribute = stats_->GetAttribute(field);
     EXPECT_FALSE(field.has_value())
         << stats_->type() << "." << attribute.name() << "[" << stats_->id()
@@ -184,7 +184,7 @@
   }
 
   template <typename T>
-  void TestAttributeIsPositive(const absl::optional<T>& field) {
+  void TestAttributeIsPositive(const std::optional<T>& field) {
     Attribute attribute = stats_->GetAttribute(field);
     EXPECT_TRUE(field.has_value()) << stats_->type() << "." << attribute.name()
                                    << "[" << stats_->id() << "] was undefined.";
@@ -200,7 +200,7 @@
   }
 
   template <typename T>
-  void TestAttributeIsNonNegative(const absl::optional<T>& field) {
+  void TestAttributeIsNonNegative(const std::optional<T>& field) {
     Attribute attribute = stats_->GetAttribute(field);
     EXPECT_TRUE(field.has_value()) << stats_->type() << "." << attribute.name()
                                    << "[" << stats_->id() << "] was undefined.";
@@ -216,13 +216,13 @@
   }
 
   template <typename T>
-  void TestAttributeIsIDReference(const absl::optional<T>& field,
+  void TestAttributeIsIDReference(const std::optional<T>& field,
                                   const char* expected_type) {
     TestAttributeIsIDReference(field, expected_type, false);
   }
 
   template <typename T>
-  void TestAttributeIsOptionalIDReference(const absl::optional<T>& field,
+  void TestAttributeIsOptionalIDReference(const std::optional<T>& field,
                                           const char* expected_type) {
     TestAttributeIsIDReference(field, expected_type, true);
   }
@@ -239,7 +239,7 @@
 
  private:
   template <typename T>
-  void TestAttributeIsIDReference(const absl::optional<T>& field,
+  void TestAttributeIsIDReference(const std::optional<T>& field,
                                   const char* expected_type,
                                   bool optional) {
     if (optional && !field.has_value()) {
diff --git a/pc/rtc_stats_traversal.cc b/pc/rtc_stats_traversal.cc
index e9d11b5..aeaf244 100644
--- a/pc/rtc_stats_traversal.cc
+++ b/pc/rtc_stats_traversal.cc
@@ -11,11 +11,11 @@
 #include "pc/rtc_stats_traversal.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/stats/rtcstats_objects.h"
 #include "rtc_base/checks.h"
 
@@ -43,7 +43,7 @@
   }
 }
 
-void AddIdIfDefined(const absl::optional<std::string>& id,
+void AddIdIfDefined(const std::optional<std::string>& id,
                     std::vector<const std::string*>* neighbor_ids) {
   if (id.has_value())
     neighbor_ids->push_back(&(*id));
diff --git a/pc/rtp_parameters_conversion.cc b/pc/rtp_parameters_conversion.cc
index 2463cef..1c0c3ee 100644
--- a/pc/rtp_parameters_conversion.cc
+++ b/pc/rtp_parameters_conversion.cc
@@ -196,7 +196,7 @@
   return std::move(cricket_streams);
 }
 
-absl::optional<RtcpFeedback> ToRtcpFeedback(
+std::optional<RtcpFeedback> ToRtcpFeedback(
     const cricket::FeedbackParam& cricket_feedback) {
   if (cricket_feedback.id() == cricket::kRtcpFbParamCcm) {
     if (cricket_feedback.param() == cricket::kRtcpFbCcmParamFir) {
@@ -204,7 +204,7 @@
     } else {
       RTC_LOG(LS_WARNING) << "Unsupported parameter for CCM RTCP feedback: "
                           << cricket_feedback.param();
-      return absl::nullopt;
+      return std::nullopt;
     }
   } else if (cricket_feedback.id() == cricket::kRtcpFbParamLntf) {
     if (cricket_feedback.param().empty()) {
@@ -212,7 +212,7 @@
     } else {
       RTC_LOG(LS_WARNING) << "Unsupported parameter for LNTF RTCP feedback: "
                           << cricket_feedback.param();
-      return absl::nullopt;
+      return std::nullopt;
     }
   } else if (cricket_feedback.id() == cricket::kRtcpFbParamNack) {
     if (cricket_feedback.param().empty()) {
@@ -223,13 +223,13 @@
     } else {
       RTC_LOG(LS_WARNING) << "Unsupported parameter for NACK RTCP feedback: "
                           << cricket_feedback.param();
-      return absl::nullopt;
+      return std::nullopt;
     }
   } else if (cricket_feedback.id() == cricket::kRtcpFbParamRemb) {
     if (!cricket_feedback.param().empty()) {
       RTC_LOG(LS_WARNING) << "Unsupported parameter for REMB RTCP feedback: "
                           << cricket_feedback.param();
-      return absl::nullopt;
+      return std::nullopt;
     } else {
       return RtcpFeedback(RtcpFeedbackType::REMB);
     }
@@ -238,14 +238,14 @@
       RTC_LOG(LS_WARNING)
           << "Unsupported parameter for transport-cc RTCP feedback: "
           << cricket_feedback.param();
-      return absl::nullopt;
+      return std::nullopt;
     } else {
       return RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC);
     }
   }
   RTC_LOG(LS_WARNING) << "Unsupported RTCP feedback type: "
                       << cricket_feedback.id();
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 std::vector<RtpEncodingParameters> ToRtpEncodings(
@@ -269,7 +269,7 @@
   codec.preferred_payload_type.emplace(cricket_codec.id);
   for (const cricket::FeedbackParam& cricket_feedback :
        cricket_codec.feedback_params.params()) {
-    absl::optional<RtcpFeedback> feedback = ToRtcpFeedback(cricket_feedback);
+    std::optional<RtcpFeedback> feedback = ToRtcpFeedback(cricket_feedback);
     if (feedback) {
       codec.rtcp_feedback.push_back(feedback.value());
     }
@@ -297,7 +297,7 @@
   codec_param.payload_type = cricket_codec.id;
   for (const cricket::FeedbackParam& cricket_feedback :
        cricket_codec.feedback_params.params()) {
-    absl::optional<RtcpFeedback> feedback = ToRtcpFeedback(cricket_feedback);
+    std::optional<RtcpFeedback> feedback = ToRtcpFeedback(cricket_feedback);
     if (feedback) {
       codec_param.rtcp_feedback.push_back(feedback.value());
     }
diff --git a/pc/rtp_parameters_conversion.h b/pc/rtp_parameters_conversion.h
index 2cc39dd..eab77f4 100644
--- a/pc/rtp_parameters_conversion.h
+++ b/pc/rtp_parameters_conversion.h
@@ -11,9 +11,9 @@
 #ifndef PC_RTP_PARAMETERS_CONVERSION_H_
 #define PC_RTP_PARAMETERS_CONVERSION_H_
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/rtc_error.h"
 #include "api/rtp_parameters.h"
 #include "media/base/codec.h"
@@ -74,7 +74,7 @@
 
 // Returns empty value if `cricket_feedback` is a feedback type not
 // supported/recognized.
-absl::optional<RtcpFeedback> ToRtcpFeedback(
+std::optional<RtcpFeedback> ToRtcpFeedback(
     const cricket::FeedbackParam& cricket_feedback);
 
 std::vector<RtpEncodingParameters> ToRtpEncodings(
diff --git a/pc/rtp_parameters_conversion_unittest.cc b/pc/rtp_parameters_conversion_unittest.cc
index 0c68b0a..5bf5419 100644
--- a/pc/rtp_parameters_conversion_unittest.cc
+++ b/pc/rtp_parameters_conversion_unittest.cc
@@ -344,7 +344,7 @@
 }
 
 TEST(RtpParametersConversionTest, ToRtcpFeedback) {
-  absl::optional<RtcpFeedback> result = ToRtcpFeedback({"ccm", "fir"});
+  std::optional<RtcpFeedback> result = ToRtcpFeedback({"ccm", "fir"});
   EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::CCM, RtcpFeedbackMessageType::FIR),
             *result);
 
@@ -369,7 +369,7 @@
 
 TEST(RtpParametersConversionTest, ToRtcpFeedbackErrors) {
   // CCM with missing or invalid message type.
-  absl::optional<RtcpFeedback> result = ToRtcpFeedback({"ccm", "pli"});
+  std::optional<RtcpFeedback> result = ToRtcpFeedback({"ccm", "pli"});
   EXPECT_FALSE(result);
 
   result = ToRtcpFeedback(cricket::FeedbackParam("ccm"));
diff --git a/pc/rtp_receiver.h b/pc/rtp_receiver.h
index 53451a3..14e102f 100644
--- a/pc/rtp_receiver.h
+++ b/pc/rtp_receiver.h
@@ -17,10 +17,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/dtls_transport_interface.h"
 #include "api/media_stream_interface.h"
 #include "api/rtp_receiver_interface.h"
@@ -59,7 +59,7 @@
       rtc::scoped_refptr<DtlsTransportInterface> dtls_transport) = 0;
   // This SSRC is used as an identifier for the receiver between the API layer
   // and the WebRtcVideoEngine, WebRtcVoiceEngine layer.
-  virtual absl::optional<uint32_t> ssrc() const = 0;
+  virtual std::optional<uint32_t> ssrc() const = 0;
 
   // Call this to notify the RtpReceiver when the first packet has been received
   // on the corresponding channel.
diff --git a/pc/rtp_receiver_proxy.h b/pc/rtp_receiver_proxy.h
index 0cdf6ff..feb569b 100644
--- a/pc/rtp_receiver_proxy.h
+++ b/pc/rtp_receiver_proxy.h
@@ -11,10 +11,10 @@
 #ifndef PC_RTP_RECEIVER_PROXY_H_
 #define PC_RTP_RECEIVER_PROXY_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/crypto/frame_decryptor_interface.h"
 #include "api/dtls_transport_interface.h"
 #include "api/frame_transformer_interface.h"
@@ -44,7 +44,7 @@
 PROXY_METHOD1(void, SetObserver, RtpReceiverObserverInterface*)
 PROXY_SECONDARY_METHOD1(void,
                         SetJitterBufferMinimumDelay,
-                        absl::optional<double>)
+                        std::optional<double>)
 PROXY_SECONDARY_CONSTMETHOD0(std::vector<RtpSource>, GetSources)
 // TODO(bugs.webrtc.org/12772): Remove.
 PROXY_SECONDARY_METHOD1(void,
diff --git a/pc/rtp_sender.cc b/pc/rtp_sender.cc
index 6e28734..cc74716 100644
--- a/pc/rtp_sender.cc
+++ b/pc/rtp_sender.cc
@@ -248,7 +248,7 @@
   }
   if (!media_channel_ || !ssrc_) {
     auto result = cricket::CheckRtpParametersInvalidModificationAndValues(
-        init_parameters_, parameters, send_codecs_, absl::nullopt);
+        init_parameters_, parameters, send_codecs_, std::nullopt);
     if (result.ok()) {
       init_parameters_ = parameters;
     }
@@ -299,7 +299,7 @@
   }
   if (!media_channel_ || !ssrc_) {
     auto result = cricket::CheckRtpParametersInvalidModificationAndValues(
-        init_parameters_, parameters, send_codecs_, absl::nullopt);
+        init_parameters_, parameters, send_codecs_, std::nullopt);
     if (result.ok()) {
       init_parameters_ = parameters;
     }
@@ -339,11 +339,11 @@
 }
 
 RTCError RtpSenderBase::CheckCodecParameters(const RtpParameters& parameters) {
-  absl::optional<cricket::Codec> send_codec = media_channel_->GetSendCodec();
+  std::optional<cricket::Codec> send_codec = media_channel_->GetSendCodec();
 
   // Match the currently used codec against the codec preferences to gather
   // the SVC capabilities.
-  absl::optional<cricket::Codec> send_codec_with_svc_info;
+  std::optional<cricket::Codec> send_codec_with_svc_info;
   if (send_codec && send_codec->type == cricket::Codec::Type::kVideo) {
     auto codec_match = absl::c_find_if(
         send_codecs_, [&](auto& codec) { return send_codec->Matches(codec); });
@@ -498,7 +498,7 @@
           init_parameters_.degradation_preference;
       media_channel_->SetRtpSendParameters(ssrc_, current_parameters, nullptr);
       init_parameters_.encodings.clear();
-      init_parameters_.degradation_preference = absl::nullopt;
+      init_parameters_.degradation_preference = std::nullopt;
     });
   }
   // Attempt to attach the frame decryptor to the current media channel.
@@ -606,7 +606,7 @@
     int sample_rate,
     size_t number_of_channels,
     size_t number_of_frames,
-    absl::optional<int64_t> absolute_capture_timestamp_ms) {
+    std::optional<int64_t> absolute_capture_timestamp_ms) {
   TRACE_EVENT2("webrtc", "LocalAudioSinkAdapter::OnData", "sample_rate",
                sample_rate, "number_of_frames", number_of_frames);
   MutexLock lock(&lock_);
diff --git a/pc/rtp_sender.h b/pc/rtp_sender.h
index bd2cf9d..ec8f923 100644
--- a/pc/rtp_sender.h
+++ b/pc/rtp_sender.h
@@ -19,10 +19,10 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/crypto/frame_encryptor_interface.h"
 #include "api/dtls_transport_interface.h"
 #include "api/dtmf_sender_interface.h"
@@ -276,7 +276,7 @@
   // As such, it is used for internal verification and is not observable by the
   // the client. It is marked as mutable to enable `GetParameters` to be a
   // const method.
-  mutable absl::optional<std::string> last_transaction_id_;
+  mutable std::optional<std::string> last_transaction_id_;
   std::vector<std::string> disabled_rids_;
 
   SetStreamsObserver* set_streams_observer_ = nullptr;
@@ -303,7 +303,7 @@
               int sample_rate,
               size_t number_of_channels,
               size_t number_of_frames,
-              absl::optional<int64_t> absolute_capture_timestamp_ms) override;
+              std::optional<int64_t> absolute_capture_timestamp_ms) override;
 
   // AudioSinkInterface implementation.
   void OnData(const void* audio_data,
@@ -313,7 +313,7 @@
               size_t number_of_frames) override {
     OnData(audio_data, bits_per_sample, sample_rate, number_of_channels,
            number_of_frames,
-           /*absolute_capture_timestamp_ms=*/absl::nullopt);
+           /*absolute_capture_timestamp_ms=*/std::nullopt);
   }
 
   // AudioSinkInterface implementation.
diff --git a/pc/rtp_sender_receiver_unittest.cc b/pc/rtp_sender_receiver_unittest.cc
index b73edf5..99a113a 100644
--- a/pc/rtp_sender_receiver_unittest.cc
+++ b/pc/rtp_sender_receiver_unittest.cc
@@ -13,12 +13,12 @@
 #include <cstdint>
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_options.h"
 #include "api/crypto/crypto_options.h"
@@ -491,7 +491,7 @@
       RtpReceiverInterface* receiver,
       uint32_t ssrc) {
     receiver->SetJitterBufferMinimumDelay(/*delay_seconds=*/0.5);
-    absl::optional<int> delay_ms =
+    std::optional<int> delay_ms =
         media_channel->GetBaseMinimumPlayoutDelayMs(ssrc);  // In milliseconds.
     EXPECT_DOUBLE_EQ(0.5, delay_ms.value_or(0) / 1000.0);
   }
@@ -888,7 +888,7 @@
 
   RtpParameters params = audio_rtp_sender_->GetParameters();
   EXPECT_EQ(1u, params.encodings.size());
-  absl::optional<RTCError> result;
+  std::optional<RTCError> result;
   audio_rtp_sender_->SetParametersAsync(
       params, [&result](RTCError error) { result = error; });
   run_loop_.Flush();
@@ -918,7 +918,7 @@
   audio_rtp_sender_ =
       AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr);
 
-  absl::optional<RTCError> result;
+  std::optional<RTCError> result;
   RtpParameters params = audio_rtp_sender_->GetParameters();
   ASSERT_EQ(1u, params.encodings.size());
   params.encodings[0].max_bitrate_bps = 90000;
@@ -1016,7 +1016,7 @@
 
   RtpParameters params = audio_rtp_sender_->GetParameters();
   EXPECT_EQ(1u, params.encodings.size());
-  absl::optional<RTCError> result;
+  std::optional<RTCError> result;
   audio_rtp_sender_->SetParametersAsync(
       params, [&result](RTCError error) { result = error; });
   run_loop_.Flush();
@@ -1139,7 +1139,7 @@
 
   RtpParameters params = video_rtp_sender_->GetParameters();
   EXPECT_EQ(1u, params.encodings.size());
-  absl::optional<RTCError> result;
+  std::optional<RTCError> result;
   video_rtp_sender_->SetParametersAsync(
       params, [&result](RTCError error) { result = error; });
   run_loop_.Flush();
@@ -1169,7 +1169,7 @@
   video_rtp_sender_ =
       VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr);
 
-  absl::optional<RTCError> result;
+  std::optional<RTCError> result;
   RtpParameters params = video_rtp_sender_->GetParameters();
   ASSERT_EQ(1u, params.encodings.size());
   params.encodings[0].max_bitrate_bps = 90000;
@@ -1349,7 +1349,7 @@
 
   RtpParameters params = video_rtp_sender_->GetParameters();
   EXPECT_EQ(1u, params.encodings.size());
-  absl::optional<RTCError> result;
+  std::optional<RTCError> result;
   video_rtp_sender_->SetParametersAsync(
       params, [&result](RTCError error) { result = error; });
   run_loop_.Flush();
@@ -1723,7 +1723,7 @@
   video_track_->set_enabled(true);
 
   // Sender is not ready to send (no SSRC) so no option should have been set.
-  EXPECT_EQ(absl::nullopt, video_media_send_channel()->options().is_screencast);
+  EXPECT_EQ(std::nullopt, video_media_send_channel()->options().is_screencast);
 
   // Verify that the content hint is accounted for when video_rtp_sender_ does
   // get enabled.
diff --git a/pc/rtp_transceiver.cc b/pc/rtp_transceiver.cc
index f0a09ce..c275504 100644
--- a/pc/rtp_transceiver.cc
+++ b/pc/rtp_transceiver.cc
@@ -17,6 +17,7 @@
 #include <functional>
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
@@ -24,7 +25,6 @@
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_options.h"
@@ -513,7 +513,7 @@
   return media_type_;
 }
 
-absl::optional<std::string> RtpTransceiver::mid() const {
+std::optional<std::string> RtpTransceiver::mid() const {
   return mid_;
 }
 
@@ -550,7 +550,7 @@
 }
 
 void RtpTransceiver::set_fired_direction(
-    absl::optional<RtpTransceiverDirection> direction) {
+    std::optional<RtpTransceiverDirection> direction) {
   fired_direction_ = direction;
 }
 
@@ -591,7 +591,7 @@
   return RTCError::OK();
 }
 
-absl::optional<RtpTransceiverDirection> RtpTransceiver::current_direction()
+std::optional<RtpTransceiverDirection> RtpTransceiver::current_direction()
     const {
   if (unified_plan_ && stopped())
     return RtpTransceiverDirection::kStopped;
@@ -599,8 +599,7 @@
   return current_direction_;
 }
 
-absl::optional<RtpTransceiverDirection> RtpTransceiver::fired_direction()
-    const {
+std::optional<RtpTransceiverDirection> RtpTransceiver::fired_direction() const {
   return fired_direction_;
 }
 
@@ -684,7 +683,7 @@
 
   // 3. Set transceiver.[[Receptive]] to false.
   // 4. Set transceiver.[[CurrentDirection]] to null.
-  current_direction_ = absl::nullopt;
+  current_direction_ = std::nullopt;
 }
 
 RTCError RtpTransceiver::SetCodecPreferences(
diff --git a/pc/rtp_transceiver.h b/pc/rtp_transceiver.h
index 88febb9..610b842 100644
--- a/pc/rtp_transceiver.h
+++ b/pc/rtp_transceiver.h
@@ -15,11 +15,11 @@
 
 #include <functional>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio_options.h"
 #include "api/crypto/crypto_options.h"
@@ -203,15 +203,15 @@
   // when setting a local offer we need a way to remember which transceiver was
   // used to create which media section in the offer. Storing the mline index
   // in CreateOffer is specified in JSEP to allow us to do that.
-  absl::optional<size_t> mline_index() const { return mline_index_; }
-  void set_mline_index(absl::optional<size_t> mline_index) {
+  std::optional<size_t> mline_index() const { return mline_index_; }
+  void set_mline_index(std::optional<size_t> mline_index) {
     mline_index_ = mline_index;
   }
 
   // Sets the MID for this transceiver. If the MID is not null, then the
   // transceiver is considered "associated" with the media section that has the
   // same MID.
-  void set_mid(const absl::optional<std::string>& mid) { mid_ = mid; }
+  void set_mid(const std::optional<std::string>& mid) { mid_ = mid; }
 
   // Sets the intended direction for this transceiver. Intended to be used
   // internally over SetDirection since this does not trigger a negotiation
@@ -228,7 +228,7 @@
   // Sets the fired direction for this transceiver. The fired direction is null
   // until SetRemoteDescription is called or an answer is set (either local or
   // remote) after which the only valid reason to go back to null is rollback.
-  void set_fired_direction(absl::optional<RtpTransceiverDirection> direction);
+  void set_fired_direction(std::optional<RtpTransceiverDirection> direction);
 
   // According to JSEP rules for SetRemoteDescription, RtpTransceivers can be
   // reused only if they were added by AddTrack.
@@ -261,7 +261,7 @@
 
   // RtpTransceiverInterface implementation.
   cricket::MediaType media_type() const override;
-  absl::optional<std::string> mid() const override;
+  std::optional<std::string> mid() const override;
   rtc::scoped_refptr<RtpSenderInterface> sender() const override;
   rtc::scoped_refptr<RtpReceiverInterface> receiver() const override;
   bool stopped() const override;
@@ -269,8 +269,8 @@
   RtpTransceiverDirection direction() const override;
   RTCError SetDirectionWithError(
       RtpTransceiverDirection new_direction) override;
-  absl::optional<RtpTransceiverDirection> current_direction() const override;
-  absl::optional<RtpTransceiverDirection> fired_direction() const override;
+  std::optional<RtpTransceiverDirection> current_direction() const override;
+  std::optional<RtpTransceiverDirection> fired_direction() const override;
   RTCError StopStandard() override;
   void StopInternal() override;
   RTCError SetCodecPreferences(
@@ -323,10 +323,10 @@
   bool stopping_ RTC_GUARDED_BY(thread_) = false;
   bool is_pc_closed_ = false;
   RtpTransceiverDirection direction_ = RtpTransceiverDirection::kInactive;
-  absl::optional<RtpTransceiverDirection> current_direction_;
-  absl::optional<RtpTransceiverDirection> fired_direction_;
-  absl::optional<std::string> mid_;
-  absl::optional<size_t> mline_index_;
+  std::optional<RtpTransceiverDirection> current_direction_;
+  std::optional<RtpTransceiverDirection> fired_direction_;
+  std::optional<std::string> mid_;
+  std::optional<size_t> mline_index_;
   bool created_by_addtrack_ = false;
   bool reused_for_addtrack_ = false;
   bool has_ever_been_used_to_send_ = false;
@@ -352,15 +352,15 @@
 
 PROXY_PRIMARY_THREAD_DESTRUCTOR()
 BYPASS_PROXY_CONSTMETHOD0(cricket::MediaType, media_type)
-PROXY_CONSTMETHOD0(absl::optional<std::string>, mid)
+PROXY_CONSTMETHOD0(std::optional<std::string>, mid)
 PROXY_CONSTMETHOD0(rtc::scoped_refptr<RtpSenderInterface>, sender)
 PROXY_CONSTMETHOD0(rtc::scoped_refptr<RtpReceiverInterface>, receiver)
 PROXY_CONSTMETHOD0(bool, stopped)
 PROXY_CONSTMETHOD0(bool, stopping)
 PROXY_CONSTMETHOD0(RtpTransceiverDirection, direction)
 PROXY_METHOD1(RTCError, SetDirectionWithError, RtpTransceiverDirection)
-PROXY_CONSTMETHOD0(absl::optional<RtpTransceiverDirection>, current_direction)
-PROXY_CONSTMETHOD0(absl::optional<RtpTransceiverDirection>, fired_direction)
+PROXY_CONSTMETHOD0(std::optional<RtpTransceiverDirection>, current_direction)
+PROXY_CONSTMETHOD0(std::optional<RtpTransceiverDirection>, fired_direction)
 PROXY_METHOD0(RTCError, StopStandard)
 PROXY_METHOD0(void, StopInternal)
 PROXY_METHOD1(RTCError, SetCodecPreferences, rtc::ArrayView<RtpCodecCapability>)
diff --git a/pc/rtp_transceiver_unittest.cc b/pc/rtp_transceiver_unittest.cc
index b6dc7b2..9979154 100644
--- a/pc/rtp_transceiver_unittest.cc
+++ b/pc/rtp_transceiver_unittest.cc
@@ -13,10 +13,10 @@
 #include "pc/rtp_transceiver.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment_factory.h"
 #include "api/peer_connection_interface.h"
 #include "api/rtp_parameters.h"
diff --git a/pc/rtp_transmission_manager.cc b/pc/rtp_transmission_manager.cc
index ab9c58a..d42f8fc 100644
--- a/pc/rtp_transmission_manager.cc
+++ b/pc/rtp_transmission_manager.cc
@@ -10,10 +10,10 @@
 
 #include "pc/rtp_transmission_manager.h"
 
+#include <optional>
 #include <type_traits>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/peer_connection_interface.h"
 #include "api/rtp_transceiver_direction.h"
 #include "pc/audio_rtp_receiver.h"
@@ -520,8 +520,8 @@
 
   video_receiver->SetupMediaChannel(
       remote_sender_info.sender_id == kDefaultVideoSenderId
-          ? absl::nullopt
-          : absl::optional<uint32_t>(remote_sender_info.first_ssrc),
+          ? std::nullopt
+          : std::optional<uint32_t>(remote_sender_info.first_ssrc),
       video_media_receive_channel());
 
   auto receiver = RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
diff --git a/pc/rtp_transport.cc b/pc/rtp_transport.cc
index b2fc9b21..b2124003 100644
--- a/pc/rtp_transport.cc
+++ b/pc/rtp_transport.cc
@@ -58,7 +58,7 @@
     rtp_packet_transport_->SignalWritableState.disconnect(this);
     rtp_packet_transport_->SignalSentPacket.disconnect(this);
     // Reset the network route of the old transport.
-    SendNetworkRouteChanged(absl::optional<rtc::NetworkRoute>());
+    SendNetworkRouteChanged(std::optional<rtc::NetworkRoute>());
   }
   if (new_packet_transport) {
     new_packet_transport->SignalReadyToSend.connect(
@@ -95,7 +95,7 @@
     rtcp_packet_transport_->SignalWritableState.disconnect(this);
     rtcp_packet_transport_->SignalSentPacket.disconnect(this);
     // Reset the network route of the old transport.
-    SendNetworkRouteChanged(absl::optional<rtc::NetworkRoute>());
+    SendNetworkRouteChanged(std::optional<rtc::NetworkRoute>());
   }
   if (new_packet_transport) {
     new_packet_transport->SignalReadyToSend.connect(
@@ -222,7 +222,7 @@
 }
 
 void RtpTransport::OnNetworkRouteChanged(
-    absl::optional<rtc::NetworkRoute> network_route) {
+    std::optional<rtc::NetworkRoute> network_route) {
   SendNetworkRouteChanged(network_route);
 }
 
diff --git a/pc/rtp_transport.h b/pc/rtp_transport.h
index ebb7aa6..284bd30 100644
--- a/pc/rtp_transport.h
+++ b/pc/rtp_transport.h
@@ -14,9 +14,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/task_queue/pending_task_safety_flag.h"
 #include "api/units/timestamp.h"
@@ -107,7 +107,7 @@
 
   // Overridden by SrtpTransport.
   virtual void OnNetworkRouteChanged(
-      absl::optional<rtc::NetworkRoute> network_route);
+      std::optional<rtc::NetworkRoute> network_route);
   virtual void OnRtpPacketReceived(const rtc::ReceivedPacket& packet);
   virtual void OnRtcpPacketReceived(const rtc::ReceivedPacket& packet);
   // Overridden by SrtpTransport and DtlsSrtpTransport.
diff --git a/pc/rtp_transport_internal.h b/pc/rtp_transport_internal.h
index 483a1ce..90537dd 100644
--- a/pc/rtp_transport_internal.h
+++ b/pc/rtp_transport_internal.h
@@ -80,7 +80,7 @@
   // The argument is an optional network route.
   void SubscribeNetworkRouteChanged(
       const void* tag,
-      absl::AnyInvocable<void(absl::optional<rtc::NetworkRoute>)> callback) {
+      absl::AnyInvocable<void(std::optional<rtc::NetworkRoute>)> callback) {
     callback_list_network_route_changed_.AddReceiver(tag, std::move(callback));
   }
   void UnsubscribeNetworkRouteChanged(const void* tag) {
@@ -146,7 +146,7 @@
   void NotifyUnDemuxableRtpPacketReceived(RtpPacketReceived& packet) {
     callback_undemuxable_rtp_packet_received_(packet);
   }
-  void SendNetworkRouteChanged(absl::optional<rtc::NetworkRoute> route) {
+  void SendNetworkRouteChanged(std::optional<rtc::NetworkRoute> route) {
     callback_list_network_route_changed_.Send(route);
   }
   void SendWritableState(bool state) {
@@ -163,7 +163,7 @@
   absl::AnyInvocable<void(RtpPacketReceived&)>
       callback_undemuxable_rtp_packet_received_ =
           [](RtpPacketReceived& packet) {};
-  CallbackList<absl::optional<rtc::NetworkRoute>>
+  CallbackList<std::optional<rtc::NetworkRoute>>
       callback_list_network_route_changed_;
   CallbackList<bool> callback_list_writable_state_;
   CallbackList<const rtc::SentPacket&> callback_list_sent_packet_;
diff --git a/pc/rtp_transport_unittest.cc b/pc/rtp_transport_unittest.cc
index a3ab768..d4a0188 100644
--- a/pc/rtp_transport_unittest.cc
+++ b/pc/rtp_transport_unittest.cc
@@ -40,7 +40,7 @@
     transport->SubscribeReadyToSend(
         this, [this](bool ready) { OnReadyToSend(ready); });
     transport->SubscribeNetworkRouteChanged(
-        this, [this](absl::optional<rtc::NetworkRoute> route) {
+        this, [this](std::optional<rtc::NetworkRoute> route) {
           OnNetworkRouteChanged(route);
         });
     if (transport->rtp_packet_transport()) {
@@ -57,8 +57,8 @@
   bool ready() const { return ready_; }
   void OnReadyToSend(bool ready) { ready_ = ready; }
 
-  absl::optional<rtc::NetworkRoute> network_route() { return network_route_; }
-  void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
+  std::optional<rtc::NetworkRoute> network_route() { return network_route_; }
+  void OnNetworkRouteChanged(std::optional<rtc::NetworkRoute> network_route) {
     network_route_ = network_route;
   }
 
@@ -81,7 +81,7 @@
   int rtcp_transport_sent_count_ = 0;
   RtpTransport* transport_ = nullptr;
   bool ready_ = false;
-  absl::optional<rtc::NetworkRoute> network_route_;
+  std::optional<rtc::NetworkRoute> network_route_;
 };
 
 TEST(RtpTransportTest, SettingRtcpAndRtpSignalsReady) {
@@ -164,7 +164,7 @@
   network_route.remote = rtc::RouteEndpoint::CreateWithNetworkId(kRemoteNetId);
   network_route.last_sent_packet_id = kLastPacketId;
   network_route.packet_overhead = kTransportOverheadPerPacket;
-  fake_rtp.SetNetworkRoute(absl::optional<rtc::NetworkRoute>(network_route));
+  fake_rtp.SetNetworkRoute(std::optional<rtc::NetworkRoute>(network_route));
   transport.SetRtpPacketTransport(&fake_rtp);
   ASSERT_TRUE(observer.network_route());
   EXPECT_TRUE(observer.network_route()->connected);
@@ -193,7 +193,7 @@
   network_route.remote = rtc::RouteEndpoint::CreateWithNetworkId(kRemoteNetId);
   network_route.last_sent_packet_id = kLastPacketId;
   network_route.packet_overhead = kTransportOverheadPerPacket;
-  fake_rtcp.SetNetworkRoute(absl::optional<rtc::NetworkRoute>(network_route));
+  fake_rtcp.SetNetworkRoute(std::optional<rtc::NetworkRoute>(network_route));
   transport.SetRtcpPacketTransport(&fake_rtcp);
   ASSERT_TRUE(observer.network_route());
   EXPECT_TRUE(observer.network_route()->connected);
diff --git a/pc/sctp_data_channel.cc b/pc/sctp_data_channel.cc
index 6c2fb0b..bd8d3fa 100644
--- a/pc/sctp_data_channel.cc
+++ b/pc/sctp_data_channel.cc
@@ -45,8 +45,8 @@
 BYPASS_PROXY_CONSTMETHOD0(bool, ordered)
 BYPASS_PROXY_CONSTMETHOD0(uint16_t, maxRetransmitTime)
 BYPASS_PROXY_CONSTMETHOD0(uint16_t, maxRetransmits)
-BYPASS_PROXY_CONSTMETHOD0(absl::optional<int>, maxRetransmitsOpt)
-BYPASS_PROXY_CONSTMETHOD0(absl::optional<int>, maxPacketLifeTime)
+BYPASS_PROXY_CONSTMETHOD0(std::optional<int>, maxRetransmitsOpt)
+BYPASS_PROXY_CONSTMETHOD0(std::optional<int>, maxPacketLifeTime)
 BYPASS_PROXY_CONSTMETHOD0(std::string, protocol)
 BYPASS_PROXY_CONSTMETHOD0(bool, negotiated)
 // Can't bypass the proxy since the id may change.
@@ -85,7 +85,7 @@
     if (*maxRetransmits < 0) {
       RTC_LOG(LS_ERROR)
           << "Accepting maxRetransmits < 0 for backwards compatibility";
-      maxRetransmits = absl::nullopt;
+      maxRetransmits = std::nullopt;
     } else if (*maxRetransmits > std::numeric_limits<uint16_t>::max()) {
       maxRetransmits = std::numeric_limits<uint16_t>::max();
     }
@@ -95,7 +95,7 @@
     if (*maxRetransmitTime < 0) {
       RTC_LOG(LS_ERROR)
           << "Accepting maxRetransmitTime < 0 for backwards compatibility";
-      maxRetransmitTime = absl::nullopt;
+      maxRetransmitTime = std::nullopt;
     } else if (*maxRetransmitTime > std::numeric_limits<uint16_t>::max()) {
       maxRetransmitTime = std::numeric_limits<uint16_t>::max();
     }
@@ -119,7 +119,7 @@
   return true;
 }
 
-absl::optional<StreamId> SctpSidAllocator::AllocateSid(rtc::SSLRole role) {
+std::optional<StreamId> SctpSidAllocator::AllocateSid(rtc::SSLRole role) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   int potential_sid = (role == rtc::SSL_CLIENT) ? 0 : 1;
   while (potential_sid <= static_cast<int>(cricket::kMaxSctpSid)) {
@@ -129,7 +129,7 @@
     potential_sid += 2;
   }
   RTC_LOG(LS_ERROR) << "SCTP sid allocation pool exhausted.";
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool SctpSidAllocator::ReserveSid(StreamId sid) {
@@ -315,7 +315,7 @@
     rtc::Thread* network_thread)
     : signaling_thread_(signaling_thread),
       network_thread_(network_thread),
-      id_n_(config.id == -1 ? absl::nullopt : absl::make_optional(config.id)),
+      id_n_(config.id == -1 ? std::nullopt : std::make_optional(config.id)),
       internal_id_(GenerateUniqueId()),
       label_(label),
       protocol_(config.protocol),
@@ -459,11 +459,11 @@
   return max_retransmits_ ? *max_retransmits_ : static_cast<uint16_t>(-1);
 }
 
-absl::optional<int> SctpDataChannel::maxPacketLifeTime() const {
+std::optional<int> SctpDataChannel::maxPacketLifeTime() const {
   return max_retransmit_time_;
 }
 
-absl::optional<int> SctpDataChannel::maxRetransmitsOpt() const {
+std::optional<int> SctpDataChannel::maxRetransmitsOpt() const {
   return max_retransmits_;
 }
 
diff --git a/pc/sctp_data_channel.h b/pc/sctp_data_channel.h
index ea8e255..108f640 100644
--- a/pc/sctp_data_channel.h
+++ b/pc/sctp_data_channel.h
@@ -14,10 +14,10 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/data_channel_interface.h"
 #include "api/priority.h"
 #include "api/rtc_error.h"
@@ -78,7 +78,7 @@
   // stream ids in situations where we cannot determine the SSL role from the
   // transport for purposes of generating a stream ID.
   // See: https://www.rfc-editor.org/rfc/rfc8832.html#name-protocol-overview
-  absl::optional<rtc::SSLRole> fallback_ssl_role;
+  std::optional<rtc::SSLRole> fallback_ssl_role;
 };
 
 // Helper class to allocate unique IDs for SCTP DataChannels.
@@ -88,8 +88,8 @@
   // Gets the first unused odd/even id based on the DTLS role. If `role` is
   // SSL_CLIENT, the allocated id starts from 0 and takes even numbers;
   // otherwise, the id starts from 1 and takes odd numbers.
-  // If a `StreamId` cannot be allocated, `absl::nullopt` is returned.
-  absl::optional<StreamId> AllocateSid(rtc::SSLRole role);
+  // If a `StreamId` cannot be allocated, `std::nullopt` is returned.
+  std::optional<StreamId> AllocateSid(rtc::SSLRole role);
 
   // Attempts to reserve a specific sid. Returns false if it's unavailable.
   bool ReserveSid(StreamId sid);
@@ -159,8 +159,8 @@
   uint16_t maxRetransmitTime() const override;
   uint16_t maxRetransmits() const override;
 
-  absl::optional<int> maxPacketLifeTime() const override;
-  absl::optional<int> maxRetransmitsOpt() const override;
+  std::optional<int> maxPacketLifeTime() const override;
+  std::optional<int> maxRetransmitsOpt() const override;
   std::string protocol() const override;
   bool negotiated() const override;
   int id() const override;
@@ -221,7 +221,7 @@
   // stats purposes (see also `GetStats()`).
   int internal_id() const { return internal_id_; }
 
-  absl::optional<StreamId> sid_n() const {
+  std::optional<StreamId> sid_n() const {
     RTC_DCHECK_RUN_ON(network_thread_);
     return id_n_;
   }
@@ -270,14 +270,13 @@
 
   rtc::Thread* const signaling_thread_;
   rtc::Thread* const network_thread_;
-  absl::optional<StreamId> id_n_ RTC_GUARDED_BY(network_thread_) =
-      absl::nullopt;
+  std::optional<StreamId> id_n_ RTC_GUARDED_BY(network_thread_) = std::nullopt;
   const int internal_id_;
   const std::string label_;
   const std::string protocol_;
-  const absl::optional<int> max_retransmit_time_;
-  const absl::optional<int> max_retransmits_;
-  const absl::optional<PriorityValue> priority_;
+  const std::optional<int> max_retransmit_time_;
+  const std::optional<int> max_retransmits_;
+  const std::optional<PriorityValue> priority_;
   const bool negotiated_;
   const bool ordered_;
   // See the body of `MaybeSendOnBufferedAmountChanged`.
diff --git a/pc/sctp_transport.cc b/pc/sctp_transport.cc
index 6473bf4..f26d7ca 100644
--- a/pc/sctp_transport.cc
+++ b/pc/sctp_transport.cc
@@ -11,9 +11,9 @@
 #include "pc/sctp_transport.h"
 
 #include <algorithm>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/dtls_transport_interface.h"
 #include "api/priority.h"
 #include "api/sequence_checker.h"
@@ -28,8 +28,8 @@
     : owner_thread_(rtc::Thread::Current()),
       info_(SctpTransportState::kConnecting,
             dtls_transport,
-            /*max_message_size=*/absl::nullopt,
-            /*max_channels=*/absl::nullopt),
+            /*max_message_size=*/std::nullopt,
+            /*max_channels=*/std::nullopt),
       internal_sctp_transport_(std::move(internal)),
       dtls_transport_(dtls_transport) {
   RTC_DCHECK(internal_sctp_transport_.get());
diff --git a/pc/sctp_transport_unittest.cc b/pc/sctp_transport_unittest.cc
index 049cf41..f70bd70 100644
--- a/pc/sctp_transport_unittest.cc
+++ b/pc/sctp_transport_unittest.cc
@@ -10,11 +10,11 @@
 
 #include "pc/sctp_transport.h"
 
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/memory/memory.h"
-#include "absl/types/optional.h"
 #include "api/dtls_transport_interface.h"
 #include "api/priority.h"
 #include "api/transport/data_channel_transport_interface.h"
@@ -58,10 +58,10 @@
   bool ReadyToSendData() override { return true; }
   void set_debug_name_for_testing(const char* debug_name) override {}
   int max_message_size() const override { return 0; }
-  absl::optional<int> max_outbound_streams() const override {
+  std::optional<int> max_outbound_streams() const override {
     return max_outbound_streams_;
   }
-  absl::optional<int> max_inbound_streams() const override {
+  std::optional<int> max_inbound_streams() const override {
     return max_inbound_streams_;
   }
   size_t buffered_amount(int sid) const override { return 0; }
@@ -79,8 +79,8 @@
   void set_max_inbound_streams(int streams) { max_inbound_streams_ = streams; }
 
  private:
-  absl::optional<int> max_outbound_streams_;
-  absl::optional<int> max_inbound_streams_;
+  std::optional<int> max_outbound_streams_;
+  std::optional<int> max_inbound_streams_;
   std::function<void()> on_connected_callback_;
 };
 
diff --git a/pc/sctp_utils.cc b/pc/sctp_utils.cc
index df1da4d..2d81534 100644
--- a/pc/sctp_utils.cc
+++ b/pc/sctp_utils.cc
@@ -13,8 +13,8 @@
 #include <stddef.h>
 
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/priority.h"
 #include "rtc_base/byte_buffer.h"
 #include "rtc_base/copy_on_write_buffer.h"
@@ -122,8 +122,8 @@
       config->ordered = false;
   }
 
-  config->maxRetransmits = absl::nullopt;
-  config->maxRetransmitTime = absl::nullopt;
+  config->maxRetransmits = std::nullopt;
+  config->maxRetransmitTime = std::nullopt;
   switch (channel_type) {
     case DCOMCT_ORDERED_PARTIAL_RTXS:
     case DCOMCT_UNORDERED_PARTIAL_RTXS:
@@ -162,10 +162,10 @@
 
 bool WriteDataChannelOpenMessage(const std::string& label,
                                  const std::string& protocol,
-                                 absl::optional<PriorityValue> opt_priority,
+                                 std::optional<PriorityValue> opt_priority,
                                  bool ordered,
-                                 absl::optional<int> max_retransmits,
-                                 absl::optional<int> max_retransmit_time,
+                                 std::optional<int> max_retransmits,
+                                 std::optional<int> max_retransmit_time,
                                  rtc::CopyOnWriteBuffer* payload) {
   // Format defined at
   // http://tools.ietf.org/html/draft-ietf-rtcweb-data-protocol-09#section-5.1
diff --git a/pc/sctp_utils.h b/pc/sctp_utils.h
index 2f4b1f0..16759a1 100644
--- a/pc/sctp_utils.h
+++ b/pc/sctp_utils.h
@@ -64,10 +64,10 @@
 
 bool WriteDataChannelOpenMessage(const std::string& label,
                                  const std::string& protocol,
-                                 absl::optional<PriorityValue> priority,
+                                 std::optional<PriorityValue> priority,
                                  bool ordered,
-                                 absl::optional<int> max_retransmits,
-                                 absl::optional<int> max_retransmit_time,
+                                 std::optional<int> max_retransmits,
+                                 std::optional<int> max_retransmit_time,
                                  rtc::CopyOnWriteBuffer* payload);
 bool WriteDataChannelOpenMessage(const std::string& label,
                                  const DataChannelInit& config,
diff --git a/pc/sctp_utils_unittest.cc b/pc/sctp_utils_unittest.cc
index 0907b90..9f4c4a1 100644
--- a/pc/sctp_utils_unittest.cc
+++ b/pc/sctp_utils_unittest.cc
@@ -13,8 +13,8 @@
 #include <stdint.h>
 
 #include <limits>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/priority.h"
 #include "media/sctp/sctp_transport_internal.h"
 #include "rtc_base/byte_buffer.h"
diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc
index 199d7ec..5a50867 100644
--- a/pc/sdp_offer_answer.cc
+++ b/pc/sdp_offer_answer.cc
@@ -17,6 +17,7 @@
 #include <iterator>
 #include <map>
 #include <memory>
+#include <optional>
 #include <queue>
 #include <set>
 #include <string>
@@ -27,7 +28,6 @@
 #include "absl/memory/memory.h"
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/candidate.h"
 #include "api/crypto/crypto_options.h"
@@ -3241,7 +3241,7 @@
   }
 }
 
-absl::optional<bool> SdpOfferAnswerHandler::is_caller() const {
+std::optional<bool> SdpOfferAnswerHandler::is_caller() const {
   RTC_DCHECK_RUN_ON(signaling_thread());
   return is_caller_;
 }
@@ -3263,7 +3263,7 @@
   return pc_->NeedsIceRestart(content_name);
 }
 
-absl::optional<rtc::SSLRole> SdpOfferAnswerHandler::GetDtlsRole(
+std::optional<rtc::SSLRole> SdpOfferAnswerHandler::GetDtlsRole(
     const std::string& mid) const {
   RTC_DCHECK_RUN_ON(signaling_thread());
   return transport_controller_s()->GetDtlsRole(mid);
@@ -3341,11 +3341,11 @@
     return;
   }
 
-  absl::optional<rtc::SSLRole> guessed_role = GuessSslRole();
+  std::optional<rtc::SSLRole> guessed_role = GuessSslRole();
   network_thread()->BlockingCall(
       [&, data_channel_controller = data_channel_controller()] {
         RTC_DCHECK_RUN_ON(network_thread());
-        absl::optional<rtc::SSLRole> role = pc_->GetSctpSslRole_n();
+        std::optional<rtc::SSLRole> role = pc_->GetSctpSslRole_n();
         if (!role)
           role = guessed_role;
         if (role)
@@ -3353,10 +3353,10 @@
       });
 }
 
-absl::optional<rtc::SSLRole> SdpOfferAnswerHandler::GuessSslRole() const {
+std::optional<rtc::SSLRole> SdpOfferAnswerHandler::GuessSslRole() const {
   RTC_DCHECK_RUN_ON(signaling_thread());
   if (!pc_->sctp_mid())
-    return absl::nullopt;
+    return std::nullopt;
 
   // TODO(bugs.webrtc.org/13668): This guesswork is guessing wrong (returning
   // SSL_CLIENT = ACTIVE) if remote offer has role ACTIVE, but we'll be able
@@ -4188,9 +4188,9 @@
           (offer_answer_options.offer_to_receive_video > 0);
     }
   }
-  absl::optional<size_t> audio_index;
-  absl::optional<size_t> video_index;
-  absl::optional<size_t> data_index;
+  std::optional<size_t> audio_index;
+  std::optional<size_t> video_index;
+  std::optional<size_t> data_index;
   // If a current description exists, generate m= sections in the same order,
   // using the first audio/video/data section that appears and rejecting
   // extraneous ones.
@@ -4454,9 +4454,9 @@
     }
   }
 
-  absl::optional<size_t> audio_index;
-  absl::optional<size_t> video_index;
-  absl::optional<size_t> data_index;
+  std::optional<size_t> audio_index;
+  std::optional<size_t> video_index;
+  std::optional<size_t> data_index;
 
   // Generate m= sections that match those in the offer.
   // Note that mediasession.cc will handle intersection our preferred
@@ -4979,8 +4979,8 @@
         (remote_content && remote_content->rejected)) {
       RTC_LOG(LS_INFO) << "Dissociating transceiver"
                           " since the media section is being recycled.";
-      transceiver->internal()->set_mid(absl::nullopt);
-      transceiver->internal()->set_mline_index(absl::nullopt);
+      transceiver->internal()->set_mid(std::nullopt);
+      transceiver->internal()->set_mline_index(std::nullopt);
     } else if (!local_content && !remote_content) {
       // TODO(bugs.webrtc.org/11973): Consider if this should be removed already
       // See https://github.com/w3c/webrtc-pc/issues/2576
@@ -5241,9 +5241,9 @@
     const SessionDescriptionInterface* session_desc,
     RtpTransceiverDirection audio_direction,
     RtpTransceiverDirection video_direction,
-    absl::optional<size_t>* audio_index,
-    absl::optional<size_t>* video_index,
-    absl::optional<size_t>* data_index,
+    std::optional<size_t>* audio_index,
+    std::optional<size_t>* video_index,
+    std::optional<size_t>* data_index,
     cricket::MediaSessionOptions* session_options) {
   RTC_DCHECK_RUN_ON(signaling_thread());
   for (const cricket::ContentInfo& content :
diff --git a/pc/sdp_offer_answer.h b/pc/sdp_offer_answer.h
index 8b845f4..13492b6 100644
--- a/pc/sdp_offer_answer.h
+++ b/pc/sdp_offer_answer.h
@@ -17,11 +17,11 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/audio_options.h"
 #include "api/candidate.h"
 #include "api/jsep.h"
@@ -111,7 +111,7 @@
 
   bool NeedsIceRestart(const std::string& content_name) const override;
   bool IceRestartPending(const std::string& content_name) const override;
-  absl::optional<rtc::SSLRole> GetDtlsRole(
+  std::optional<rtc::SSLRole> GetDtlsRole(
       const std::string& mid) const override;
 
   void RestartIce();
@@ -155,7 +155,7 @@
   bool AddStream(MediaStreamInterface* local_stream);
   void RemoveStream(MediaStreamInterface* local_stream);
 
-  absl::optional<bool> is_caller() const;
+  std::optional<bool> is_caller() const;
   bool HasNewIceCredentials();
   void UpdateNegotiationNeeded();
   void AllocateSctpSids();
@@ -163,7 +163,7 @@
   // directly getting the information from the transport.
   // This is used for allocating stream ids for data channels.
   // See also `InternalDataChannelInit::fallback_ssl_role`.
-  absl::optional<rtc::SSLRole> GuessSslRole() const;
+  std::optional<rtc::SSLRole> GuessSslRole() const;
 
   // Destroys all media BaseChannels.
   void DestroyMediaChannels();
@@ -531,9 +531,9 @@
       const SessionDescriptionInterface* session_desc,
       RtpTransceiverDirection audio_direction,
       RtpTransceiverDirection video_direction,
-      absl::optional<size_t>* audio_index,
-      absl::optional<size_t>* video_index,
-      absl::optional<size_t>* data_index,
+      std::optional<size_t>* audio_index,
+      std::optional<size_t>* video_index,
+      std::optional<size_t>* data_index,
       cricket::MediaSessionOptions* session_options);
 
   // Generates the active MediaDescriptionOptions for the local data channel
@@ -605,7 +605,7 @@
       RTC_GUARDED_BY(signaling_thread()) = PeerConnectionInterface::kStable;
 
   // Whether this peer is the caller. Set when the local description is applied.
-  absl::optional<bool> is_caller_ RTC_GUARDED_BY(signaling_thread());
+  std::optional<bool> is_caller_ RTC_GUARDED_BY(signaling_thread());
 
   // Streams added via AddStream.
   const rtc::scoped_refptr<StreamCollection> local_streams_
@@ -678,7 +678,7 @@
 
   // Whether we are the initial offerer on the association. This
   // determines the SSL role.
-  absl::optional<bool> initial_offerer_ RTC_GUARDED_BY(signaling_thread());
+  std::optional<bool> initial_offerer_ RTC_GUARDED_BY(signaling_thread());
 
   rtc::WeakPtrFactory<SdpOfferAnswerHandler> weak_ptr_factory_
       RTC_GUARDED_BY(signaling_thread());
diff --git a/pc/sdp_state_provider.h b/pc/sdp_state_provider.h
index 23ffc91..8fe5bf5 100644
--- a/pc/sdp_state_provider.h
+++ b/pc/sdp_state_provider.h
@@ -45,7 +45,7 @@
   // Whether an ICE restart was indicated in the remote offer.
   // Used in CreateAnswer.
   virtual bool IceRestartPending(const std::string& content_name) const = 0;
-  virtual absl::optional<rtc::SSLRole> GetDtlsRole(
+  virtual std::optional<rtc::SSLRole> GetDtlsRole(
       const std::string& mid) const = 0;
 };
 
diff --git a/pc/simulcast_sdp_serializer.cc b/pc/simulcast_sdp_serializer.cc
index ceb2881..225c733 100644
--- a/pc/simulcast_sdp_serializer.cc
+++ b/pc/simulcast_sdp_serializer.cc
@@ -11,6 +11,7 @@
 #include "pc/simulcast_sdp_serializer.h"
 
 #include <map>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <utility>
@@ -18,7 +19,6 @@
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/string_encode.h"
@@ -164,7 +164,7 @@
   }
 
   for (const std::string& payload_type : string_payloads) {
-    absl::optional<int> value = rtc::StringToNumber<int>(payload_type);
+    std::optional<int> value = rtc::StringToNumber<int>(payload_type);
     if (!value.has_value()) {
       return ParseError("Invalid payload type: " + payload_type);
     }
diff --git a/pc/slow_peer_connection_integration_test.cc b/pc/slow_peer_connection_integration_test.cc
index 9e49291..fae81b5 100644
--- a/pc/slow_peer_connection_integration_test.cc
+++ b/pc/slow_peer_connection_integration_test.cc
@@ -14,13 +14,13 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/dtmf_sender_interface.h"
 #include "api/peer_connection_interface.h"
 #include "api/rtp_receiver_interface.h"
diff --git a/pc/srtp_transport.cc b/pc/srtp_transport.cc
index dd4fb14..aaf7283 100644
--- a/pc/srtp_transport.cc
+++ b/pc/srtp_transport.cc
@@ -173,7 +173,7 @@
 }
 
 void SrtpTransport::OnNetworkRouteChanged(
-    absl::optional<rtc::NetworkRoute> network_route) {
+    std::optional<rtc::NetworkRoute> network_route) {
   // Only append the SRTP overhead when there is a selected network route.
   if (network_route) {
     int srtp_overhead = 0;
diff --git a/pc/srtp_transport.h b/pc/srtp_transport.h
index e435e4a..ff8b728 100644
--- a/pc/srtp_transport.h
+++ b/pc/srtp_transport.h
@@ -15,10 +15,10 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/rtc_error.h"
 #include "p2p/base/packet_transport_internal.h"
@@ -120,7 +120,7 @@
   void OnRtpPacketReceived(const rtc::ReceivedPacket& packet) override;
   void OnRtcpPacketReceived(const rtc::ReceivedPacket& packet) override;
   void OnNetworkRouteChanged(
-      absl::optional<rtc::NetworkRoute> network_route) override;
+      std::optional<rtc::NetworkRoute> network_route) override;
 
   // Override the RtpTransport::OnWritableState.
   void OnWritableState(rtc::PacketTransportInternal* packet_transport) override;
@@ -151,8 +151,8 @@
   std::unique_ptr<cricket::SrtpSession> send_rtcp_session_;
   std::unique_ptr<cricket::SrtpSession> recv_rtcp_session_;
 
-  absl::optional<int> send_crypto_suite_;
-  absl::optional<int> recv_crypto_suite_;
+  std::optional<int> send_crypto_suite_;
+  std::optional<int> recv_crypto_suite_;
   rtc::ZeroOnFreeBuffer<uint8_t> send_key_;
   rtc::ZeroOnFreeBuffer<uint8_t> recv_key_;
 
diff --git a/pc/test/fake_audio_capture_module.h b/pc/test/fake_audio_capture_module.h
index f25d151..ac3fe61 100644
--- a/pc/test/fake_audio_capture_module.h
+++ b/pc/test/fake_audio_capture_module.h
@@ -137,7 +137,7 @@
 
   int32_t GetPlayoutUnderrunCount() const override { return -1; }
 
-  absl::optional<webrtc::AudioDeviceModule::Stats> GetStats() const override {
+  std::optional<webrtc::AudioDeviceModule::Stats> GetStats() const override {
     return webrtc::AudioDeviceModule::Stats();
   }
 #if defined(WEBRTC_IOS)
diff --git a/pc/test/fake_peer_connection_base.h b/pc/test/fake_peer_connection_base.h
index c69abe5..640f741 100644
--- a/pc/test/fake_peer_connection_base.h
+++ b/pc/test/fake_peer_connection_base.h
@@ -13,11 +13,11 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/sctp_transport_interface.h"
 #include "pc/peer_connection_internal.h"
@@ -229,7 +229,7 @@
     return IceGatheringState::kIceGatheringNew;
   }
 
-  absl::optional<bool> can_trickle_ice_candidates() { return absl::nullopt; }
+  std::optional<bool> can_trickle_ice_candidates() { return std::nullopt; }
 
   void AddAdaptationResource(rtc::scoped_refptr<Resource> resource) {}
 
@@ -262,13 +262,11 @@
     return {};
   }
 
-  absl::optional<std::string> sctp_transport_name() const override {
-    return absl::nullopt;
+  std::optional<std::string> sctp_transport_name() const override {
+    return std::nullopt;
   }
 
-  absl::optional<std::string> sctp_mid() const override {
-    return absl::nullopt;
-  }
+  std::optional<std::string> sctp_mid() const override { return std::nullopt; }
 
   std::map<std::string, cricket::TransportStats> GetTransportStatsByNames(
       const std::set<std::string>& transport_names) override {
@@ -277,8 +275,8 @@
 
   Call::Stats GetCallStats() override { return Call::Stats(); }
 
-  absl::optional<AudioDeviceModule::Stats> GetAudioDeviceStats() override {
-    return absl::nullopt;
+  std::optional<AudioDeviceModule::Stats> GetAudioDeviceStats() override {
+    return std::nullopt;
   }
 
   bool GetLocalCertificate(
@@ -327,8 +325,8 @@
   cricket::PortAllocator* port_allocator() override { return nullptr; }
   LegacyStatsCollector* legacy_stats() override { return nullptr; }
   PeerConnectionObserver* Observer() const override { return nullptr; }
-  absl::optional<rtc::SSLRole> GetSctpSslRole_n() override {
-    return absl::nullopt;
+  std::optional<rtc::SSLRole> GetSctpSslRole_n() override {
+    return std::nullopt;
   }
   PeerConnectionInterface::IceConnectionState ice_connection_state_internal()
       override {
diff --git a/pc/test/fake_peer_connection_for_stats.h b/pc/test/fake_peer_connection_for_stats.h
index 3e45899..e953eff 100644
--- a/pc/test/fake_peer_connection_for_stats.h
+++ b/pc/test/fake_peer_connection_for_stats.h
@@ -52,7 +52,7 @@
   }
 
  private:
-  absl::optional<cricket::VoiceMediaSendInfo> send_stats_;
+  std::optional<cricket::VoiceMediaSendInfo> send_stats_;
 };
 
 class FakeVoiceMediaReceiveChannelForStats
@@ -80,7 +80,7 @@
   }
 
  private:
-  absl::optional<cricket::VoiceMediaReceiveInfo> receive_stats_;
+  std::optional<cricket::VoiceMediaReceiveInfo> receive_stats_;
 };
 
 // Fake VideoMediaChannel where the result of GetStats can be configured.
@@ -108,7 +108,7 @@
   }
 
  private:
-  absl::optional<cricket::VideoMediaSendInfo> send_stats_;
+  std::optional<cricket::VideoMediaSendInfo> send_stats_;
 };
 
 class FakeVideoMediaReceiveChannelForStats
@@ -134,7 +134,7 @@
   }
 
  private:
-  absl::optional<cricket::VideoMediaReceiveInfo> receive_stats_;
+  std::optional<cricket::VideoMediaReceiveInfo> receive_stats_;
 };
 
 constexpr bool kDefaultRtcpMuxRequired = true;
@@ -387,7 +387,7 @@
   void SetCallStats(const Call::Stats& call_stats) { call_stats_ = call_stats; }
 
   void SetAudioDeviceStats(
-      absl::optional<AudioDeviceModule::Stats> audio_device_stats) {
+      std::optional<AudioDeviceModule::Stats> audio_device_stats) {
     audio_device_stats_ = audio_device_stats;
   }
 
@@ -473,7 +473,7 @@
 
   Call::Stats GetCallStats() override { return call_stats_; }
 
-  absl::optional<AudioDeviceModule::Stats> GetAudioDeviceStats() override {
+  std::optional<AudioDeviceModule::Stats> GetAudioDeviceStats() override {
     return audio_device_stats_;
   }
 
@@ -558,7 +558,7 @@
 
   Call::Stats call_stats_;
 
-  absl::optional<AudioDeviceModule::Stats> audio_device_stats_;
+  std::optional<AudioDeviceModule::Stats> audio_device_stats_;
 
   std::map<std::string, rtc::scoped_refptr<rtc::RTCCertificate>>
       local_certificates_by_transport_;
diff --git a/pc/test/fake_rtc_certificate_generator.h b/pc/test/fake_rtc_certificate_generator.h
index 61da26a..5d60529 100644
--- a/pc/test/fake_rtc_certificate_generator.h
+++ b/pc/test/fake_rtc_certificate_generator.h
@@ -11,10 +11,10 @@
 #ifndef PC_TEST_FAKE_RTC_CERTIFICATE_GENERATOR_H_
 #define PC_TEST_FAKE_RTC_CERTIFICATE_GENERATOR_H_
 
+#include <optional>
 #include <string>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/peer_connection_interface.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/units/time_delta.h"
@@ -136,7 +136,7 @@
   int generated_failures() { return generated_failures_; }
 
   void GenerateCertificateAsync(const rtc::KeyParams& key_params,
-                                const absl::optional<uint64_t>& expires_ms,
+                                const std::optional<uint64_t>& expires_ms,
                                 Callback callback) override {
     // The certificates are created from constant PEM strings and use its coded
     // expiration time, we do not support modifying it.
diff --git a/pc/test/frame_generator_capturer_video_track_source.h b/pc/test/frame_generator_capturer_video_track_source.h
index 79a5b34..700a64a 100644
--- a/pc/test/frame_generator_capturer_video_track_source.h
+++ b/pc/test/frame_generator_capturer_video_track_source.h
@@ -49,7 +49,7 @@
     video_capturer_ = std::make_unique<test::FrameGeneratorCapturer>(
         clock,
         test::CreateSquareFrameGenerator(config.width, config.height,
-                                         absl::nullopt,
+                                         std::nullopt,
                                          config.num_squares_generated),
         config.frames_per_second, *task_queue_factory_);
     video_capturer_->Init();
diff --git a/pc/test/integration_test_helpers.h b/pc/test/integration_test_helpers.h
index 5b9d632..8938ac2 100644
--- a/pc/test/integration_test_helpers.h
+++ b/pc/test/integration_test_helpers.h
@@ -21,6 +21,7 @@
 #include <list>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
@@ -29,7 +30,6 @@
 #include "absl/algorithm/container.h"
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/audio/audio_processing.h"
 #include "api/audio_options.h"
@@ -915,7 +915,7 @@
                          int sdp_mline_index,
                          const std::string& msg) override {
     RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
-    absl::optional<RTCError> result;
+    std::optional<RTCError> result;
     pc()->AddIceCandidate(absl::WrapUnique(CreateIceCandidate(
                               sdp_mid, sdp_mline_index, msg, nullptr)),
                           [&result](RTCError r) { result = r; });
@@ -1256,7 +1256,7 @@
  public:
   PeerConnectionIntegrationBaseTest(
       SdpSemantics sdp_semantics,
-      absl::optional<std::string> field_trials = absl::nullopt)
+      std::optional<std::string> field_trials = std::nullopt)
       : sdp_semantics_(sdp_semantics),
         ss_(new rtc::VirtualSocketServer()),
         fss_(new rtc::FirewallSocketServer(ss_.get())),
diff --git a/pc/test/mock_peer_connection_internal.h b/pc/test/mock_peer_connection_internal.h
index 64d0962..09a11dc 100644
--- a/pc/test/mock_peer_connection_internal.h
+++ b/pc/test/mock_peer_connection_internal.h
@@ -200,7 +200,7 @@
               AddAdaptationResource,
               (rtc::scoped_refptr<Resource>),
               (override));
-  MOCK_METHOD(absl::optional<bool>, can_trickle_ice_candidates, (), (override));
+  MOCK_METHOD(std::optional<bool>, can_trickle_ice_candidates, (), (override));
   MOCK_METHOD(bool,
               StartRtcEventLog,
               (std::unique_ptr<RtcEventLogOutput>, int64_t),
@@ -216,7 +216,7 @@
   // PeerConnectionSdpMethods
   MOCK_METHOD(std::string, session_id, (), (const, override));
   MOCK_METHOD(bool, NeedsIceRestart, (const std::string&), (const, override));
-  MOCK_METHOD(absl::optional<std::string>, sctp_mid, (), (const, override));
+  MOCK_METHOD(std::optional<std::string>, sctp_mid, (), (const, override));
   MOCK_METHOD(PeerConnectionInterface::RTCConfiguration*,
               configuration,
               (),
@@ -243,7 +243,7 @@
   MOCK_METHOD(cricket::PortAllocator*, port_allocator, (), (override));
   MOCK_METHOD(LegacyStatsCollector*, legacy_stats, (), (override));
   MOCK_METHOD(PeerConnectionObserver*, Observer, (), (const, override));
-  MOCK_METHOD(absl::optional<rtc::SSLRole>, GetSctpSslRole_n, (), (override));
+  MOCK_METHOD(std::optional<rtc::SSLRole>, GetSctpSslRole_n, (), (override));
   MOCK_METHOD(PeerConnectionInterface::IceConnectionState,
               ice_connection_state_internal,
               (),
@@ -295,7 +295,7 @@
               GetDataChannelStats,
               (),
               (const, override));
-  MOCK_METHOD(absl::optional<std::string>,
+  MOCK_METHOD(std::optional<std::string>,
               sctp_transport_name,
               (),
               (const, override));
@@ -308,7 +308,7 @@
               (const std::set<std::string>&),
               (override));
   MOCK_METHOD(Call::Stats, GetCallStats, (), (override));
-  MOCK_METHOD(absl::optional<AudioDeviceModule::Stats>,
+  MOCK_METHOD(std::optional<AudioDeviceModule::Stats>,
               GetAudioDeviceStats,
               (),
               (override));
diff --git a/pc/test/mock_peer_connection_observers.h b/pc/test/mock_peer_connection_observers.h
index 6222ef7..063e0d6 100644
--- a/pc/test/mock_peer_connection_observers.h
+++ b/pc/test/mock_peer_connection_observers.h
@@ -227,7 +227,7 @@
     return latest_negotiation_needed_event_.value_or(0u);
   }
   void clear_latest_negotiation_needed_event() {
-    latest_negotiation_needed_event_ = absl::nullopt;
+    latest_negotiation_needed_event_ = std::nullopt;
   }
 
   rtc::scoped_refptr<PeerConnectionInterface> pc_;
@@ -236,7 +236,7 @@
   rtc::scoped_refptr<DataChannelInterface> last_datachannel_;
   rtc::scoped_refptr<StreamCollection> remote_streams_;
   bool renegotiation_needed_ = false;
-  absl::optional<uint32_t> latest_negotiation_needed_event_;
+  std::optional<uint32_t> latest_negotiation_needed_event_;
   bool ice_gathering_complete_ = false;
   bool ice_connected_ = false;
   bool callback_triggered_ = false;
@@ -352,7 +352,7 @@
 
  private:
   // Set on complete, on success this is set to an RTCError::OK() error.
-  absl::optional<RTCError> error_;
+  std::optional<RTCError> error_;
 };
 
 class FakeSetRemoteDescriptionObserver
@@ -371,7 +371,7 @@
 
  private:
   // Set on complete, on success this is set to an RTCError::OK() error.
-  absl::optional<RTCError> error_;
+  std::optional<RTCError> error_;
 };
 
 class MockDataChannelObserver : public DataChannelObserver {
diff --git a/pc/test/mock_rtp_receiver_internal.h b/pc/test/mock_rtp_receiver_internal.h
index e76b567..c429a9b 100644
--- a/pc/test/mock_rtp_receiver_internal.h
+++ b/pc/test/mock_rtp_receiver_internal.h
@@ -11,10 +11,10 @@
 #ifndef PC_TEST_MOCK_RTP_RECEIVER_INTERNAL_H_
 #define PC_TEST_MOCK_RTP_RECEIVER_INTERNAL_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "pc/rtp_receiver.h"
 #include "test/gmock.h"
 
@@ -43,7 +43,7 @@
   MOCK_METHOD(void, SetObserver, (RtpReceiverObserverInterface*), (override));
   MOCK_METHOD(void,
               SetJitterBufferMinimumDelay,
-              (absl::optional<double>),
+              (std::optional<double>),
               (override));
   MOCK_METHOD(std::vector<RtpSource>, GetSources, (), (const, override));
   MOCK_METHOD(void,
@@ -63,7 +63,7 @@
               (override));
   MOCK_METHOD(void, SetupMediaChannel, (uint32_t), (override));
   MOCK_METHOD(void, SetupUnsignaledMediaChannel, (), (override));
-  MOCK_METHOD(absl::optional<uint32_t>, ssrc, (), (const, override));
+  MOCK_METHOD(std::optional<uint32_t>, ssrc, (), (const, override));
   MOCK_METHOD(void, NotifyFirstPacketReceived, (), (override));
   MOCK_METHOD(void, set_stream_ids, (std::vector<std::string>), (override));
   MOCK_METHOD(void,
diff --git a/pc/test/mock_voice_media_receive_channel_interface.h b/pc/test/mock_voice_media_receive_channel_interface.h
index 8c0f837..a86420f 100644
--- a/pc/test/mock_voice_media_receive_channel_interface.h
+++ b/pc/test/mock_voice_media_receive_channel_interface.h
@@ -92,7 +92,7 @@
               OnPacketReceived,
               (const webrtc::RtpPacketReceived& packet),
               (override));
-  MOCK_METHOD(absl::optional<uint32_t>,
+  MOCK_METHOD(std::optional<uint32_t>,
               GetUnsignaledSsrc,
               (),
               (const, override));
@@ -118,7 +118,7 @@
               SetBaseMinimumPlayoutDelayMs,
               (uint32_t ssrc, int delay_ms),
               (override));
-  MOCK_METHOD(absl::optional<int>,
+  MOCK_METHOD(std::optional<int>,
               GetBaseMinimumPlayoutDelayMs,
               (uint32_t ssrc),
               (const, override));
diff --git a/pc/test/peer_connection_test_wrapper.cc b/pc/test/peer_connection_test_wrapper.cc
index e5c3811..dc926c7 100644
--- a/pc/test/peer_connection_test_wrapper.cc
+++ b/pc/test/peer_connection_test_wrapper.cc
@@ -13,12 +13,12 @@
 #include <stddef.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "api/audio/audio_mixer.h"
 #include "api/audio/audio_processing.h"
@@ -81,7 +81,7 @@
   std::unique_ptr<webrtc::VideoEncoder> Create(
       const Environment& env,
       const webrtc::SdpVideoFormat& format) override {
-    if (absl::optional<webrtc::SdpVideoFormat> original_format =
+    if (std::optional<webrtc::SdpVideoFormat> original_format =
             webrtc::FuzzyMatchSdpVideoFormat(factory_.GetSupportedFormats(),
                                              format)) {
       return std::make_unique<webrtc::SimulcastEncoderAdapter>(
@@ -93,7 +93,7 @@
 
   CodecSupport QueryCodecSupport(
       const webrtc::SdpVideoFormat& format,
-      absl::optional<std::string> scalability_mode) const override {
+      std::optional<std::string> scalability_mode) const override {
     return factory_.QueryCodecSupport(format, scalability_mode);
   }
 
@@ -207,7 +207,7 @@
   return result.MoveValue();
 }
 
-absl::optional<webrtc::RtpCodecCapability>
+std::optional<webrtc::RtpCodecCapability>
 PeerConnectionTestWrapper::FindFirstSendCodecWithName(
     cricket::MediaType media_type,
     const std::string& name) const {
@@ -218,7 +218,7 @@
       return codec;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void PeerConnectionTestWrapper::WaitForNegotiation() {
diff --git a/pc/test/peer_connection_test_wrapper.h b/pc/test/peer_connection_test_wrapper.h
index 751c946..966bee0 100644
--- a/pc/test/peer_connection_test_wrapper.h
+++ b/pc/test/peer_connection_test_wrapper.h
@@ -65,7 +65,7 @@
       const std::string& label,
       const webrtc::DataChannelInit& init);
 
-  absl::optional<webrtc::RtpCodecCapability> FindFirstSendCodecWithName(
+  std::optional<webrtc::RtpCodecCapability> FindFirstSendCodecWithName(
       cricket::MediaType media_type,
       const std::string& name) const;
 
diff --git a/pc/test/svc_e2e_tests.cc b/pc/test/svc_e2e_tests.cc
index 757e983..332e553 100644
--- a/pc/test/svc_e2e_tests.cc
+++ b/pc/test/svc_e2e_tests.cc
@@ -95,7 +95,7 @@
 struct SvcTestParameters {
   static SvcTestParameters Create(const std::string& codec_name,
                                   const std::string& scalability_mode_str) {
-    absl::optional<ScalabilityMode> scalability_mode =
+    std::optional<ScalabilityMode> scalability_mode =
         ScalabilityModeFromString(scalability_mode_str);
     RTC_CHECK(scalability_mode.has_value())
         << "Unsupported scalability mode: " << scalability_mode_str;
@@ -177,8 +177,8 @@
                       const EncodedImage& encoded_image,
                       const EncoderStats& stats,
                       bool discarded) override {
-    absl::optional<int> spatial_id = encoded_image.SpatialIndex();
-    absl::optional<int> temporal_id = encoded_image.TemporalIndex();
+    std::optional<int> spatial_id = encoded_image.SpatialIndex();
+    std::optional<int> temporal_id = encoded_image.TemporalIndex();
     encoder_layers_seen_[spatial_id.value_or(0)][temporal_id.value_or(0)]++;
     DefaultVideoQualityAnalyzer::OnFrameEncoded(
         peer_name, frame_id, encoded_image, stats, discarded);
@@ -187,8 +187,8 @@
   void OnFramePreDecode(absl::string_view peer_name,
                         uint16_t frame_id,
                         const EncodedImage& input_image) override {
-    absl::optional<int> spatial_id = input_image.SpatialIndex();
-    absl::optional<int> temporal_id = input_image.TemporalIndex();
+    std::optional<int> spatial_id = input_image.SpatialIndex();
+    std::optional<int> temporal_id = input_image.TemporalIndex();
     if (!spatial_id) {
       decoder_layers_seen_[0][temporal_id.value_or(0)]++;
     } else {
@@ -223,14 +223,14 @@
   const SpatialTemporalLayerCounts& decoder_layers_seen() const {
     return decoder_layers_seen_;
   }
-  const absl::optional<std::string> reported_scalability_mode() const {
+  const std::optional<std::string> reported_scalability_mode() const {
     return reported_scalability_mode_;
   }
 
  private:
   SpatialTemporalLayerCounts encoder_layers_seen_;
   SpatialTemporalLayerCounts decoder_layers_seen_;
-  absl::optional<std::string> reported_scalability_mode_;
+  std::optional<std::string> reported_scalability_mode_;
 };
 
 MATCHER_P2(HasSpatialAndTemporalLayers,
diff --git a/pc/track_media_info_map.cc b/pc/track_media_info_map.cc
index ac24d07..7d440b8 100644
--- a/pc/track_media_info_map.cc
+++ b/pc/track_media_info_map.cc
@@ -107,8 +107,8 @@
 TrackMediaInfoMap::TrackMediaInfoMap() = default;
 
 void TrackMediaInfoMap::Initialize(
-    absl::optional<cricket::VoiceMediaInfo> voice_media_info,
-    absl::optional<cricket::VideoMediaInfo> video_media_info,
+    std::optional<cricket::VoiceMediaInfo> voice_media_info,
+    std::optional<cricket::VideoMediaInfo> video_media_info,
     rtc::ArrayView<rtc::scoped_refptr<RtpSenderInternal>> rtp_senders,
     rtc::ArrayView<rtc::scoped_refptr<RtpReceiverInternal>> rtp_receivers) {
   rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
@@ -262,12 +262,12 @@
   return FindValueOrNull(video_track_by_receiver_info_, &video_receiver_info);
 }
 
-absl::optional<int> TrackMediaInfoMap::GetAttachmentIdByTrack(
+std::optional<int> TrackMediaInfoMap::GetAttachmentIdByTrack(
     const MediaStreamTrackInterface* track) const {
   RTC_DCHECK(is_initialized_);
   auto it = attachment_id_by_track_.find(track);
-  return it != attachment_id_by_track_.end() ? absl::optional<int>(it->second)
-                                             : absl::nullopt;
+  return it != attachment_id_by_track_.end() ? std::optional<int>(it->second)
+                                             : std::nullopt;
 }
 
 }  // namespace webrtc
diff --git a/pc/track_media_info_map.h b/pc/track_media_info_map.h
index 98f8548..a3780d1 100644
--- a/pc/track_media_info_map.h
+++ b/pc/track_media_info_map.h
@@ -15,10 +15,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/media_stream_interface.h"
 #include "api/scoped_refptr.h"
@@ -41,16 +41,16 @@
   // or receivers, but TrackMediaInfoMap will keep their associated tracks alive
   // through reference counting until the map is destroyed.
   void Initialize(
-      absl::optional<cricket::VoiceMediaInfo> voice_media_info,
-      absl::optional<cricket::VideoMediaInfo> video_media_info,
+      std::optional<cricket::VoiceMediaInfo> voice_media_info,
+      std::optional<cricket::VideoMediaInfo> video_media_info,
       rtc::ArrayView<rtc::scoped_refptr<RtpSenderInternal>> rtp_senders,
       rtc::ArrayView<rtc::scoped_refptr<RtpReceiverInternal>> rtp_receivers);
 
-  const absl::optional<cricket::VoiceMediaInfo>& voice_media_info() const {
+  const std::optional<cricket::VoiceMediaInfo>& voice_media_info() const {
     RTC_DCHECK(is_initialized_);
     return voice_media_info_;
   }
-  const absl::optional<cricket::VideoMediaInfo>& video_media_info() const {
+  const std::optional<cricket::VideoMediaInfo>& video_media_info() const {
     RTC_DCHECK(is_initialized_);
     return video_media_info_;
   }
@@ -75,13 +75,13 @@
   // It is not going to work if a track is attached multiple times, and
   // it is not going to work if a received track is attached as a sending
   // track (loopback).
-  absl::optional<int> GetAttachmentIdByTrack(
+  std::optional<int> GetAttachmentIdByTrack(
       const MediaStreamTrackInterface* track) const;
 
  private:
   bool is_initialized_ = false;
-  absl::optional<cricket::VoiceMediaInfo> voice_media_info_;
-  absl::optional<cricket::VideoMediaInfo> video_media_info_;
+  std::optional<cricket::VoiceMediaInfo> voice_media_info_;
+  std::optional<cricket::VideoMediaInfo> video_media_info_;
   // These maps map info objects to their corresponding tracks. They are always
   // the inverse of the maps above. One info object always maps to only one
   // track. The use of scoped_refptr<> here ensures the tracks outlive
diff --git a/pc/track_media_info_map_unittest.cc b/pc/track_media_info_map_unittest.cc
index bffa3eb..43a97b8 100644
--- a/pc/track_media_info_map_unittest.cc
+++ b/pc/track_media_info_map_unittest.cc
@@ -325,7 +325,7 @@
   InitializeMap();
   EXPECT_EQ(rtp_senders_[0]->AttachmentId(),
             map_.GetAttachmentIdByTrack(local_audio_track_.get()));
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             map_.GetAttachmentIdByTrack(local_video_track_.get()));
 }
 
diff --git a/pc/transceiver_list.cc b/pc/transceiver_list.cc
index 250dfbc..e9059f9 100644
--- a/pc/transceiver_list.cc
+++ b/pc/transceiver_list.cc
@@ -22,8 +22,8 @@
 }
 
 void TransceiverStableState::SetMSectionIfUnset(
-    absl::optional<std::string> mid,
-    absl::optional<size_t> mline_index) {
+    std::optional<std::string> mid,
+    std::optional<size_t> mline_index) {
   if (!has_m_section_) {
     mid_ = mid;
     mline_index_ = mline_index;
diff --git a/pc/transceiver_list.h b/pc/transceiver_list.h
index 848ccc2..9e03171 100644
--- a/pc/transceiver_list.h
+++ b/pc/transceiver_list.h
@@ -15,10 +15,10 @@
 
 #include <algorithm>
 #include <map>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/media_types.h"
 #include "api/rtc_error.h"
 #include "api/rtp_parameters.h"
@@ -41,21 +41,21 @@
  public:
   TransceiverStableState() {}
   void set_newly_created();
-  void SetMSectionIfUnset(absl::optional<std::string> mid,
-                          absl::optional<size_t> mline_index);
+  void SetMSectionIfUnset(std::optional<std::string> mid,
+                          std::optional<size_t> mline_index);
   void SetRemoteStreamIds(const std::vector<std::string>& ids);
   void SetInitSendEncodings(
       const std::vector<RtpEncodingParameters>& encodings);
   void SetFiredDirection(
-      absl::optional<RtpTransceiverDirection> fired_direction) {
+      std::optional<RtpTransceiverDirection> fired_direction) {
     fired_direction_ = fired_direction;
   }
-  absl::optional<std::string> mid() const { return mid_; }
-  absl::optional<size_t> mline_index() const { return mline_index_; }
-  absl::optional<std::vector<std::string>> remote_stream_ids() const {
+  std::optional<std::string> mid() const { return mid_; }
+  std::optional<size_t> mline_index() const { return mline_index_; }
+  std::optional<std::vector<std::string>> remote_stream_ids() const {
     return remote_stream_ids_;
   }
-  absl::optional<std::vector<RtpEncodingParameters>> init_send_encodings()
+  std::optional<std::vector<RtpEncodingParameters>> init_send_encodings()
       const {
     return init_send_encodings_;
   }
@@ -64,16 +64,16 @@
   bool did_set_fired_direction() const { return fired_direction_.has_value(); }
   // Because fired_direction() is nullable, did_set_fired_direction() is used to
   // distinguish beteen "no value" and "null value".
-  absl::optional<RtpTransceiverDirection> fired_direction() const {
+  std::optional<RtpTransceiverDirection> fired_direction() const {
     RTC_DCHECK(did_set_fired_direction());
     return fired_direction_.value();
   }
 
  private:
-  absl::optional<std::string> mid_;
-  absl::optional<size_t> mline_index_;
-  absl::optional<std::vector<std::string>> remote_stream_ids_;
-  absl::optional<std::vector<RtpEncodingParameters>> init_send_encodings_;
+  std::optional<std::string> mid_;
+  std::optional<size_t> mline_index_;
+  std::optional<std::vector<std::string>> remote_stream_ids_;
+  std::optional<std::vector<RtpEncodingParameters>> init_send_encodings_;
   // Indicates that mid value from stable state has been captured and
   // that rollback has to restore the transceiver. Also protects against
   // subsequent overwrites.
@@ -84,7 +84,7 @@
   bool newly_created_ = false;
   // `fired_direction_` is nullable, so an optional of an optional is used to
   // distinguish between null and not set (sorry if this hurts your eyes).
-  absl::optional<absl::optional<RtpTransceiverDirection>> fired_direction_;
+  std::optional<std::optional<RtpTransceiverDirection>> fired_direction_;
 };
 
 // This class encapsulates the active list of transceivers on a
diff --git a/pc/transport_stats.h b/pc/transport_stats.h
index 46dccc9..db98813 100644
--- a/pc/transport_stats.h
+++ b/pc/transport_stats.h
@@ -31,7 +31,7 @@
   int ssl_version_bytes = 0;
   int srtp_crypto_suite = rtc::kSrtpInvalidCryptoSuite;
   int ssl_cipher_suite = rtc::kTlsNullWithNullNull;
-  absl::optional<rtc::SSLRole> dtls_role;
+  std::optional<rtc::SSLRole> dtls_role;
   webrtc::DtlsTransportState dtls_state = webrtc::DtlsTransportState::kNew;
   IceTransportStats ice_transport_stats;
   uint16_t ssl_peer_signature_algorithm = rtc::kSslSignatureAlgorithmUnknown;
diff --git a/pc/video_rtp_receiver.cc b/pc/video_rtp_receiver.cc
index 6694d3e..c3aeec9 100644
--- a/pc/video_rtp_receiver.cc
+++ b/pc/video_rtp_receiver.cc
@@ -114,7 +114,7 @@
   track_->internal()->set_ended();
 }
 
-void VideoRtpReceiver::RestartMediaChannel(absl::optional<uint32_t> ssrc) {
+void VideoRtpReceiver::RestartMediaChannel(std::optional<uint32_t> ssrc) {
   RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
   MediaSourceInterface::SourceState state = source_->state();
   // TODO(tommi): Can we restart the media channel without blocking?
@@ -126,7 +126,7 @@
 }
 
 void VideoRtpReceiver::RestartMediaChannel_w(
-    absl::optional<uint32_t> ssrc,
+    std::optional<uint32_t> ssrc,
     MediaSourceInterface::SourceState state) {
   RTC_DCHECK_RUN_ON(worker_thread_);
   if (!media_channel_) {
@@ -184,10 +184,10 @@
 
 void VideoRtpReceiver::SetupUnsignaledMediaChannel() {
   RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
-  RestartMediaChannel(absl::nullopt);
+  RestartMediaChannel(std::nullopt);
 }
 
-absl::optional<uint32_t> VideoRtpReceiver::ssrc() const {
+std::optional<uint32_t> VideoRtpReceiver::ssrc() const {
   RTC_DCHECK_RUN_ON(worker_thread_);
   if (!signaled_ssrc_.has_value() && media_channel_) {
     return media_channel_->GetUnsignaledSsrc();
@@ -250,7 +250,7 @@
 }
 
 void VideoRtpReceiver::SetJitterBufferMinimumDelay(
-    absl::optional<double> delay_seconds) {
+    std::optional<double> delay_seconds) {
   RTC_DCHECK_RUN_ON(worker_thread_);
   delay_.Set(delay_seconds);
   if (media_channel_ && signaled_ssrc_)
@@ -326,7 +326,7 @@
 }
 
 void VideoRtpReceiver::SetupMediaChannel(
-    absl::optional<uint32_t> ssrc,
+    std::optional<uint32_t> ssrc,
     cricket::MediaReceiveChannelInterface* media_channel) {
   RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
   RTC_DCHECK(media_channel);
diff --git a/pc/video_rtp_receiver.h b/pc/video_rtp_receiver.h
index dfa491c..bc42ad3 100644
--- a/pc/video_rtp_receiver.h
+++ b/pc/video_rtp_receiver.h
@@ -13,10 +13,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/crypto/frame_decryptor_interface.h"
 #include "api/dtls_transport_interface.h"
 #include "api/frame_transformer_interface.h"
@@ -89,7 +89,7 @@
   void Stop() override;
   void SetupMediaChannel(uint32_t ssrc) override;
   void SetupUnsignaledMediaChannel() override;
-  absl::optional<uint32_t> ssrc() const override;
+  std::optional<uint32_t> ssrc() const override;
   void NotifyFirstPacketReceived() override;
   void set_stream_ids(std::vector<std::string> stream_ids) override;
   void set_transport(
@@ -100,7 +100,7 @@
   void SetObserver(RtpReceiverObserverInterface* observer) override;
 
   void SetJitterBufferMinimumDelay(
-      absl::optional<double> delay_seconds) override;
+      std::optional<double> delay_seconds) override;
 
   void SetMediaChannel(
       cricket::MediaReceiveChannelInterface* media_channel) override;
@@ -111,13 +111,13 @@
 
   // Combines SetMediaChannel, SetupMediaChannel and
   // SetupUnsignaledMediaChannel.
-  void SetupMediaChannel(absl::optional<uint32_t> ssrc,
+  void SetupMediaChannel(std::optional<uint32_t> ssrc,
                          cricket::MediaReceiveChannelInterface* media_channel);
 
  private:
-  void RestartMediaChannel(absl::optional<uint32_t> ssrc)
+  void RestartMediaChannel(std::optional<uint32_t> ssrc)
       RTC_RUN_ON(&signaling_thread_checker_);
-  void RestartMediaChannel_w(absl::optional<uint32_t> ssrc,
+  void RestartMediaChannel_w(std::optional<uint32_t> ssrc,
                              MediaSourceInterface::SourceState state)
       RTC_RUN_ON(worker_thread_);
   void SetSink(rtc::VideoSinkInterface<VideoFrame>* sink)
@@ -151,7 +151,7 @@
   const std::string id_;
   cricket::VideoMediaReceiveChannelInterface* media_channel_
       RTC_GUARDED_BY(worker_thread_) = nullptr;
-  absl::optional<uint32_t> signaled_ssrc_ RTC_GUARDED_BY(worker_thread_);
+  std::optional<uint32_t> signaled_ssrc_ RTC_GUARDED_BY(worker_thread_);
   // `source_` is held here to be able to change the state of the source when
   // the VideoRtpReceiver is stopped.
   const rtc::scoped_refptr<VideoRtpTrackSource> source_;
diff --git a/pc/video_rtp_track_source_unittest.cc b/pc/video_rtp_track_source_unittest.cc
index 55632ce..62d33f5 100644
--- a/pc/video_rtp_track_source_unittest.cc
+++ b/pc/video_rtp_track_source_unittest.cc
@@ -10,7 +10,8 @@
 
 #include "pc/video_rtp_track_source.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/scoped_refptr.h"
 #include "api/units/timestamp.h"
 #include "api/video/color_space.h"
@@ -113,8 +114,8 @@
       const override {
     return nullptr;
   }
-  absl::optional<ColorSpace> color_space() const override {
-    return absl::nullopt;
+  std::optional<ColorSpace> color_space() const override {
+    return std::nullopt;
   }
   VideoCodecType codec() const override { return kVideoCodecGeneric; }
   bool is_key_frame() const override { return false; }
diff --git a/pc/video_track.h b/pc/video_track.h
index e504182..6733ad0 100644
--- a/pc/video_track.h
+++ b/pc/video_track.h
@@ -11,9 +11,9 @@
 #ifndef PC_VIDEO_TRACK_H_
 #define PC_VIDEO_TRACK_H_
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/media_stream_interface.h"
 #include "api/media_stream_track.h"
 #include "api/scoped_refptr.h"
diff --git a/pc/video_track_source.h b/pc/video_track_source.h
index 6aae178..75ea4ba 100644
--- a/pc/video_track_source.h
+++ b/pc/video_track_source.h
@@ -11,7 +11,8 @@
 #ifndef PC_VIDEO_TRACK_SOURCE_H_
 #define PC_VIDEO_TRACK_SOURCE_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/media_stream_interface.h"
 #include "api/notifier.h"
 #include "api/sequence_checker.h"
@@ -41,9 +42,7 @@
   bool remote() const override { return remote_; }
 
   bool is_screencast() const override { return false; }
-  absl::optional<bool> needs_denoising() const override {
-    return absl::nullopt;
-  }
+  std::optional<bool> needs_denoising() const override { return std::nullopt; }
 
   bool GetStats(Stats* stats) override { return false; }
 
diff --git a/pc/video_track_source_proxy.h b/pc/video_track_source_proxy.h
index 40d2423..d0ca34b 100644
--- a/pc/video_track_source_proxy.h
+++ b/pc/video_track_source_proxy.h
@@ -11,7 +11,8 @@
 #ifndef PC_VIDEO_TRACK_SOURCE_PROXY_H_
 #define PC_VIDEO_TRACK_SOURCE_PROXY_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/media_stream_interface.h"
 #include "api/video/recordable_encoded_frame.h"
 #include "api/video/video_frame.h"
@@ -32,7 +33,7 @@
 PROXY_CONSTMETHOD0(SourceState, state)
 BYPASS_PROXY_CONSTMETHOD0(bool, remote)
 BYPASS_PROXY_CONSTMETHOD0(bool, is_screencast)
-PROXY_CONSTMETHOD0(absl::optional<bool>, needs_denoising)
+PROXY_CONSTMETHOD0(std::optional<bool>, needs_denoising)
 PROXY_METHOD1(bool, GetStats, Stats*)
 PROXY_SECONDARY_METHOD2(void,
                         AddOrUpdateSink,
diff --git a/pc/webrtc_sdp.cc b/pc/webrtc_sdp.cc
index 3e638b0..cab245a 100644
--- a/pc/webrtc_sdp.cc
+++ b/pc/webrtc_sdp.cc
@@ -18,6 +18,7 @@
 #include <cstdint>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <type_traits>
@@ -28,13 +29,11 @@
 #include "absl/algorithm/container.h"
 #include "absl/strings/ascii.h"
 #include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
 #include "api/candidate.h"
 #include "api/jsep_ice_candidate.h"
 #include "api/jsep_session_description.h"
 #include "api/media_types.h"
-// for RtpExtension
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/rtc_error.h"
 #include "api/rtp_parameters.h"
 #include "api/rtp_transceiver_direction.h"
@@ -503,11 +502,11 @@
 
 // Gets line of `message` starting at `pos`, and checks overall SDP syntax. On
 // success, advances `pos` to the next line.
-static absl::optional<absl::string_view> GetLine(absl::string_view message,
-                                                 size_t* pos) {
+static std::optional<absl::string_view> GetLine(absl::string_view message,
+                                                size_t* pos) {
   size_t line_end = message.find(kNewLineChar, *pos);
   if (line_end == absl::string_view::npos) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   absl::string_view line =
       TrimReturnChar(message.substr(*pos, line_end - *pos));
@@ -528,7 +527,7 @@
   if (line.length() < 3 || !islower(static_cast<unsigned char>(line[0])) ||
       line[1] != kSdpDelimiterEqualChar ||
       (line[0] != kLineTypeSessionName && line[2] == kSdpDelimiterSpaceChar)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   *pos = line_end + 1;
   return line;
@@ -571,12 +570,12 @@
   return IsLineType(line, type, 0);
 }
 
-static absl::optional<absl::string_view>
+static std::optional<absl::string_view>
 GetLineWithType(absl::string_view message, size_t* pos, const char type) {
   if (IsLineType(message, type, *pos)) {
     return GetLine(message, pos);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 static bool HasAttribute(absl::string_view line, absl::string_view attribute) {
@@ -1102,7 +1101,7 @@
   }
   SocketAddress address(connection_address, port);
 
-  absl::optional<cricket::ProtocolType> protocol =
+  std::optional<cricket::ProtocolType> protocol =
       cricket::StringToProto(transport);
   if (!protocol) {
     return ParseFailed(first_line, "Unsupported transport type.", error);
@@ -2096,7 +2095,7 @@
                              rtc::SocketAddress* connection_addr,
                              cricket::SessionDescription* desc,
                              SdpParseError* error) {
-  absl::optional<absl::string_view> line;
+  std::optional<absl::string_view> line;
 
   desc->set_msid_signaling(cricket::kMsidSignalingNotUsed);
   desc->set_extmap_allow_mixed(false);
@@ -2153,7 +2152,7 @@
   // RFC 4566
   // c=* (connection information -- not required if included in
   //      all media)
-  if (absl::optional<absl::string_view> cline =
+  if (std::optional<absl::string_view> cline =
           GetLineWithType(message, pos, kLineTypeConnection);
       cline.has_value()) {
     if (!ParseConnectionData(*cline, connection_addr, error)) {
@@ -2198,7 +2197,7 @@
 
   // RFC 4566
   // a=* (zero or more session attribute lines)
-  while (absl::optional<absl::string_view> aline =
+  while (std::optional<absl::string_view> aline =
              GetLineWithType(message, pos, kLineTypeAttributes)) {
     if (HasAttribute(*aline, kAttributeGroup)) {
       if (!ParseGroupAttribute(*aline, desc, error)) {
@@ -2320,7 +2319,7 @@
   if (fields.size() != expected_fields) {
     return ParseFailedExpectFieldNum(line, expected_fields, error);
   }
-  if (absl::optional<cricket::ConnectionRole> role =
+  if (std::optional<cricket::ConnectionRole> role =
           cricket::StringToConnectionRole(fields[1]);
       role.has_value()) {
     *role_ptr = *role;
@@ -2702,7 +2701,7 @@
   // Zero or more media descriptions
   // RFC 4566
   // m=<media> <port> <proto> <fmt>
-  while (absl::optional<absl::string_view> mline =
+  while (std::optional<absl::string_view> mline =
              GetLineWithType(message, pos, kLineTypeMedia)) {
     ++mline_index;
 
@@ -2984,7 +2983,7 @@
   AddOrReplaceCodec(desc, codec);
 }
 
-absl::optional<cricket::Codec> PopWildcardCodec(
+std::optional<cricket::Codec> PopWildcardCodec(
     std::vector<cricket::Codec>* codecs) {
   RTC_DCHECK(codecs);
   for (auto iter = codecs->begin(); iter != codecs->end(); ++iter) {
@@ -2994,13 +2993,13 @@
       return wildcard_codec;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void UpdateFromWildcardCodecs(cricket::MediaContentDescription* desc) {
   RTC_DCHECK(desc);
   auto codecs = desc->codecs();
-  absl::optional<cricket::Codec> wildcard_codec = PopWildcardCodec(&codecs);
+  std::optional<cricket::Codec> wildcard_codec = PopWildcardCodec(&codecs);
   if (!wildcard_codec) {
     return;
   }
@@ -3063,7 +3062,7 @@
 
   // Loop until the next m line
   while (!IsLineType(message, kLineTypeMedia, *pos)) {
-    absl::optional<absl::string_view> line = GetLine(message, pos);
+    std::optional<absl::string_view> line = GetLine(message, pos);
     if (!line.has_value()) {
       if (*pos >= message.size()) {
         break;  // Done parsing
diff --git a/pc/webrtc_sdp_unittest.cc b/pc/webrtc_sdp_unittest.cc
index 71f6d04..6c08bf4 100644
--- a/pc/webrtc_sdp_unittest.cc
+++ b/pc/webrtc_sdp_unittest.cc
@@ -14,6 +14,7 @@
 #include <cstdint>
 #include <map>
 #include <memory>
+#include <optional>
 #include <sstream>
 #include <string>
 #include <utility>
@@ -23,7 +24,6 @@
 #include "absl/memory/memory.h"
 #include "absl/strings/str_replace.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/jsep_session_description.h"
 #include "api/media_types.h"
@@ -3352,11 +3352,11 @@
   cricket::Codec vp9 = vcd->codecs()[1];
   EXPECT_EQ(vp9.name, "VP9");
   EXPECT_EQ(vp9.id, 121);
-  EXPECT_EQ(vp9.packetization, absl::nullopt);
+  EXPECT_EQ(vp9.packetization, std::nullopt);
   cricket::Codec h264 = vcd->codecs()[2];
   EXPECT_EQ(h264.name, "H264");
   EXPECT_EQ(h264.id, 122);
-  EXPECT_EQ(h264.packetization, absl::nullopt);
+  EXPECT_EQ(h264.packetization, std::nullopt);
 }
 
 TEST_F(WebRtcSdpTest, SerializeAudioFmtpWithUnknownParameter) {
diff --git a/pc/webrtc_session_description_factory.cc b/pc/webrtc_session_description_factory.cc
index 9919260..236ec74 100644
--- a/pc/webrtc_session_description_factory.cc
+++ b/pc/webrtc_session_description_factory.cc
@@ -12,6 +12,7 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include <queue>
 #include <string>
 #include <type_traits>
@@ -19,7 +20,6 @@
 #include <vector>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/jsep.h"
 #include "api/jsep_session_description.h"
 #include "api/rtc_error.h"
@@ -163,7 +163,7 @@
       << key_params.type() << ").";
 
   // Request certificate. This happens asynchronously on a different thread.
-  cert_generator_->GenerateCertificateAsync(key_params, absl::nullopt,
+  cert_generator_->GenerateCertificateAsync(key_params, std::nullopt,
                                             std::move(callback));
 }
 
@@ -318,7 +318,7 @@
           sdp_info_->IceRestartPending(options.mid);
       // We should pass the current DTLS role to the transport description
       // factory, if there is already an existing ongoing session.
-      absl::optional<rtc::SSLRole> dtls_role =
+      std::optional<rtc::SSLRole> dtls_role =
           sdp_info_->GetDtlsRole(options.mid);
       if (dtls_role) {
         options.transport_options.prefer_passive_role =
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 4e06cdd..bbe25fd 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -91,10 +91,7 @@
 rtc_source_set("moving_max_counter") {
   visibility = [ "*" ]
   sources = [ "numerics/moving_max_counter.h" ]
-  deps = [
-    ":checks",
-    "//third_party/abseil-cpp/absl/types:optional",
-  ]
+  deps = [ ":checks" ]
 }
 
 rtc_source_set("one_time_event") {
@@ -220,10 +217,7 @@
     "numerics/histogram_percentile_counter.cc",
     "numerics/histogram_percentile_counter.h",
   ]
-  deps = [
-    ":checks",
-    "//third_party/abseil-cpp/absl/types:optional",
-  ]
+  deps = [ ":checks" ]
 }
 
 rtc_library("race_checker") {
@@ -264,7 +258,6 @@
     "../api/units:time_delta",
     "../api/units:timestamp",
     "system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -280,7 +273,6 @@
     "../api/units:time_delta",
     "../api/units:timestamp",
     "system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -297,7 +289,6 @@
     ":logging",
     ":safe_conversions",
     "system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -322,7 +313,6 @@
   deps = [
     ":checks",
     ":safe_conversions",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -404,7 +394,6 @@
     ":timeutils",
     "../api:sequence_checker",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -431,7 +420,6 @@
       "../api/units:time_delta",
       "synchronization:yield_policy",
       "system:warn_current_thread_is_deadlocked",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
@@ -454,7 +442,6 @@
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/meta:type_traits",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 
   if (build_with_chromium) {
@@ -523,7 +510,6 @@
     ":rate_statistics",
     "../system_wrappers",
     "synchronization:mutex",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -614,7 +600,6 @@
     ":safe_minmax",
     "../api:array_view",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -648,7 +633,6 @@
     "../api:scoped_refptr",
     "../api:sequence_checker",
     "system:no_unique_address",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -722,7 +706,6 @@
       "synchronization:mutex",
       "//third_party/abseil-cpp/absl/functional:any_invocable",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
@@ -798,7 +781,6 @@
   deps = [
     ":checks",
     ":mod_ops",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1082,7 +1064,6 @@
     "./network:ecn_marking",
     "system:rtc_export",
     "third_party/sigslot",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   if (is_win) {
     deps += [ ":win32" ]
@@ -1322,7 +1303,6 @@
     "network:received_packet",
     "network:sent_packet",
     "system:no_unique_address",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1388,7 +1368,6 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1460,7 +1439,6 @@
     "../api:scoped_refptr",
     "system:rtc_export",
     "//third_party/abseil-cpp/absl/functional:any_invocable",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1634,7 +1612,6 @@
     "//third_party/abseil-cpp/absl/functional:any_invocable",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 
   # If we are building the SSL library ourselves, we know it's BoringSSL.
@@ -1773,7 +1750,6 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   if (is_fuchsia) {
     deps += [ "//third_party/fuchsia-sdk/sdk/pkg/zx" ]
@@ -2007,7 +1983,6 @@
         "//third_party/abseil-cpp/absl/memory",
         "//third_party/abseil-cpp/absl/numeric:bits",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
 
       if (is_win) {
@@ -2067,7 +2042,6 @@
         "../test:test_main",
         "../test:test_support",
         "//third_party/abseil-cpp/absl/algorithm:container",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
 
@@ -2172,7 +2146,6 @@
         "//third_party/abseil-cpp/absl/memory",
         "//third_party/abseil-cpp/absl/strings",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
       if (rtc_enable_google_benchmarks) {
         deps += [ "synchronization:synchronization_unittests" ]
diff --git a/rtc_base/async_udp_socket.cc b/rtc_base/async_udp_socket.cc
index e9c16dc..f6e2c51 100644
--- a/rtc_base/async_udp_socket.cc
+++ b/rtc_base/async_udp_socket.cc
@@ -10,7 +10,8 @@
 
 #include "rtc_base/async_udp_socket.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/time_delta.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
diff --git a/rtc_base/async_udp_socket.h b/rtc_base/async_udp_socket.h
index af361b9..5eb4b4c 100644
--- a/rtc_base/async_udp_socket.h
+++ b/rtc_base/async_udp_socket.h
@@ -15,8 +15,8 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/sequence_checker.h"
 #include "api/units/time_delta.h"
 #include "rtc_base/async_packet_socket.h"
@@ -70,7 +70,7 @@
   RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker sequence_checker_;
   std::unique_ptr<Socket> socket_;
   rtc::Buffer buffer_ RTC_GUARDED_BY(sequence_checker_);
-  absl::optional<webrtc::TimeDelta> socket_time_offset_
+  std::optional<webrtc::TimeDelta> socket_time_offset_
       RTC_GUARDED_BY(sequence_checker_);
 };
 
diff --git a/rtc_base/bitrate_tracker.cc b/rtc_base/bitrate_tracker.cc
index 340e444..0146d3c 100644
--- a/rtc_base/bitrate_tracker.cc
+++ b/rtc_base/bitrate_tracker.cc
@@ -10,7 +10,8 @@
 
 #include "rtc_base/bitrate_tracker.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/data_rate.h"
 #include "api/units/timestamp.h"
 #include "rtc_base/rate_statistics.h"
@@ -20,11 +21,11 @@
 BitrateTracker::BitrateTracker(TimeDelta max_window_size)
     : impl_(max_window_size.ms(), RateStatistics::kBpsScale) {}
 
-absl::optional<DataRate> BitrateTracker::Rate(Timestamp now) const {
-  if (absl::optional<int64_t> rate = impl_.Rate(now.ms())) {
+std::optional<DataRate> BitrateTracker::Rate(Timestamp now) const {
+  if (std::optional<int64_t> rate = impl_.Rate(now.ms())) {
     return DataRate::BitsPerSec(*rate);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool BitrateTracker::SetWindowSize(TimeDelta window_size, Timestamp now) {
diff --git a/rtc_base/bitrate_tracker.h b/rtc_base/bitrate_tracker.h
index a54bd9a..9570cd6 100644
--- a/rtc_base/bitrate_tracker.h
+++ b/rtc_base/bitrate_tracker.h
@@ -14,7 +14,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/data_rate.h"
 #include "api/units/data_size.h"
 #include "api/units/time_delta.h"
@@ -50,7 +51,7 @@
 
   // Returns bitrate, moving averaging window as needed.
   // Returns nullopt when bitrate can't be measured.
-  absl::optional<DataRate> Rate(Timestamp now) const;
+  std::optional<DataRate> Rate(Timestamp now) const;
 
   // Update the size of the averaging window. The maximum allowed value for
   // `window_size` is `max_window_size` as supplied in the constructor.
diff --git a/rtc_base/bitrate_tracker_unittest.cc b/rtc_base/bitrate_tracker_unittest.cc
index c9e3d1e..61f569d 100644
--- a/rtc_base/bitrate_tracker_unittest.cc
+++ b/rtc_base/bitrate_tracker_unittest.cc
@@ -12,8 +12,8 @@
 
 #include <cstdlib>
 #include <limits>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/units/data_rate.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -34,7 +34,7 @@
   Timestamp now = Timestamp::Seconds(12'345);
   BitrateTracker stats(kWindow);
 
-  EXPECT_EQ(stats.Rate(now), absl::nullopt);
+  EXPECT_EQ(stats.Rate(now), std::nullopt);
 }
 
 TEST(BitrateTrackerTest, ReturnsNulloptAfterSingleDataPoint) {
@@ -44,7 +44,7 @@
   stats.Update(1'500, now);
   now += TimeDelta::Millis(10);
 
-  EXPECT_EQ(stats.Rate(now), absl::nullopt);
+  EXPECT_EQ(stats.Rate(now), std::nullopt);
 }
 
 TEST(BitrateTrackerTest, ReturnsRateAfterTwoMeasurements) {
@@ -82,7 +82,7 @@
 
     // Until window is full, bitrate is measured over a smaller window and might
     // look larger than the constant rate.
-    absl::optional<DataRate> bitrate = stats.Rate(now);
+    std::optional<DataRate> bitrate = stats.Rate(now);
     ASSERT_THAT(bitrate,
                 AllOf(Ge(kConstantRate), Le(total_size / (now - start))));
 
@@ -115,7 +115,7 @@
     now += kLargeInterval;
     stats.Update(kLargePacketSize, now);
   }
-  absl::optional<DataRate> last_bitrate = stats.Rate(now);
+  std::optional<DataRate> last_bitrate = stats.Rate(now);
   EXPECT_EQ(last_bitrate, kLargePacketSize / kLargeInterval);
 
   // Decrease bitrate with smaller measurments.
@@ -124,7 +124,7 @@
     now += kLargeInterval;
     stats.Update(kSmallPacketSize, now);
 
-    absl::optional<DataRate> bitrate = stats.Rate(now);
+    std::optional<DataRate> bitrate = stats.Rate(now);
     EXPECT_LT(bitrate, last_bitrate);
 
     last_bitrate = bitrate;
@@ -137,7 +137,7 @@
     now += kSmallInterval;
     stats.Update(kSmallPacketSize, now);
 
-    absl::optional<DataRate> bitrate = stats.Rate(now);
+    std::optional<DataRate> bitrate = stats.Rate(now);
     EXPECT_GE(bitrate, last_bitrate);
 
     last_bitrate = bitrate;
@@ -162,17 +162,17 @@
 
   now += kWindow + kEpsilon;
   // Silence over window size should trigger auto reset for coming sample.
-  EXPECT_EQ(stats.Rate(now), absl::nullopt);
+  EXPECT_EQ(stats.Rate(now), std::nullopt);
   stats.Update(kPacketSize, now);
   // Single measurment after reset is not enough to estimate the rate.
-  EXPECT_EQ(stats.Rate(now), absl::nullopt);
+  EXPECT_EQ(stats.Rate(now), std::nullopt);
 
   // Manual reset, add the same check again.
   stats.Reset();
-  EXPECT_EQ(stats.Rate(now), absl::nullopt);
+  EXPECT_EQ(stats.Rate(now), std::nullopt);
   now += kInterval;
   stats.Update(kPacketSize, now);
-  EXPECT_EQ(stats.Rate(now), absl::nullopt);
+  EXPECT_EQ(stats.Rate(now), std::nullopt);
 }
 
 TEST(BitrateTrackerTest, HandlesChangingWindowSize) {
@@ -223,17 +223,17 @@
   BitrateTracker stats(kWindow);
 
   stats.Update(kPacketSize, now);
-  ASSERT_EQ(stats.Rate(now), absl::nullopt);
+  ASSERT_EQ(stats.Rate(now), std::nullopt);
   now += kInterval;
   stats.Update(0, now);
-  absl::optional<DataRate> last_bitrate = stats.Rate(now);
+  std::optional<DataRate> last_bitrate = stats.Rate(now);
   EXPECT_GT(last_bitrate, DataRate::Zero());
   now += kInterval;
   while (now < start + kWindow) {
     SCOPED_TRACE(ToString(now - start));
     stats.Update(0, now);
 
-    absl::optional<DataRate> bitrate = stats.Rate(now);
+    std::optional<DataRate> bitrate = stats.Rate(now);
     EXPECT_GT(bitrate, DataRate::Zero());
     // As window expands, average bitrate decreases.
     EXPECT_LT(bitrate, last_bitrate);
@@ -260,7 +260,7 @@
   now += kEpsilon;
   stats.Update(very_large_number, now);
 
-  EXPECT_EQ(stats.Rate(now), absl::nullopt);
+  EXPECT_EQ(stats.Rate(now), std::nullopt);
 }
 
 }  // namespace
diff --git a/rtc_base/bitstream_reader_unittest.cc b/rtc_base/bitstream_reader_unittest.cc
index 46309b2..b9b51a2 100644
--- a/rtc_base/bitstream_reader_unittest.cc
+++ b/rtc_base/bitstream_reader_unittest.cc
@@ -15,9 +15,9 @@
 
 #include <array>
 #include <limits>
+#include <optional>
 
 #include "absl/numeric/bits.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "rtc_base/checks.h"
 #include "test/gmock.h"
@@ -28,26 +28,26 @@
 
 TEST(BitstreamReaderTest, InDebugModeRequiresToCheckOkStatusBeforeDestruction) {
   const uint8_t bytes[32] = {};
-  absl::optional<BitstreamReader> reader(absl::in_place, bytes);
+  std::optional<BitstreamReader> reader(absl::in_place, bytes);
 
   EXPECT_GE(reader->ReadBits(7), 0u);
 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(OS_ANDROID)
-  EXPECT_DEATH(reader = absl::nullopt, "");
+  EXPECT_DEATH(reader = std::nullopt, "");
 #endif
   EXPECT_TRUE(reader->Ok());
-  reader = absl::nullopt;
+  reader = std::nullopt;
 }
 
 TEST(BitstreamReaderTest, InDebugModeMayCheckRemainingBitsInsteadOfOkStatus) {
   const uint8_t bytes[32] = {};
-  absl::optional<BitstreamReader> reader(absl::in_place, bytes);
+  std::optional<BitstreamReader> reader(absl::in_place, bytes);
 
   EXPECT_GE(reader->ReadBit(), 0);
 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(OS_ANDROID)
-  EXPECT_DEATH(reader = absl::nullopt, "");
+  EXPECT_DEATH(reader = std::nullopt, "");
 #endif
   EXPECT_GE(reader->RemainingBitCount(), 0);
-  reader = absl::nullopt;
+  reader = std::nullopt;
 }
 
 TEST(BitstreamReaderTest, ConsumeBits) {
diff --git a/rtc_base/event.cc b/rtc_base/event.cc
index c2f6f8a..37d3f63 100644
--- a/rtc_base/event.cc
+++ b/rtc_base/event.cc
@@ -21,7 +21,8 @@
 #error "Must define either WEBRTC_WIN or WEBRTC_POSIX."
 #endif
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "rtc_base/checks.h"
 #include "rtc_base/synchronization/yield_policy.h"
 #include "rtc_base/system/warn_current_thread_is_deadlocked.h"
@@ -148,27 +149,26 @@
   // Instant when we'll log a warning message (because we've been waiting so
   // long it might be a bug), but not yet give up waiting. nullopt if we
   // shouldn't log a warning.
-  const absl::optional<timespec> warn_ts =
-      warn_after >= give_up_after
-          ? absl::nullopt
-          : absl::make_optional(GetTimespec(warn_after));
+  const std::optional<timespec> warn_ts =
+      warn_after >= give_up_after ? std::nullopt
+                                  : std::make_optional(GetTimespec(warn_after));
 
   // Instant when we'll stop waiting and return an error. nullopt if we should
   // never give up.
-  const absl::optional<timespec> give_up_ts =
+  const std::optional<timespec> give_up_ts =
       give_up_after.IsPlusInfinity()
-          ? absl::nullopt
-          : absl::make_optional(GetTimespec(give_up_after));
+          ? std::nullopt
+          : std::make_optional(GetTimespec(give_up_after));
 
   ScopedYieldPolicy::YieldExecution();
   pthread_mutex_lock(&event_mutex_);
 
   // Wait for `event_cond_` to trigger and `event_status_` to be set, with the
   // given timeout (or without a timeout if none is given).
-  const auto wait = [&](const absl::optional<timespec> timeout_ts) {
+  const auto wait = [&](const std::optional<timespec> timeout_ts) {
     int error = 0;
     while (!event_status_ && error == 0) {
-      if (timeout_ts == absl::nullopt) {
+      if (timeout_ts == std::nullopt) {
         error = pthread_cond_wait(&event_cond_, &event_mutex_);
       } else {
 #if USE_PTHREAD_COND_TIMEDWAIT_MONOTONIC_NP
@@ -184,7 +184,7 @@
   };
 
   int error;
-  if (warn_ts == absl::nullopt) {
+  if (warn_ts == std::nullopt) {
     error = wait(give_up_ts);
   } else {
     error = wait(warn_ts);
diff --git a/rtc_base/experiments/BUILD.gn b/rtc_base/experiments/BUILD.gn
index dc6f8b2..8b21a61 100644
--- a/rtc_base/experiments/BUILD.gn
+++ b/rtc_base/experiments/BUILD.gn
@@ -17,7 +17,6 @@
     "..:logging",
     "../../api:field_trials_view",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -42,7 +41,6 @@
     "../../rtc_base:stringutils",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -55,7 +53,6 @@
     ":field_trial_parser",
     "..:logging",
     "../../api:field_trials_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -70,7 +67,6 @@
     "../../api/transport:field_trial_based_config",
     "../../api/video_codecs:video_codecs_api",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -82,7 +78,6 @@
   deps = [
     "..:logging",
     "../../api:field_trials_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -97,7 +92,6 @@
     "../../api:field_trials_view",
     "../../api/video_codecs:video_codecs_api",
     "../../system_wrappers:field_trial",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -112,7 +106,6 @@
     "../../api:field_trials_view",
     "../../api/video_codecs:video_codecs_api",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -130,7 +123,6 @@
     "../../api/video_codecs:video_codecs_api",
     "../../video/config:encoder_config",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -142,7 +134,6 @@
   deps = [
     ":field_trial_parser",
     "../../api:field_trials_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -170,7 +161,6 @@
     "../../api/video:video_frame",
     "../../rtc_base:checks",
     "../../rtc_base:logging",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -217,7 +207,6 @@
       "../../test:test_support",
       "../../video/config:encoder_config",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
diff --git a/rtc_base/experiments/alr_experiment.cc b/rtc_base/experiments/alr_experiment.cc
index 5370de5..1c5ca14 100644
--- a/rtc_base/experiments/alr_experiment.cc
+++ b/rtc_base/experiments/alr_experiment.cc
@@ -34,11 +34,11 @@
          key_value_config.Lookup(kScreenshareProbingBweExperimentName).empty();
 }
 
-absl::optional<AlrExperimentSettings>
+std::optional<AlrExperimentSettings>
 AlrExperimentSettings::CreateFromFieldTrial(
     const FieldTrialsView& key_value_config,
     absl::string_view experiment_name) {
-  absl::optional<AlrExperimentSettings> ret;
+  std::optional<AlrExperimentSettings> ret;
   std::string group_name = key_value_config.Lookup(experiment_name);
 
   const std::string kIgnoredSuffix = "_Dogfood";
diff --git a/rtc_base/experiments/alr_experiment.h b/rtc_base/experiments/alr_experiment.h
index 9914828..bc4514e 100644
--- a/rtc_base/experiments/alr_experiment.h
+++ b/rtc_base/experiments/alr_experiment.h
@@ -13,8 +13,9 @@
 
 #include <stdint.h>
 
+#include <optional>
+
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 
 namespace webrtc {
@@ -35,7 +36,7 @@
   static constexpr absl::string_view kStrictPacingAndProbingExperimentName =
       "WebRTC-StrictPacingAndProbing";
 
-  static absl::optional<AlrExperimentSettings> CreateFromFieldTrial(
+  static std::optional<AlrExperimentSettings> CreateFromFieldTrial(
       const FieldTrialsView& key_value_config,
       absl::string_view experiment_name);
   static bool MaxOneFieldTrialEnabled(const FieldTrialsView& key_value_config);
diff --git a/rtc_base/experiments/balanced_degradation_settings.cc b/rtc_base/experiments/balanced_degradation_settings.cc
index 1a269b4..8e0b513 100644
--- a/rtc_base/experiments/balanced_degradation_settings.cc
+++ b/rtc_base/experiments/balanced_degradation_settings.cc
@@ -144,11 +144,11 @@
   return DefaultConfigs();
 }
 
-absl::optional<VideoEncoder::QpThresholds> GetThresholds(
+std::optional<VideoEncoder::QpThresholds> GetThresholds(
     VideoCodecType type,
     const BalancedDegradationSettings::Config& config) {
-  absl::optional<int> low;
-  absl::optional<int> high;
+  std::optional<int> low;
+  std::optional<int> high;
 
   switch (type) {
     case kVideoCodecVP8:
@@ -179,19 +179,19 @@
 
   if (low && high) {
     RTC_LOG(LS_INFO) << "QP thresholds: low: " << *low << ", high: " << *high;
-    return absl::optional<VideoEncoder::QpThresholds>(
+    return std::optional<VideoEncoder::QpThresholds>(
         VideoEncoder::QpThresholds(*low, *high));
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 int GetFps(VideoCodecType type,
-           const absl::optional<BalancedDegradationSettings::Config>& config) {
+           const std::optional<BalancedDegradationSettings::Config>& config) {
   if (!config.has_value()) {
     return std::numeric_limits<int>::max();
   }
 
-  absl::optional<int> fps;
+  std::optional<int> fps;
   switch (type) {
     case kVideoCodecVP8:
       fps = config->vp8.GetFps();
@@ -219,13 +219,13 @@
   return (framerate == kMaxFps) ? std::numeric_limits<int>::max() : framerate;
 }
 
-absl::optional<int> GetKbps(
+std::optional<int> GetKbps(
     VideoCodecType type,
-    const absl::optional<BalancedDegradationSettings::Config>& config) {
+    const std::optional<BalancedDegradationSettings::Config>& config) {
   if (!config.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
-  absl::optional<int> kbps;
+  std::optional<int> kbps;
   switch (type) {
     case kVideoCodecVP8:
       kbps = config->vp8.GetKbps();
@@ -251,16 +251,16 @@
   if (kbps.has_value())
     return kbps;
 
-  return config->kbps > 0 ? absl::optional<int>(config->kbps) : absl::nullopt;
+  return config->kbps > 0 ? std::optional<int>(config->kbps) : std::nullopt;
 }
 
-absl::optional<int> GetKbpsRes(
+std::optional<int> GetKbpsRes(
     VideoCodecType type,
-    const absl::optional<BalancedDegradationSettings::Config>& config) {
+    const std::optional<BalancedDegradationSettings::Config>& config) {
   if (!config.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
-  absl::optional<int> kbps_res;
+  std::optional<int> kbps_res;
   switch (type) {
     case kVideoCodecVP8:
       kbps_res = config->vp8.GetKbpsRes();
@@ -286,34 +286,34 @@
   if (kbps_res.has_value())
     return kbps_res;
 
-  return config->kbps_res > 0 ? absl::optional<int>(config->kbps_res)
-                              : absl::nullopt;
+  return config->kbps_res > 0 ? std::optional<int>(config->kbps_res)
+                              : std::nullopt;
 }
 }  // namespace
 
-absl::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetQpLow()
+std::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetQpLow()
     const {
-  return (qp_low > 0) ? absl::optional<int>(qp_low) : absl::nullopt;
+  return (qp_low > 0) ? std::optional<int>(qp_low) : std::nullopt;
 }
 
-absl::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetQpHigh()
+std::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetQpHigh()
     const {
-  return (qp_high > 0) ? absl::optional<int>(qp_high) : absl::nullopt;
+  return (qp_high > 0) ? std::optional<int>(qp_high) : std::nullopt;
 }
 
-absl::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetFps()
+std::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetFps()
     const {
-  return (fps > 0) ? absl::optional<int>(fps) : absl::nullopt;
+  return (fps > 0) ? std::optional<int>(fps) : std::nullopt;
 }
 
-absl::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetKbps()
+std::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetKbps()
     const {
-  return (kbps > 0) ? absl::optional<int>(kbps) : absl::nullopt;
+  return (kbps > 0) ? std::optional<int>(kbps) : std::nullopt;
 }
 
-absl::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetKbpsRes()
+std::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetKbpsRes()
     const {
-  return (kbps_res > 0) ? absl::optional<int>(kbps_res) : absl::nullopt;
+  return (kbps_res > 0) ? std::optional<int>(kbps_res) : std::nullopt;
 }
 
 BalancedDegradationSettings::Config::Config() = default;
@@ -415,32 +415,32 @@
   return GetFps(type, GetMinFpsConfig(pixels));
 }
 
-absl::optional<BalancedDegradationSettings::Config>
+std::optional<BalancedDegradationSettings::Config>
 BalancedDegradationSettings::GetMinFpsConfig(int pixels) const {
   for (const auto& config : configs_) {
     if (pixels <= config.pixels)
       return config;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 int BalancedDegradationSettings::MaxFps(VideoCodecType type, int pixels) const {
   return GetFps(type, GetMaxFpsConfig(pixels));
 }
 
-absl::optional<BalancedDegradationSettings::Config>
+std::optional<BalancedDegradationSettings::Config>
 BalancedDegradationSettings::GetMaxFpsConfig(int pixels) const {
   for (size_t i = 0; i < configs_.size() - 1; ++i) {
     if (pixels <= configs_[i].pixels)
       return configs_[i + 1];
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool BalancedDegradationSettings::CanAdaptUp(VideoCodecType type,
                                              int pixels,
                                              uint32_t bitrate_bps) const {
-  absl::optional<int> min_kbps = GetKbps(type, GetMaxFpsConfig(pixels));
+  std::optional<int> min_kbps = GetKbps(type, GetMaxFpsConfig(pixels));
   if (!min_kbps.has_value() || bitrate_bps == 0) {
     return true;  // No limit configured or bitrate provided.
   }
@@ -451,25 +451,25 @@
     VideoCodecType type,
     int pixels,
     uint32_t bitrate_bps) const {
-  absl::optional<int> min_kbps = GetKbpsRes(type, GetMaxFpsConfig(pixels));
+  std::optional<int> min_kbps = GetKbpsRes(type, GetMaxFpsConfig(pixels));
   if (!min_kbps.has_value() || bitrate_bps == 0) {
     return true;  // No limit configured or bitrate provided.
   }
   return bitrate_bps >= static_cast<uint32_t>(min_kbps.value() * 1000);
 }
 
-absl::optional<int> BalancedDegradationSettings::MinFpsDiff(int pixels) const {
+std::optional<int> BalancedDegradationSettings::MinFpsDiff(int pixels) const {
   for (const auto& config : configs_) {
     if (pixels <= config.pixels) {
       return (config.fps_diff > kNoFpsDiff)
-                 ? absl::optional<int>(config.fps_diff)
-                 : absl::nullopt;
+                 ? std::optional<int>(config.fps_diff)
+                 : std::nullopt;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<VideoEncoder::QpThresholds>
+std::optional<VideoEncoder::QpThresholds>
 BalancedDegradationSettings::GetQpThresholds(VideoCodecType type,
                                              int pixels) const {
   return GetThresholds(type, GetConfig(pixels));
diff --git a/rtc_base/experiments/balanced_degradation_settings.h b/rtc_base/experiments/balanced_degradation_settings.h
index 2bca73d..6993681 100644
--- a/rtc_base/experiments/balanced_degradation_settings.h
+++ b/rtc_base/experiments/balanced_degradation_settings.h
@@ -11,9 +11,9 @@
 #ifndef RTC_BASE_EXPERIMENTS_BALANCED_DEGRADATION_SETTINGS_H_
 #define RTC_BASE_EXPERIMENTS_BALANCED_DEGRADATION_SETTINGS_H_
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/video_codecs/video_encoder.h"
 
@@ -40,11 +40,11 @@
              kbps == o.kbps && kbps_res == o.kbps_res;
     }
 
-    absl::optional<int> GetQpLow() const;
-    absl::optional<int> GetQpHigh() const;
-    absl::optional<int> GetFps() const;
-    absl::optional<int> GetKbps() const;
-    absl::optional<int> GetKbpsRes() const;
+    std::optional<int> GetQpLow() const;
+    std::optional<int> GetQpHigh() const;
+    std::optional<int> GetFps() const;
+    std::optional<int> GetKbps() const;
+    std::optional<int> GetKbpsRes() const;
 
     // Optional settings.
     int qp_low = 0;
@@ -123,16 +123,15 @@
                             uint32_t bitrate_bps) const;
 
   // Gets the min framerate diff from `configs_` based on `pixels`.
-  absl::optional<int> MinFpsDiff(int pixels) const;
+  std::optional<int> MinFpsDiff(int pixels) const;
 
   // Gets QpThresholds for the codec `type` based on `pixels`.
-  absl::optional<VideoEncoder::QpThresholds> GetQpThresholds(
-      VideoCodecType type,
-      int pixels) const;
+  std::optional<VideoEncoder::QpThresholds> GetQpThresholds(VideoCodecType type,
+                                                            int pixels) const;
 
  private:
-  absl::optional<Config> GetMinFpsConfig(int pixels) const;
-  absl::optional<Config> GetMaxFpsConfig(int pixels) const;
+  std::optional<Config> GetMinFpsConfig(int pixels) const;
+  std::optional<Config> GetMaxFpsConfig(int pixels) const;
   Config GetConfig(int pixels) const;
 
   std::vector<Config> configs_;
diff --git a/rtc_base/experiments/encoder_info_settings.cc b/rtc_base/experiments/encoder_info_settings.cc
index e9229df..82480ea 100644
--- a/rtc_base/experiments/encoder_info_settings.cc
+++ b/rtc_base/experiments/encoder_info_settings.cc
@@ -73,7 +73,7 @@
           {1280 * 720, 900000, 30000, 2500000}};
 }
 
-absl::optional<VideoEncoder::ResolutionBitrateLimits>
+std::optional<VideoEncoder::ResolutionBitrateLimits>
 EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
     VideoCodecType codec_type,
     int frame_size_pixels) {
@@ -101,13 +101,13 @@
 
 // Through linear interpolation, return the bitrate limit corresponding to the
 // specified |frame_size_pixels|.
-absl::optional<VideoEncoder::ResolutionBitrateLimits>
+std::optional<VideoEncoder::ResolutionBitrateLimits>
 EncoderInfoSettings::GetSinglecastBitrateLimitForResolutionWhenQpIsUntrusted(
-    absl::optional<int> frame_size_pixels,
+    std::optional<int> frame_size_pixels,
     const std::vector<VideoEncoder::ResolutionBitrateLimits>&
         resolution_bitrate_limits) {
   if (!frame_size_pixels.has_value() || frame_size_pixels.value() <= 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<VideoEncoder::ResolutionBitrateLimits> bitrate_limits =
@@ -121,7 +121,7 @@
        });
 
   if (bitrate_limits.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   int interpolation_index = -1;
@@ -171,7 +171,7 @@
         << " min_start_bitrate_bps = " << min_start_bitrate_bps
         << " min_bitrate_bps = " << kDefaultMinBitratebps
         << " max_bitrate_bps = " << max_bitrate_bps;
-    return absl::nullopt;
+    return std::nullopt;
   }
 }
 
@@ -208,12 +208,12 @@
   resolution_bitrate_limits_ = ToResolutionBitrateLimits(bitrate_limits.Get());
 }
 
-absl::optional<uint32_t> EncoderInfoSettings::requested_resolution_alignment()
+std::optional<uint32_t> EncoderInfoSettings::requested_resolution_alignment()
     const {
   if (requested_resolution_alignment_ &&
       requested_resolution_alignment_.Value() < 1) {
     RTC_LOG(LS_WARNING) << "Unsupported alignment value, ignored.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return requested_resolution_alignment_.GetOptional();
 }
diff --git a/rtc_base/experiments/encoder_info_settings.h b/rtc_base/experiments/encoder_info_settings.h
index b200238..b534659 100644
--- a/rtc_base/experiments/encoder_info_settings.h
+++ b/rtc_base/experiments/encoder_info_settings.h
@@ -11,11 +11,11 @@
 #ifndef RTC_BASE_EXPERIMENTS_ENCODER_INFO_SETTINGS_H_
 #define RTC_BASE_EXPERIMENTS_ENCODER_INFO_SETTINGS_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/video_codecs/video_encoder.h"
 #include "rtc_base/experiments/field_trial_parser.h"
@@ -34,7 +34,7 @@
     int max_bitrate_bps = 0;        // The maximum bitrate.
   };
 
-  absl::optional<uint32_t> requested_resolution_alignment() const;
+  std::optional<uint32_t> requested_resolution_alignment() const;
   bool apply_alignment_to_all_simulcast_layers() const {
     return apply_alignment_to_all_simulcast_layers_.Get();
   }
@@ -46,16 +46,16 @@
   static std::vector<VideoEncoder::ResolutionBitrateLimits>
   GetDefaultSinglecastBitrateLimits(VideoCodecType codec_type);
 
-  static absl::optional<VideoEncoder::ResolutionBitrateLimits>
+  static std::optional<VideoEncoder::ResolutionBitrateLimits>
   GetDefaultSinglecastBitrateLimitsForResolution(VideoCodecType codec_type,
                                                  int frame_size_pixels);
 
   static std::vector<VideoEncoder::ResolutionBitrateLimits>
   GetDefaultSinglecastBitrateLimitsWhenQpIsUntrusted();
 
-  static absl::optional<VideoEncoder::ResolutionBitrateLimits>
+  static std::optional<VideoEncoder::ResolutionBitrateLimits>
   GetSinglecastBitrateLimitForResolutionWhenQpIsUntrusted(
-      absl::optional<int> frame_size_pixels,
+      std::optional<int> frame_size_pixels,
       const std::vector<VideoEncoder::ResolutionBitrateLimits>&
           resolution_bitrate_limits);
 
diff --git a/rtc_base/experiments/encoder_info_settings_unittest.cc b/rtc_base/experiments/encoder_info_settings_unittest.cc
index 5739673..916f980 100644
--- a/rtc_base/experiments/encoder_info_settings_unittest.cc
+++ b/rtc_base/experiments/encoder_info_settings_unittest.cc
@@ -22,7 +22,7 @@
   ExplicitKeyValueConfig field_trials("");
 
   SimulcastEncoderAdapterEncoderInfoSettings settings(field_trials);
-  EXPECT_EQ(absl::nullopt, settings.requested_resolution_alignment());
+  EXPECT_EQ(std::nullopt, settings.requested_resolution_alignment());
   EXPECT_FALSE(settings.apply_alignment_to_all_simulcast_layers());
   EXPECT_TRUE(settings.resolution_bitrate_limits().empty());
 }
@@ -33,7 +33,7 @@
       "requested_resolution_alignment:0/");
 
   SimulcastEncoderAdapterEncoderInfoSettings settings(field_trials);
-  EXPECT_EQ(absl::nullopt, settings.requested_resolution_alignment());
+  EXPECT_EQ(std::nullopt, settings.requested_resolution_alignment());
 }
 
 TEST(SimulcastEncoderAdapterSettingsTest, GetResolutionAlignment) {
@@ -68,7 +68,7 @@
       "max_bitrate_bps:77000/");
 
   SimulcastEncoderAdapterEncoderInfoSettings settings(field_trials);
-  EXPECT_EQ(absl::nullopt, settings.requested_resolution_alignment());
+  EXPECT_EQ(std::nullopt, settings.requested_resolution_alignment());
   EXPECT_FALSE(settings.apply_alignment_to_all_simulcast_layers());
   EXPECT_THAT(settings.resolution_bitrate_limits(),
               ::testing::ElementsAre(VideoEncoder::ResolutionBitrateLimits{
diff --git a/rtc_base/experiments/field_trial_list.cc b/rtc_base/experiments/field_trial_list.cc
index 72cd79f..26c17b5 100644
--- a/rtc_base/experiments/field_trial_list.cc
+++ b/rtc_base/experiments/field_trial_list.cc
@@ -35,7 +35,7 @@
   return GetList()->Used();
 }
 
-bool FieldTrialStructListBase::Parse(absl::optional<std::string> str_value) {
+bool FieldTrialStructListBase::Parse(std::optional<std::string> str_value) {
   RTC_DCHECK_NOTREACHED();
   return true;
 }
diff --git a/rtc_base/experiments/field_trial_list.h b/rtc_base/experiments/field_trial_list.h
index 63403cc..0c90f94 100644
--- a/rtc_base/experiments/field_trial_list.h
+++ b/rtc_base/experiments/field_trial_list.h
@@ -65,7 +65,7 @@
   const std::vector<T>* operator->() const { return &values_; }
 
  protected:
-  bool Parse(absl::optional<std::string> str_value) override {
+  bool Parse(std::optional<std::string> str_value) override {
     parse_got_called_ = true;
 
     if (!str_value) {
@@ -76,7 +76,7 @@
     std::vector<T> new_values_;
 
     for (const absl::string_view token : rtc::split(str_value.value(), '|')) {
-      absl::optional<T> value = ParseTypedParameter<T>(token);
+      std::optional<T> value = ParseTypedParameter<T>(token);
       if (value) {
         new_values_.push_back(*value);
       } else {
@@ -180,7 +180,7 @@
   // user-supplied values, we return -1.
   int ValidateAndGetLength();
 
-  bool Parse(absl::optional<std::string> str_value) override;
+  bool Parse(std::optional<std::string> str_value) override;
 
   std::vector<std::unique_ptr<FieldTrialListWrapper>> sub_lists_;
 };
diff --git a/rtc_base/experiments/field_trial_parser.cc b/rtc_base/experiments/field_trial_parser.cc
index 78d5489..d27fbba 100644
--- a/rtc_base/experiments/field_trial_parser.cc
+++ b/rtc_base/experiments/field_trial_parser.cc
@@ -60,7 +60,7 @@
   while (!tail.empty()) {
     size_t key_end = tail.find_first_of(",:");
     absl::string_view key = tail.substr(0, key_end);
-    absl::optional<std::string> opt_value;
+    std::optional<std::string> opt_value;
     if (key_end == absl::string_view::npos) {
       tail = "";
     } else if (tail[key_end] == ':') {
@@ -112,17 +112,17 @@
 }
 
 template <>
-absl::optional<bool> ParseTypedParameter<bool>(absl::string_view str) {
+std::optional<bool> ParseTypedParameter<bool>(absl::string_view str) {
   if (str == "true" || str == "1") {
     return true;
   } else if (str == "false" || str == "0") {
     return false;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 template <>
-absl::optional<double> ParseTypedParameter<double>(absl::string_view str) {
+std::optional<double> ParseTypedParameter<double>(absl::string_view str) {
   double value;
   char unit[2]{0, 0};
   if (sscanf(std::string(str).c_str(), "%lf%1s", &value, unit) >= 1) {
@@ -130,56 +130,56 @@
       return value / 100;
     return value;
   } else {
-    return absl::nullopt;
+    return std::nullopt;
   }
 }
 
 template <>
-absl::optional<int> ParseTypedParameter<int>(absl::string_view str) {
+std::optional<int> ParseTypedParameter<int>(absl::string_view str) {
   int64_t value;
   if (sscanf(std::string(str).c_str(), "%" SCNd64, &value) == 1) {
     if (rtc::IsValueInRangeForNumericType<int, int64_t>(value)) {
       return static_cast<int>(value);
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 template <>
-absl::optional<unsigned> ParseTypedParameter<unsigned>(absl::string_view str) {
+std::optional<unsigned> ParseTypedParameter<unsigned>(absl::string_view str) {
   int64_t value;
   if (sscanf(std::string(str).c_str(), "%" SCNd64, &value) == 1) {
     if (rtc::IsValueInRangeForNumericType<unsigned, int64_t>(value)) {
       return static_cast<unsigned>(value);
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 template <>
-absl::optional<std::string> ParseTypedParameter<std::string>(
+std::optional<std::string> ParseTypedParameter<std::string>(
     absl::string_view str) {
   return std::string(str);
 }
 
 template <>
-absl::optional<absl::optional<bool>> ParseTypedParameter<absl::optional<bool>>(
+std::optional<std::optional<bool>> ParseTypedParameter<std::optional<bool>>(
     absl::string_view str) {
   return ParseOptionalParameter<bool>(str);
 }
 template <>
-absl::optional<absl::optional<int>> ParseTypedParameter<absl::optional<int>>(
+std::optional<std::optional<int>> ParseTypedParameter<std::optional<int>>(
     absl::string_view str) {
   return ParseOptionalParameter<int>(str);
 }
 template <>
-absl::optional<absl::optional<unsigned>>
-ParseTypedParameter<absl::optional<unsigned>>(absl::string_view str) {
+std::optional<std::optional<unsigned>>
+ParseTypedParameter<std::optional<unsigned>>(absl::string_view str) {
   return ParseOptionalParameter<unsigned>(str);
 }
 template <>
-absl::optional<absl::optional<double>>
-ParseTypedParameter<absl::optional<double>>(absl::string_view str) {
+std::optional<std::optional<double>> ParseTypedParameter<std::optional<double>>(
+    absl::string_view str) {
   return ParseOptionalParameter<double>(str);
 }
 
@@ -197,10 +197,10 @@
   return value_;
 }
 
-bool FieldTrialFlag::Parse(absl::optional<std::string> str_value) {
+bool FieldTrialFlag::Parse(std::optional<std::string> str_value) {
   // Only set the flag if there is no argument provided.
   if (str_value) {
-    absl::optional<bool> opt_value = ParseTypedParameter<bool>(*str_value);
+    std::optional<bool> opt_value = ParseTypedParameter<bool>(*str_value);
     if (!opt_value)
       return false;
     value_ = *opt_value;
@@ -224,14 +224,14 @@
     default;
 AbstractFieldTrialEnum::~AbstractFieldTrialEnum() = default;
 
-bool AbstractFieldTrialEnum::Parse(absl::optional<std::string> str_value) {
+bool AbstractFieldTrialEnum::Parse(std::optional<std::string> str_value) {
   if (str_value) {
     auto it = enum_mapping_.find(*str_value);
     if (it != enum_mapping_.end()) {
       value_ = it->second;
       return true;
     }
-    absl::optional<int> value = ParseTypedParameter<int>(*str_value);
+    std::optional<int> value = ParseTypedParameter<int>(*str_value);
     if (value.has_value() &&
         (valid_values_.find(*value) != valid_values_.end())) {
       value_ = *value;
diff --git a/rtc_base/experiments/field_trial_parser.h b/rtc_base/experiments/field_trial_parser.h
index 822895e..890da80 100644
--- a/rtc_base/experiments/field_trial_parser.h
+++ b/rtc_base/experiments/field_trial_parser.h
@@ -14,12 +14,12 @@
 
 #include <initializer_list>
 #include <map>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 
 // Field trial parser functionality. Provides funcitonality to parse field trial
 // argument strings in key:value format. Each parameter is described using
@@ -51,7 +51,7 @@
       std::initializer_list<FieldTrialParameterInterface*> fields,
       absl::string_view trial_string);
   void MarkAsUsed() { used_ = true; }
-  virtual bool Parse(absl::optional<std::string> str_value) = 0;
+  virtual bool Parse(std::optional<std::string> str_value) = 0;
 
   virtual void ParseDone() {}
 
@@ -68,10 +68,10 @@
     std::initializer_list<FieldTrialParameterInterface*> fields,
     absl::string_view trial_string);
 
-// Specialize this in code file for custom types. Should return absl::nullopt if
+// Specialize this in code file for custom types. Should return std::nullopt if
 // the given string cannot be properly parsed.
 template <typename T>
-absl::optional<T> ParseTypedParameter(absl::string_view);
+std::optional<T> ParseTypedParameter(absl::string_view);
 
 // This class uses the ParseTypedParameter function to implement a parameter
 // implementation with an enforced default value.
@@ -87,9 +87,9 @@
   void SetForTest(T value) { value_ = value; }
 
  protected:
-  bool Parse(absl::optional<std::string> str_value) override {
+  bool Parse(std::optional<std::string> str_value) override {
     if (str_value) {
-      absl::optional<T> value = ParseTypedParameter<T>(*str_value);
+      std::optional<T> value = ParseTypedParameter<T>(*str_value);
       if (value.has_value()) {
         value_ = value.value();
         return true;
@@ -110,8 +110,8 @@
  public:
   FieldTrialConstrained(absl::string_view key,
                         T default_value,
-                        absl::optional<T> lower_limit,
-                        absl::optional<T> upper_limit)
+                        std::optional<T> lower_limit,
+                        std::optional<T> upper_limit)
       : FieldTrialParameterInterface(key),
         value_(default_value),
         lower_limit_(lower_limit),
@@ -121,9 +121,9 @@
   const T* operator->() const { return &value_; }
 
  protected:
-  bool Parse(absl::optional<std::string> str_value) override {
+  bool Parse(std::optional<std::string> str_value) override {
     if (str_value) {
-      absl::optional<T> value = ParseTypedParameter<T>(*str_value);
+      std::optional<T> value = ParseTypedParameter<T>(*str_value);
       if (value && (!lower_limit_ || *value >= *lower_limit_) &&
           (!upper_limit_ || *value <= *upper_limit_)) {
         value_ = *value;
@@ -135,8 +135,8 @@
 
  private:
   T value_;
-  absl::optional<T> lower_limit_;
-  absl::optional<T> upper_limit_;
+  std::optional<T> lower_limit_;
+  std::optional<T> upper_limit_;
 };
 
 class AbstractFieldTrialEnum : public FieldTrialParameterInterface {
@@ -148,7 +148,7 @@
   AbstractFieldTrialEnum(const AbstractFieldTrialEnum&);
 
  protected:
-  bool Parse(absl::optional<std::string> str_value) override;
+  bool Parse(std::optional<std::string> str_value) override;
 
  protected:
   int value_;
@@ -181,35 +181,35 @@
 };
 
 // This class uses the ParseTypedParameter function to implement an optional
-// parameter implementation that can default to absl::nullopt.
+// parameter implementation that can default to std::nullopt.
 template <typename T>
 class FieldTrialOptional : public FieldTrialParameterInterface {
  public:
   explicit FieldTrialOptional(absl::string_view key)
       : FieldTrialParameterInterface(key) {}
-  FieldTrialOptional(absl::string_view key, absl::optional<T> default_value)
+  FieldTrialOptional(absl::string_view key, std::optional<T> default_value)
       : FieldTrialParameterInterface(key), value_(default_value) {}
-  absl::optional<T> GetOptional() const { return value_; }
+  std::optional<T> GetOptional() const { return value_; }
   const T& Value() const { return value_.value(); }
   const T& operator*() const { return value_.value(); }
   const T* operator->() const { return &value_.value(); }
   explicit operator bool() const { return value_.has_value(); }
 
  protected:
-  bool Parse(absl::optional<std::string> str_value) override {
+  bool Parse(std::optional<std::string> str_value) override {
     if (str_value) {
-      absl::optional<T> value = ParseTypedParameter<T>(*str_value);
+      std::optional<T> value = ParseTypedParameter<T>(*str_value);
       if (!value.has_value())
         return false;
       value_ = value.value();
     } else {
-      value_ = absl::nullopt;
+      value_ = std::nullopt;
     }
     return true;
   }
 
  private:
-  absl::optional<T> value_;
+  std::optional<T> value_;
 };
 
 // Equivalent to a FieldTrialParameter<bool> in the case that both key and value
@@ -223,47 +223,46 @@
   explicit operator bool() const;
 
  protected:
-  bool Parse(absl::optional<std::string> str_value) override;
+  bool Parse(std::optional<std::string> str_value) override;
 
  private:
   bool value_;
 };
 
 template <typename T>
-absl::optional<absl::optional<T>> ParseOptionalParameter(
-    absl::string_view str) {
+std::optional<std::optional<T>> ParseOptionalParameter(absl::string_view str) {
   if (str.empty())
-    return absl::optional<T>();
+    return std::optional<T>();
   auto parsed = ParseTypedParameter<T>(str);
   if (parsed.has_value())
     return parsed;
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 template <>
-absl::optional<bool> ParseTypedParameter<bool>(absl::string_view str);
+std::optional<bool> ParseTypedParameter<bool>(absl::string_view str);
 template <>
-absl::optional<double> ParseTypedParameter<double>(absl::string_view str);
+std::optional<double> ParseTypedParameter<double>(absl::string_view str);
 template <>
-absl::optional<int> ParseTypedParameter<int>(absl::string_view str);
+std::optional<int> ParseTypedParameter<int>(absl::string_view str);
 template <>
-absl::optional<unsigned> ParseTypedParameter<unsigned>(absl::string_view str);
+std::optional<unsigned> ParseTypedParameter<unsigned>(absl::string_view str);
 template <>
-absl::optional<std::string> ParseTypedParameter<std::string>(
+std::optional<std::string> ParseTypedParameter<std::string>(
     absl::string_view str);
 
 template <>
-absl::optional<absl::optional<bool>> ParseTypedParameter<absl::optional<bool>>(
+std::optional<std::optional<bool>> ParseTypedParameter<std::optional<bool>>(
     absl::string_view str);
 template <>
-absl::optional<absl::optional<int>> ParseTypedParameter<absl::optional<int>>(
+std::optional<std::optional<int>> ParseTypedParameter<std::optional<int>>(
     absl::string_view str);
 template <>
-absl::optional<absl::optional<unsigned>>
-ParseTypedParameter<absl::optional<unsigned>>(absl::string_view str);
+std::optional<std::optional<unsigned>>
+ParseTypedParameter<std::optional<unsigned>>(absl::string_view str);
 template <>
-absl::optional<absl::optional<double>>
-ParseTypedParameter<absl::optional<double>>(absl::string_view str);
+std::optional<std::optional<double>> ParseTypedParameter<std::optional<double>>(
+    absl::string_view str);
 
 // Accepts true, false, else parsed with sscanf %i, true if != 0.
 extern template class FieldTrialParameter<bool>;
diff --git a/rtc_base/experiments/field_trial_parser_unittest.cc b/rtc_base/experiments/field_trial_parser_unittest.cc
index 73d1153..9968350 100644
--- a/rtc_base/experiments/field_trial_parser_unittest.cc
+++ b/rtc_base/experiments/field_trial_parser_unittest.cc
@@ -116,8 +116,8 @@
   EXPECT_EQ(exp.hash.Get(), "a80");
 }
 TEST(FieldTrialParserTest, IgnoresOutOfRange) {
-  FieldTrialConstrained<double> low("low", 10, absl::nullopt, 100);
-  FieldTrialConstrained<double> high("high", 10, 5, absl::nullopt);
+  FieldTrialConstrained<double> low("low", 10, std::nullopt, 100);
+  FieldTrialConstrained<double> high("high", 10, 5, std::nullopt);
   ParseFieldTrial({&low, &high}, "low:1000,high:0");
   EXPECT_EQ(low.Get(), 10);
   EXPECT_EQ(high.Get(), 10);
@@ -141,7 +141,7 @@
   EXPECT_EQ(req.Get(), 30);
 }
 TEST(FieldTrialParserTest, ParsesOptionalParameters) {
-  FieldTrialOptional<int> max_count("c", absl::nullopt);
+  FieldTrialOptional<int> max_count("c", std::nullopt);
   ParseFieldTrial({&max_count}, "");
   EXPECT_FALSE(max_count.GetOptional().has_value());
   ParseFieldTrial({&max_count}, "c:10");
@@ -153,7 +153,7 @@
   ParseFieldTrial({&max_count}, "c:");
   EXPECT_EQ(max_count.GetOptional().value(), 20);
 
-  FieldTrialOptional<unsigned> max_size("c", absl::nullopt);
+  FieldTrialOptional<unsigned> max_size("c", std::nullopt);
   ParseFieldTrial({&max_size}, "");
   EXPECT_FALSE(max_size.GetOptional().has_value());
   ParseFieldTrial({&max_size}, "c:10");
diff --git a/rtc_base/experiments/field_trial_units.cc b/rtc_base/experiments/field_trial_units.cc
index 92af46a..ddb954a 100644
--- a/rtc_base/experiments/field_trial_units.cc
+++ b/rtc_base/experiments/field_trial_units.cc
@@ -12,10 +12,10 @@
 #include <stdio.h>
 
 #include <limits>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 
 // Large enough to fit "seconds", the longest supported unit name.
 #define RTC_TRIAL_UNIT_LENGTH_STR "7"
@@ -29,7 +29,7 @@
   std::string unit;
 };
 
-absl::optional<ValueWithUnit> ParseValueWithUnit(absl::string_view str) {
+std::optional<ValueWithUnit> ParseValueWithUnit(absl::string_view str) {
   if (str == "inf") {
     return ValueWithUnit{std::numeric_limits<double>::infinity(), ""};
   } else if (str == "-inf") {
@@ -43,13 +43,13 @@
       return ValueWithUnit{double_val, unit_char};
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 }  // namespace
 
 template <>
-absl::optional<DataRate> ParseTypedParameter<DataRate>(absl::string_view str) {
-  absl::optional<ValueWithUnit> result = ParseValueWithUnit(str);
+std::optional<DataRate> ParseTypedParameter<DataRate>(absl::string_view str) {
+  std::optional<ValueWithUnit> result = ParseValueWithUnit(str);
   if (result) {
     if (result->unit.empty() || result->unit == "kbps") {
       return DataRate::KilobitsPerSec(result->value);
@@ -57,23 +57,22 @@
       return DataRate::BitsPerSec(result->value);
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 template <>
-absl::optional<DataSize> ParseTypedParameter<DataSize>(absl::string_view str) {
-  absl::optional<ValueWithUnit> result = ParseValueWithUnit(str);
+std::optional<DataSize> ParseTypedParameter<DataSize>(absl::string_view str) {
+  std::optional<ValueWithUnit> result = ParseValueWithUnit(str);
   if (result) {
     if (result->unit.empty() || result->unit == "bytes")
       return DataSize::Bytes(result->value);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 template <>
-absl::optional<TimeDelta> ParseTypedParameter<TimeDelta>(
-    absl::string_view str) {
-  absl::optional<ValueWithUnit> result = ParseValueWithUnit(str);
+std::optional<TimeDelta> ParseTypedParameter<TimeDelta>(absl::string_view str) {
+  std::optional<ValueWithUnit> result = ParseValueWithUnit(str);
   if (result) {
     if (result->unit == "s" || result->unit == "seconds") {
       return TimeDelta::Seconds(result->value);
@@ -83,22 +82,22 @@
       return TimeDelta::Millis(result->value);
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 template <>
-absl::optional<absl::optional<DataRate>>
-ParseTypedParameter<absl::optional<DataRate>>(absl::string_view str) {
+std::optional<std::optional<DataRate>>
+ParseTypedParameter<std::optional<DataRate>>(absl::string_view str) {
   return ParseOptionalParameter<DataRate>(str);
 }
 template <>
-absl::optional<absl::optional<DataSize>>
-ParseTypedParameter<absl::optional<DataSize>>(absl::string_view str) {
+std::optional<std::optional<DataSize>>
+ParseTypedParameter<std::optional<DataSize>>(absl::string_view str) {
   return ParseOptionalParameter<DataSize>(str);
 }
 template <>
-absl::optional<absl::optional<TimeDelta>>
-ParseTypedParameter<absl::optional<TimeDelta>>(absl::string_view str) {
+std::optional<std::optional<TimeDelta>>
+ParseTypedParameter<std::optional<TimeDelta>>(absl::string_view str) {
   return ParseOptionalParameter<TimeDelta>(str);
 }
 
diff --git a/rtc_base/experiments/field_trial_units.h b/rtc_base/experiments/field_trial_units.h
index 408367c..0bab5fe 100644
--- a/rtc_base/experiments/field_trial_units.h
+++ b/rtc_base/experiments/field_trial_units.h
@@ -19,11 +19,11 @@
 namespace webrtc {
 
 template <>
-absl::optional<DataRate> ParseTypedParameter<DataRate>(absl::string_view str);
+std::optional<DataRate> ParseTypedParameter<DataRate>(absl::string_view str);
 template <>
-absl::optional<DataSize> ParseTypedParameter<DataSize>(absl::string_view str);
+std::optional<DataSize> ParseTypedParameter<DataSize>(absl::string_view str);
 template <>
-absl::optional<TimeDelta> ParseTypedParameter<TimeDelta>(absl::string_view str);
+std::optional<TimeDelta> ParseTypedParameter<TimeDelta>(absl::string_view str);
 
 extern template class FieldTrialParameter<DataRate>;
 extern template class FieldTrialParameter<DataSize>;
diff --git a/rtc_base/experiments/field_trial_units_unittest.cc b/rtc_base/experiments/field_trial_units_unittest.cc
index 8996663..82ef580 100644
--- a/rtc_base/experiments/field_trial_units_unittest.cc
+++ b/rtc_base/experiments/field_trial_units_unittest.cc
@@ -9,10 +9,10 @@
  */
 #include "rtc_base/experiments/field_trial_units.h"
 
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "rtc_base/experiments/field_trial_parser.h"
 #include "test/gtest.h"
 
@@ -24,7 +24,7 @@
   FieldTrialParameter<TimeDelta> period =
       FieldTrialParameter<TimeDelta>("p", TimeDelta::Millis(100));
   FieldTrialOptional<DataSize> max_buffer =
-      FieldTrialOptional<DataSize>("b", absl::nullopt);
+      FieldTrialOptional<DataSize>("b", std::nullopt);
 
   explicit DummyExperiment(absl::string_view field_trial) {
     ParseFieldTrial({&target_rate, &max_buffer, &period}, field_trial);
diff --git a/rtc_base/experiments/keyframe_interval_settings.cc b/rtc_base/experiments/keyframe_interval_settings.cc
index df31d29..760870b 100644
--- a/rtc_base/experiments/keyframe_interval_settings.cc
+++ b/rtc_base/experiments/keyframe_interval_settings.cc
@@ -27,8 +27,7 @@
                   key_value_config.Lookup(kFieldTrialName));
 }
 
-absl::optional<int> KeyframeIntervalSettings::MinKeyframeSendIntervalMs()
-    const {
+std::optional<int> KeyframeIntervalSettings::MinKeyframeSendIntervalMs() const {
   return min_keyframe_send_interval_ms_.GetOptional();
 }
 }  // namespace webrtc
diff --git a/rtc_base/experiments/keyframe_interval_settings.h b/rtc_base/experiments/keyframe_interval_settings.h
index df1f679..a9c1971 100644
--- a/rtc_base/experiments/keyframe_interval_settings.h
+++ b/rtc_base/experiments/keyframe_interval_settings.h
@@ -11,7 +11,8 @@
 #ifndef RTC_BASE_EXPERIMENTS_KEYFRAME_INTERVAL_SETTINGS_H_
 #define RTC_BASE_EXPERIMENTS_KEYFRAME_INTERVAL_SETTINGS_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/field_trials_view.h"
 #include "rtc_base/experiments/field_trial_parser.h"
 
@@ -26,7 +27,7 @@
 
   // Sender side.
   // The encoded keyframe send rate is <= 1/MinKeyframeSendIntervalMs().
-  absl::optional<int> MinKeyframeSendIntervalMs() const;
+  std::optional<int> MinKeyframeSendIntervalMs() const;
 
  private:
   FieldTrialOptional<int> min_keyframe_send_interval_ms_;
diff --git a/rtc_base/experiments/min_video_bitrate_experiment.cc b/rtc_base/experiments/min_video_bitrate_experiment.cc
index 179d4db..dd216b8 100644
--- a/rtc_base/experiments/min_video_bitrate_experiment.cc
+++ b/rtc_base/experiments/min_video_bitrate_experiment.cc
@@ -26,20 +26,20 @@
     "WebRTC-VP8-Forced-Fallback-Encoder-v2";
 const char kMinVideoBitrateExperiment[] = "WebRTC-Video-MinVideoBitrate";
 
-absl::optional<int> GetFallbackMinBpsFromFieldTrial(
+std::optional<int> GetFallbackMinBpsFromFieldTrial(
     const FieldTrialsView& field_trials,
     VideoCodecType type) {
   if (type != kVideoCodecVP8) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (!field_trials.IsEnabled(kForcedFallbackFieldTrial)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   const std::string group = field_trials.Lookup(kForcedFallbackFieldTrial);
   if (group.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   int min_pixels;  // Ignored.
@@ -47,21 +47,21 @@
   int min_bps;
   if (sscanf(group.c_str(), "Enabled-%d,%d,%d", &min_pixels, &max_pixels,
              &min_bps) != 3) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (min_bps <= 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return min_bps;
 }
 }  // namespace
 
-absl::optional<DataRate> GetExperimentalMinVideoBitrate(
+std::optional<DataRate> GetExperimentalMinVideoBitrate(
     const FieldTrialsView& field_trials,
     VideoCodecType type) {
-  const absl::optional<int> fallback_min_bitrate_bps =
+  const std::optional<int> fallback_min_bitrate_bps =
       GetFallbackMinBpsFromFieldTrial(field_trials, type);
   if (fallback_min_bitrate_bps) {
     return DataRate::BitsPerSec(*fallback_min_bitrate_bps);
@@ -106,13 +106,13 @@
       case kVideoCodecH264:
         return min_bitrate_h264.GetOptional();
       case kVideoCodecGeneric:
-        return absl::nullopt;
+        return std::nullopt;
     }
 
     RTC_DCHECK_NOTREACHED();
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace webrtc
diff --git a/rtc_base/experiments/min_video_bitrate_experiment.h b/rtc_base/experiments/min_video_bitrate_experiment.h
index ac1335f..af6acb3 100644
--- a/rtc_base/experiments/min_video_bitrate_experiment.h
+++ b/rtc_base/experiments/min_video_bitrate_experiment.h
@@ -11,7 +11,8 @@
 #ifndef RTC_BASE_EXPERIMENTS_MIN_VIDEO_BITRATE_EXPERIMENT_H_
 #define RTC_BASE_EXPERIMENTS_MIN_VIDEO_BITRATE_EXPERIMENT_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/field_trials_view.h"
 #include "api/units/data_rate.h"
 #include "api/video/video_codec_type.h"
@@ -22,7 +23,7 @@
 
 // Return the experiment-driven minimum video bitrate.
 // If no experiment is effective, returns nullopt.
-absl::optional<DataRate> GetExperimentalMinVideoBitrate(
+std::optional<DataRate> GetExperimentalMinVideoBitrate(
     const FieldTrialsView& field_trials,
     VideoCodecType type);
 
diff --git a/rtc_base/experiments/min_video_bitrate_experiment_unittest.cc b/rtc_base/experiments/min_video_bitrate_experiment_unittest.cc
index b8a5809..182669d 100644
--- a/rtc_base/experiments/min_video_bitrate_experiment_unittest.cc
+++ b/rtc_base/experiments/min_video_bitrate_experiment_unittest.cc
@@ -10,7 +10,8 @@
 
 #include "rtc_base/experiments/min_video_bitrate_experiment.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/data_rate.h"
 #include "api/video/video_codec_type.h"
 #include "test/explicit_key_value_config.h"
@@ -26,13 +27,13 @@
   ExplicitKeyValueConfig field_trials("");
 
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecGeneric),
-            absl::nullopt);
+            std::nullopt);
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP8),
-            absl::nullopt);
+            std::nullopt);
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP9),
-            absl::nullopt);
+            std::nullopt);
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecH264),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(GetExperimentalMinVideoBitrateTest,
@@ -41,13 +42,13 @@
       "WebRTC-Video-MinVideoBitrate/Disabled,br:123kbps/");
 
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecGeneric),
-            absl::nullopt);
+            std::nullopt);
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP8),
-            absl::nullopt);
+            std::nullopt);
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP9),
-            absl::nullopt);
+            std::nullopt);
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecH264),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(GetExperimentalMinVideoBitrateTest, BrForAllCodecsIfDefined) {
@@ -86,13 +87,13 @@
       "Disabled,vp8_br:100kbps,vp9_br:200kbps,h264_br:300kbps/");
 
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecGeneric),
-            absl::nullopt);
+            std::nullopt);
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP8),
-            absl::nullopt);
+            std::nullopt);
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP9),
-            absl::nullopt);
+            std::nullopt);
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecH264),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(GetExperimentalMinVideoBitrateTest, SpecificCodecConfigsUsedIfExpEnabled) {
@@ -101,7 +102,7 @@
       "Enabled,vp8_br:100kbps,vp9_br:200kbps,h264_br:300kbps/");
 
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecGeneric),
-            absl::nullopt);
+            std::nullopt);
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP8),
             DataRate::KilobitsPerSec(100));
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP9),
@@ -131,7 +132,7 @@
       "Enabled-444444,555555,666666/");
 
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecGeneric),
-            absl::nullopt);
+            std::nullopt);
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP9),
             DataRate::KilobitsPerSec(200));
   EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecH264),
diff --git a/rtc_base/experiments/normalize_simulcast_size_experiment.cc b/rtc_base/experiments/normalize_simulcast_size_experiment.cc
index 6fe881a..0e54357 100644
--- a/rtc_base/experiments/normalize_simulcast_size_experiment.cc
+++ b/rtc_base/experiments/normalize_simulcast_size_experiment.cc
@@ -24,27 +24,27 @@
 constexpr int kMaxSetting = 5;
 }  // namespace
 
-absl::optional<int> NormalizeSimulcastSizeExperiment::GetBase2Exponent(
+std::optional<int> NormalizeSimulcastSizeExperiment::GetBase2Exponent(
     const FieldTrialsView& field_trials) {
   if (!field_trials.IsEnabled(kFieldTrial))
-    return absl::nullopt;
+    return std::nullopt;
 
   const std::string group = field_trials.Lookup(kFieldTrial);
   if (group.empty())
-    return absl::nullopt;
+    return std::nullopt;
 
   int exponent;
   if (sscanf(group.c_str(), "Enabled-%d", &exponent) != 1) {
     RTC_LOG(LS_WARNING) << "No parameter provided.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (exponent < kMinSetting || exponent > kMaxSetting) {
     RTC_LOG(LS_WARNING) << "Unsupported exp value provided, value ignored.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  return absl::optional<int>(exponent);
+  return std::optional<int>(exponent);
 }
 
 }  // namespace webrtc
diff --git a/rtc_base/experiments/normalize_simulcast_size_experiment.h b/rtc_base/experiments/normalize_simulcast_size_experiment.h
index 3c187f9..79eada1 100644
--- a/rtc_base/experiments/normalize_simulcast_size_experiment.h
+++ b/rtc_base/experiments/normalize_simulcast_size_experiment.h
@@ -11,14 +11,15 @@
 #ifndef RTC_BASE_EXPERIMENTS_NORMALIZE_SIMULCAST_SIZE_EXPERIMENT_H_
 #define RTC_BASE_EXPERIMENTS_NORMALIZE_SIMULCAST_SIZE_EXPERIMENT_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/field_trials_view.h"
 
 namespace webrtc {
 class NormalizeSimulcastSizeExperiment {
  public:
   // Returns the base two exponent from field trial.
-  static absl::optional<int> GetBase2Exponent(
+  static std::optional<int> GetBase2Exponent(
       const FieldTrialsView& field_trials);
 };
 
diff --git a/rtc_base/experiments/quality_scaler_settings.cc b/rtc_base/experiments/quality_scaler_settings.cc
index 24da211..0193a69 100644
--- a/rtc_base/experiments/quality_scaler_settings.cc
+++ b/rtc_base/experiments/quality_scaler_settings.cc
@@ -34,61 +34,61 @@
                   field_trials.Lookup("WebRTC-Video-QualityScalerSettings"));
 }
 
-absl::optional<int> QualityScalerSettings::SamplingPeriodMs() const {
+std::optional<int> QualityScalerSettings::SamplingPeriodMs() const {
   if (sampling_period_ms_ && sampling_period_ms_.Value() <= 0) {
     RTC_LOG(LS_WARNING) << "Unsupported sampling_period_ms value, ignored.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return sampling_period_ms_.GetOptional();
 }
 
-absl::optional<int> QualityScalerSettings::AverageQpWindow() const {
+std::optional<int> QualityScalerSettings::AverageQpWindow() const {
   if (average_qp_window_ && average_qp_window_.Value() <= 0) {
     RTC_LOG(LS_WARNING) << "Unsupported average_qp_window value, ignored.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return average_qp_window_.GetOptional();
 }
 
-absl::optional<int> QualityScalerSettings::MinFrames() const {
+std::optional<int> QualityScalerSettings::MinFrames() const {
   if (min_frames_ && min_frames_.Value() < kMinFrames) {
     RTC_LOG(LS_WARNING) << "Unsupported min_frames value, ignored.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return min_frames_.GetOptional();
 }
 
-absl::optional<double> QualityScalerSettings::InitialScaleFactor() const {
+std::optional<double> QualityScalerSettings::InitialScaleFactor() const {
   if (initial_scale_factor_ &&
       initial_scale_factor_.Value() < kMinScaleFactor) {
     RTC_LOG(LS_WARNING) << "Unsupported initial_scale_factor value, ignored.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return initial_scale_factor_.GetOptional();
 }
 
-absl::optional<double> QualityScalerSettings::ScaleFactor() const {
+std::optional<double> QualityScalerSettings::ScaleFactor() const {
   if (scale_factor_ && scale_factor_.Value() < kMinScaleFactor) {
     RTC_LOG(LS_WARNING) << "Unsupported scale_factor value, ignored.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return scale_factor_.GetOptional();
 }
 
-absl::optional<int> QualityScalerSettings::InitialBitrateIntervalMs() const {
+std::optional<int> QualityScalerSettings::InitialBitrateIntervalMs() const {
   if (initial_bitrate_interval_ms_ &&
       initial_bitrate_interval_ms_.Value() < 0) {
     RTC_LOG(LS_WARNING) << "Unsupported bitrate_interval value, ignored.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return initial_bitrate_interval_ms_.GetOptional();
 }
 
-absl::optional<double> QualityScalerSettings::InitialBitrateFactor() const {
+std::optional<double> QualityScalerSettings::InitialBitrateFactor() const {
   if (initial_bitrate_factor_ &&
       initial_bitrate_factor_.Value() < kMinScaleFactor) {
     RTC_LOG(LS_WARNING) << "Unsupported initial_bitrate_factor value, ignored.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return initial_bitrate_factor_.GetOptional();
 }
diff --git a/rtc_base/experiments/quality_scaler_settings.h b/rtc_base/experiments/quality_scaler_settings.h
index 1085816..428f18f 100644
--- a/rtc_base/experiments/quality_scaler_settings.h
+++ b/rtc_base/experiments/quality_scaler_settings.h
@@ -11,7 +11,8 @@
 #ifndef RTC_BASE_EXPERIMENTS_QUALITY_SCALER_SETTINGS_H_
 #define RTC_BASE_EXPERIMENTS_QUALITY_SCALER_SETTINGS_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/field_trials_view.h"
 #include "rtc_base/experiments/field_trial_parser.h"
 
@@ -21,13 +22,13 @@
  public:
   explicit QualityScalerSettings(const FieldTrialsView& field_trials);
 
-  absl::optional<int> SamplingPeriodMs() const;
-  absl::optional<int> AverageQpWindow() const;
-  absl::optional<int> MinFrames() const;
-  absl::optional<double> InitialScaleFactor() const;
-  absl::optional<double> ScaleFactor() const;
-  absl::optional<int> InitialBitrateIntervalMs() const;
-  absl::optional<double> InitialBitrateFactor() const;
+  std::optional<int> SamplingPeriodMs() const;
+  std::optional<int> AverageQpWindow() const;
+  std::optional<int> MinFrames() const;
+  std::optional<double> InitialScaleFactor() const;
+  std::optional<double> ScaleFactor() const;
+  std::optional<int> InitialBitrateIntervalMs() const;
+  std::optional<double> InitialBitrateFactor() const;
 
  private:
   FieldTrialOptional<int> sampling_period_ms_;
diff --git a/rtc_base/experiments/quality_scaling_experiment.cc b/rtc_base/experiments/quality_scaling_experiment.cc
index ee3d7c0..a5b909e 100644
--- a/rtc_base/experiments/quality_scaling_experiment.cc
+++ b/rtc_base/experiments/quality_scaling_experiment.cc
@@ -32,14 +32,14 @@
     "Enabled-29,95,149,205,24,37,26,36,0.9995,0.9999,1";
 #endif
 
-absl::optional<VideoEncoder::QpThresholds> GetThresholds(int low,
-                                                         int high,
-                                                         int max) {
+std::optional<VideoEncoder::QpThresholds> GetThresholds(int low,
+                                                        int high,
+                                                        int max) {
   if (low < kMinQp || high > max || high < low)
-    return absl::nullopt;
+    return std::nullopt;
 
   RTC_LOG(LS_INFO) << "QP thresholds: low: " << low << ", high: " << high;
-  return absl::optional<VideoEncoder::QpThresholds>(
+  return std::optional<VideoEncoder::QpThresholds>(
       VideoEncoder::QpThresholds(low, high));
 }
 }  // namespace
@@ -52,7 +52,7 @@
 #endif
 }
 
-absl::optional<QualityScalingExperiment::Settings>
+std::optional<QualityScalingExperiment::Settings>
 QualityScalingExperiment::ParseSettings(const FieldTrialsView& field_trials) {
   std::string group = field_trials.Lookup(kFieldTrial);
   // TODO(http://crbug.com/webrtc/12401): Completely remove the experiment code
@@ -67,17 +67,17 @@
              &s.h264_high, &s.generic_low, &s.generic_high, &s.alpha_high,
              &s.alpha_low, &s.drop) != 11) {
     RTC_LOG(LS_WARNING) << "Invalid number of parameters provided.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return s;
 }
 
-absl::optional<VideoEncoder::QpThresholds>
+std::optional<VideoEncoder::QpThresholds>
 QualityScalingExperiment::GetQpThresholds(VideoCodecType codec_type,
                                           const FieldTrialsView& field_trials) {
   const auto settings = ParseSettings(field_trials);
   if (!settings)
-    return absl::nullopt;
+    return std::nullopt;
 
   switch (codec_type) {
     case kVideoCodecVP8:
@@ -92,7 +92,7 @@
       return GetThresholds(settings->generic_low, settings->generic_high,
                            kMaxGenericQp);
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
diff --git a/rtc_base/experiments/quality_scaling_experiment.h b/rtc_base/experiments/quality_scaling_experiment.h
index bd24c06..0d197c1 100644
--- a/rtc_base/experiments/quality_scaling_experiment.h
+++ b/rtc_base/experiments/quality_scaling_experiment.h
@@ -10,7 +10,8 @@
 #ifndef RTC_BASE_EXPERIMENTS_QUALITY_SCALING_EXPERIMENT_H_
 #define RTC_BASE_EXPERIMENTS_QUALITY_SCALING_EXPERIMENT_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/field_trials_view.h"
 #include "api/video_codecs/video_encoder.h"
 
@@ -44,11 +45,11 @@
   static bool Enabled(const FieldTrialsView& field_trials);
 
   // Returns settings from field trial.
-  static absl::optional<Settings> ParseSettings(
+  static std::optional<Settings> ParseSettings(
       const FieldTrialsView& field_trials);
 
   // Returns QpThresholds for the `codec_type`.
-  static absl::optional<VideoEncoder::QpThresholds> GetQpThresholds(
+  static std::optional<VideoEncoder::QpThresholds> GetQpThresholds(
       VideoCodecType codec_type,
       const FieldTrialsView& field_trials);
 
diff --git a/rtc_base/experiments/rate_control_settings.cc b/rtc_base/experiments/rate_control_settings.cc
index 597bc73..2aaf0e1 100644
--- a/rtc_base/experiments/rate_control_settings.cc
+++ b/rtc_base/experiments/rate_control_settings.cc
@@ -110,12 +110,12 @@
       kDefaultMinPushbackTargetBitrateBps);
 }
 
-absl::optional<DataSize>
-RateControlSettings::CongestionWindowInitialDataWindow() const {
+std::optional<DataSize> RateControlSettings::CongestionWindowInitialDataWindow()
+    const {
   return congestion_window_config_.initial_data_window;
 }
 
-absl::optional<double> RateControlSettings::GetPacingFactor() const {
+std::optional<double> RateControlSettings::GetPacingFactor() const {
   return video_config_.pacing_factor;
 }
 
@@ -123,18 +123,18 @@
   return video_config_.alr_probing;
 }
 
-absl::optional<int> RateControlSettings::LibvpxVp8QpMax() const {
+std::optional<int> RateControlSettings::LibvpxVp8QpMax() const {
   if (video_config_.vp8_qp_max &&
       (*video_config_.vp8_qp_max < 0 || *video_config_.vp8_qp_max > 63)) {
     RTC_LOG(LS_WARNING) << "Unsupported vp8_qp_max_ value, ignored.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return video_config_.vp8_qp_max;
 }
 
-absl::optional<int> RateControlSettings::LibvpxVp8MinPixels() const {
+std::optional<int> RateControlSettings::LibvpxVp8MinPixels() const {
   if (video_config_.vp8_min_pixels && *video_config_.vp8_min_pixels < 1) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return video_config_.vp8_min_pixels;
 }
diff --git a/rtc_base/experiments/rate_control_settings.h b/rtc_base/experiments/rate_control_settings.h
index 0dd4a14..d48da1c 100644
--- a/rtc_base/experiments/rate_control_settings.h
+++ b/rtc_base/experiments/rate_control_settings.h
@@ -11,7 +11,8 @@
 #ifndef RTC_BASE_EXPERIMENTS_RATE_CONTROL_SETTINGS_H_
 #define RTC_BASE_EXPERIMENTS_RATE_CONTROL_SETTINGS_H_
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/field_trials_view.h"
 #include "api/units/data_size.h"
 #include "api/video_codecs/video_codec.h"
@@ -22,9 +23,9 @@
 
 struct CongestionWindowConfig {
   static constexpr char kKey[] = "WebRTC-CongestionWindow";
-  absl::optional<int> queue_size_ms;
-  absl::optional<int> min_bitrate_bps;
-  absl::optional<DataSize> initial_data_window;
+  std::optional<int> queue_size_ms;
+  std::optional<int> min_bitrate_bps;
+  std::optional<DataSize> initial_data_window;
   bool drop_frame_only = false;
   std::unique_ptr<StructParametersParser> Parser();
   static CongestionWindowConfig Parse(absl::string_view config);
@@ -32,10 +33,10 @@
 
 struct VideoRateControlConfig {
   static constexpr char kKey[] = "WebRTC-VideoRateControl";
-  absl::optional<double> pacing_factor;
+  std::optional<double> pacing_factor;
   bool alr_probing = false;
-  absl::optional<int> vp8_qp_max;
-  absl::optional<int> vp8_min_pixels;
+  std::optional<int> vp8_qp_max;
+  std::optional<int> vp8_min_pixels;
   bool trust_vp8 = true;
   bool trust_vp9 = true;
   bool bitrate_adjuster = true;
@@ -60,13 +61,13 @@
   bool UseCongestionWindowPushback() const;
   bool UseCongestionWindowDropFrameOnly() const;
   uint32_t CongestionWindowMinPushbackTargetBitrateBps() const;
-  absl::optional<DataSize> CongestionWindowInitialDataWindow() const;
+  std::optional<DataSize> CongestionWindowInitialDataWindow() const;
 
-  absl::optional<double> GetPacingFactor() const;
+  std::optional<double> GetPacingFactor() const;
   bool UseAlrProbing() const;
 
-  absl::optional<int> LibvpxVp8QpMax() const;
-  absl::optional<int> LibvpxVp8MinPixels() const;
+  std::optional<int> LibvpxVp8QpMax() const;
+  std::optional<int> LibvpxVp8MinPixels() const;
   bool LibvpxVp8TrustedRateController() const;
   bool Vp8BoostBaseLayerQuality() const;
   bool Vp8DynamicRateSettings() const;
diff --git a/rtc_base/experiments/struct_parameters_parser.cc b/rtc_base/experiments/struct_parameters_parser.cc
index 011df3e..ffcd0a4 100644
--- a/rtc_base/experiments/struct_parameters_parser.cc
+++ b/rtc_base/experiments/struct_parameters_parser.cc
@@ -48,7 +48,7 @@
 }
 
 template <typename T>
-inline void StringEncode(std::string* sb, absl::optional<T> val) {
+inline void StringEncode(std::string* sb, std::optional<T> val) {
   if (val)
     StringEncode(sb, *val);
 }
@@ -69,16 +69,16 @@
 template class TypedParser<double>;
 template class TypedParser<int>;
 template class TypedParser<unsigned>;
-template class TypedParser<absl::optional<double>>;
-template class TypedParser<absl::optional<int>>;
-template class TypedParser<absl::optional<unsigned>>;
+template class TypedParser<std::optional<double>>;
+template class TypedParser<std::optional<int>>;
+template class TypedParser<std::optional<unsigned>>;
 
 template class TypedParser<DataRate>;
 template class TypedParser<DataSize>;
 template class TypedParser<TimeDelta>;
-template class TypedParser<absl::optional<DataRate>>;
-template class TypedParser<absl::optional<DataSize>>;
-template class TypedParser<absl::optional<TimeDelta>>;
+template class TypedParser<std::optional<DataRate>>;
+template class TypedParser<std::optional<DataSize>>;
+template class TypedParser<std::optional<TimeDelta>>;
 }  // namespace struct_parser_impl
 
 StructParametersParser::StructParametersParser(
diff --git a/rtc_base/experiments/struct_parameters_parser.h b/rtc_base/experiments/struct_parameters_parser.h
index f5f8340..3d0b05b 100644
--- a/rtc_base/experiments/struct_parameters_parser.h
+++ b/rtc_base/experiments/struct_parameters_parser.h
@@ -13,13 +13,13 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "rtc_base/experiments/field_trial_parser.h"
 #include "rtc_base/experiments/field_trial_units.h"
 #include "rtc_base/string_encode.h"
@@ -54,16 +54,16 @@
 extern template class TypedParser<double>;
 extern template class TypedParser<int>;
 extern template class TypedParser<unsigned>;
-extern template class TypedParser<absl::optional<double>>;
-extern template class TypedParser<absl::optional<int>>;
-extern template class TypedParser<absl::optional<unsigned>>;
+extern template class TypedParser<std::optional<double>>;
+extern template class TypedParser<std::optional<int>>;
+extern template class TypedParser<std::optional<unsigned>>;
 
 extern template class TypedParser<DataRate>;
 extern template class TypedParser<DataSize>;
 extern template class TypedParser<TimeDelta>;
-extern template class TypedParser<absl::optional<DataRate>>;
-extern template class TypedParser<absl::optional<DataSize>>;
-extern template class TypedParser<absl::optional<TimeDelta>>;
+extern template class TypedParser<std::optional<DataRate>>;
+extern template class TypedParser<std::optional<DataSize>>;
+extern template class TypedParser<std::optional<TimeDelta>>;
 
 template <typename T>
 void AddMembers(MemberParameter* out, const char* key, T* member) {
diff --git a/rtc_base/experiments/struct_parameters_parser_unittest.cc b/rtc_base/experiments/struct_parameters_parser_unittest.cc
index 0824bd3..918bcb6 100644
--- a/rtc_base/experiments/struct_parameters_parser_unittest.cc
+++ b/rtc_base/experiments/struct_parameters_parser_unittest.cc
@@ -19,8 +19,8 @@
   int retries = 5;
   unsigned size = 3;
   bool ping = 0;
-  absl::optional<TimeDelta> duration;
-  absl::optional<TimeDelta> latency = TimeDelta::Millis(100);
+  std::optional<TimeDelta> duration;
+  std::optional<TimeDelta> latency = TimeDelta::Millis(100);
   std::unique_ptr<StructParametersParser> Parser();
 };
 
diff --git a/rtc_base/fake_network.h b/rtc_base/fake_network.h
index bc03306..b050198 100644
--- a/rtc_base/fake_network.h
+++ b/rtc_base/fake_network.h
@@ -36,7 +36,7 @@
   struct Iface {
     SocketAddress socket_address;
     AdapterType adapter_type;
-    absl::optional<AdapterType> underlying_vpn_adapter_type;
+    std::optional<AdapterType> underlying_vpn_adapter_type;
   };
   typedef std::vector<Iface> IfaceList;
 
@@ -53,7 +53,7 @@
       const SocketAddress& iface,
       absl::string_view if_name,
       AdapterType type,
-      absl::optional<AdapterType> underlying_vpn_adapter_type = absl::nullopt) {
+      std::optional<AdapterType> underlying_vpn_adapter_type = std::nullopt) {
     SocketAddress address(if_name, 0);
     address.SetResolvedIP(iface.ipaddr());
     ifaces_.push_back({address, type, underlying_vpn_adapter_type});
diff --git a/rtc_base/file_rotating_stream.cc b/rtc_base/file_rotating_stream.cc
index c56396f..c1d3bfc 100644
--- a/rtc_base/file_rotating_stream.cc
+++ b/rtc_base/file_rotating_stream.cc
@@ -26,9 +26,10 @@
 #include <unistd.h>
 #endif  // WEBRTC_WIN
 
+#include <optional>
+
 #include "absl/algorithm/container.h"
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/strings/string_builder.h"
@@ -52,7 +53,7 @@
 bool MoveFile(absl::string_view old_file, absl::string_view new_file);
 bool IsFile(absl::string_view file);
 bool IsFolder(absl::string_view file);
-absl::optional<size_t> GetFileSize(absl::string_view file);
+std::optional<size_t> GetFileSize(absl::string_view file);
 
 #if defined(WEBRTC_WIN)
 
@@ -110,11 +111,11 @@
          FILE_ATTRIBUTE_DIRECTORY;
 }
 
-absl::optional<size_t> GetFileSize(absl::string_view file) {
+std::optional<size_t> GetFileSize(absl::string_view file) {
   WIN32_FILE_ATTRIBUTE_DATA data = {0};
   if (::GetFileAttributesExW(ToUtf16(file).c_str(), GetFileExInfoStandard,
                              &data) == 0)
-    return absl::nullopt;
+    return std::nullopt;
   return data.nFileSizeLow;
 }
 
@@ -168,10 +169,10 @@
   return res == 0 && S_ISDIR(st.st_mode);
 }
 
-absl::optional<size_t> GetFileSize(absl::string_view file) {
+std::optional<size_t> GetFileSize(absl::string_view file) {
   struct stat st;
   if (::stat(std::string(file).c_str(), &st) != 0)
-    return absl::nullopt;
+    return std::nullopt;
   return st.st_size;
 }
 
diff --git a/rtc_base/frequency_tracker.cc b/rtc_base/frequency_tracker.cc
index c3be30e..d99c67b 100644
--- a/rtc_base/frequency_tracker.cc
+++ b/rtc_base/frequency_tracker.cc
@@ -10,7 +10,8 @@
 
 #include "rtc_base/frequency_tracker.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/frequency.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -21,11 +22,11 @@
 FrequencyTracker::FrequencyTracker(TimeDelta max_window_size)
     : impl_(max_window_size.ms(), 1'000'000) {}
 
-absl::optional<Frequency> FrequencyTracker::Rate(Timestamp now) const {
-  if (absl::optional<int64_t> rate = impl_.Rate(now.ms())) {
+std::optional<Frequency> FrequencyTracker::Rate(Timestamp now) const {
+  if (std::optional<int64_t> rate = impl_.Rate(now.ms())) {
     return Frequency::MilliHertz(*rate);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void FrequencyTracker::Update(int64_t count, Timestamp now) {
diff --git a/rtc_base/frequency_tracker.h b/rtc_base/frequency_tracker.h
index 3ee2ab0..6039c53 100644
--- a/rtc_base/frequency_tracker.h
+++ b/rtc_base/frequency_tracker.h
@@ -14,7 +14,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/frequency.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -46,7 +47,7 @@
 
   // Returns rate, moving averaging window as needed.
   // Returns nullopt when rate can't be measured.
-  absl::optional<Frequency> Rate(Timestamp now) const;
+  std::optional<Frequency> Rate(Timestamp now) const;
 
  private:
   RateStatistics impl_;
diff --git a/rtc_base/frequency_tracker_unittest.cc b/rtc_base/frequency_tracker_unittest.cc
index 7f0b3d5..af9eeff 100644
--- a/rtc_base/frequency_tracker_unittest.cc
+++ b/rtc_base/frequency_tracker_unittest.cc
@@ -12,8 +12,8 @@
 
 #include <cstdlib>
 #include <limits>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/units/frequency.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -34,7 +34,7 @@
   Timestamp now = Timestamp::Seconds(12'345);
   FrequencyTracker stats(kWindow);
 
-  EXPECT_EQ(stats.Rate(now), absl::nullopt);
+  EXPECT_EQ(stats.Rate(now), std::nullopt);
 }
 
 TEST(FrequencyTrackerTest, ReturnsNulloptAfterSingleDataPoint) {
@@ -44,7 +44,7 @@
   stats.Update(now);
   now += TimeDelta::Millis(10);
 
-  EXPECT_EQ(stats.Rate(now), absl::nullopt);
+  EXPECT_EQ(stats.Rate(now), std::nullopt);
 }
 
 TEST(FrequencyTrackerTest, ReturnsRateAfterTwoMeasurements) {
@@ -76,7 +76,7 @@
 
     // Until window is full, rate is measured over a smaller window and might
     // look larger than the constant rate.
-    absl::optional<Frequency> rate = stats.Rate(now);
+    std::optional<Frequency> rate = stats.Rate(now);
     ASSERT_GE(rate, kConstantRate);
 
     // Expect the estimation error to decrease as the window is extended.
@@ -127,7 +127,7 @@
     now += kLargeInterval;
     stats.Update(kLargeSize, now);
   }
-  absl::optional<Frequency> last_rate = stats.Rate(now);
+  std::optional<Frequency> last_rate = stats.Rate(now);
   EXPECT_EQ(last_rate, kLargeSize / kLargeInterval);
 
   // Decrease rate with smaller measurments.
@@ -136,7 +136,7 @@
     now += kLargeInterval;
     stats.Update(kSmallSize, now);
 
-    absl::optional<Frequency> rate = stats.Rate(now);
+    std::optional<Frequency> rate = stats.Rate(now);
     EXPECT_LT(rate, last_rate);
 
     last_rate = rate;
@@ -149,7 +149,7 @@
     now += kSmallInterval;
     stats.Update(kSmallSize, now);
 
-    absl::optional<Frequency> rate = stats.Rate(now);
+    std::optional<Frequency> rate = stats.Rate(now);
     EXPECT_GE(rate, last_rate);
 
     last_rate = rate;
@@ -174,17 +174,17 @@
 
   now += kWindow + kEpsilon;
   // Silence over window size should trigger auto reset for coming sample.
-  EXPECT_EQ(pixel_rate.Rate(now), absl::nullopt);
+  EXPECT_EQ(pixel_rate.Rate(now), std::nullopt);
   pixel_rate.Update(kPixels, now);
   // Single measurment after reset is not enough to estimate the rate.
-  EXPECT_EQ(pixel_rate.Rate(now), absl::nullopt);
+  EXPECT_EQ(pixel_rate.Rate(now), std::nullopt);
 
   // Manual reset, add the same check again.
   pixel_rate.Reset();
-  EXPECT_EQ(pixel_rate.Rate(now), absl::nullopt);
+  EXPECT_EQ(pixel_rate.Rate(now), std::nullopt);
   now += kInterval;
   pixel_rate.Update(kPixels, now);
-  EXPECT_EQ(pixel_rate.Rate(now), absl::nullopt);
+  EXPECT_EQ(pixel_rate.Rate(now), std::nullopt);
 }
 
 TEST(FrequencyTrackerTest, ReturnsNulloptWhenOverflows) {
@@ -196,7 +196,7 @@
   now += kEpsilon;
   stats.Update(very_large_number, now);
 
-  EXPECT_EQ(stats.Rate(now), absl::nullopt);
+  EXPECT_EQ(stats.Rate(now), std::nullopt);
 }
 
 }  // namespace
diff --git a/rtc_base/logging.h b/rtc_base/logging.h
index b171cfe..3d27d6c 100644
--- a/rtc_base/logging.h
+++ b/rtc_base/logging.h
@@ -51,6 +51,7 @@
 #include <errno.h>
 
 #include <atomic>
+#include <optional>
 #include <sstream>  // no-presubmit-check TODO(webrtc:8982)
 #include <string>
 #include <type_traits>
@@ -59,7 +60,6 @@
 #include "absl/base/attributes.h"
 #include "absl/meta/type_traits.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/units/timestamp.h"
 #include "rtc_base/platform_thread_types.h"
 #include "rtc_base/strings/string_builder.h"
@@ -118,7 +118,7 @@
   absl::string_view message() const { return message_; }
   absl::string_view filename() const { return filename_; }
   int line() const { return line_; }
-  absl::optional<PlatformThreadId> thread_id() const { return thread_id_; }
+  std::optional<PlatformThreadId> thread_id() const { return thread_id_; }
   webrtc::Timestamp timestamp() const { return timestamp_; }
   absl::string_view tag() const { return tag_; }
   LoggingSeverity severity() const { return severity_; }
@@ -134,7 +134,7 @@
   void set_message(std::string message) { message_ = std::move(message); }
   void set_filename(absl::string_view filename) { filename_ = filename; }
   void set_line(int line) { line_ = line; }
-  void set_thread_id(absl::optional<PlatformThreadId> thread_id) {
+  void set_thread_id(std::optional<PlatformThreadId> thread_id) {
     thread_id_ = thread_id;
   }
   void set_timestamp(webrtc::Timestamp timestamp) { timestamp_ = timestamp; }
@@ -144,7 +144,7 @@
   std::string message_;
   absl::string_view filename_;
   int line_ = 0;
-  absl::optional<PlatformThreadId> thread_id_;
+  std::optional<PlatformThreadId> thread_id_;
   webrtc::Timestamp timestamp_ = webrtc::Timestamp::MinusInfinity();
   // The default Android debug output tag.
   absl::string_view tag_ = "libjingle";
diff --git a/rtc_base/network/BUILD.gn b/rtc_base/network/BUILD.gn
index c1e52cd..d4933f2 100644
--- a/rtc_base/network/BUILD.gn
+++ b/rtc_base/network/BUILD.gn
@@ -13,10 +13,7 @@
     "sent_packet.cc",
     "sent_packet.h",
   ]
-  deps = [
-    "../system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
-  ]
+  deps = [ "../system:rtc_export" ]
 }
 
 rtc_source_set("ecn_marking") {
@@ -36,6 +33,5 @@
     "../../api:array_view",
     "../../api/units:timestamp",
     "../system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
diff --git a/rtc_base/network/received_packet.cc b/rtc_base/network/received_packet.cc
index 9588e37..346a17f 100644
--- a/rtc_base/network/received_packet.cc
+++ b/rtc_base/network/received_packet.cc
@@ -10,16 +10,16 @@
 
 #include "rtc_base/network/received_packet.h"
 
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "rtc_base/socket_address.h"
 
 namespace rtc {
 
 ReceivedPacket::ReceivedPacket(rtc::ArrayView<const uint8_t> payload,
                                const SocketAddress& source_address,
-                               absl::optional<webrtc::Timestamp> arrival_time,
+                               std::optional<webrtc::Timestamp> arrival_time,
                                EcnMarking ecn,
                                DecryptionInfo decryption)
     : payload_(payload),
@@ -43,9 +43,9 @@
   RTC_DCHECK(packet_time_us == -1 || packet_time_us >= 0);
   return ReceivedPacket(rtc::MakeArrayView(data, size), source_address,
                         (packet_time_us >= 0)
-                            ? absl::optional<webrtc::Timestamp>(
+                            ? std::optional<webrtc::Timestamp>(
                                   webrtc::Timestamp::Micros(packet_time_us))
-                            : absl::nullopt);
+                            : std::nullopt);
 }
 
 }  // namespace rtc
diff --git a/rtc_base/network/received_packet.h b/rtc_base/network/received_packet.h
index 68dd33b..ec0b0bf 100644
--- a/rtc_base/network/received_packet.h
+++ b/rtc_base/network/received_packet.h
@@ -11,8 +11,8 @@
 #define RTC_BASE_NETWORK_RECEIVED_PACKET_H_
 
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/units/timestamp.h"
 #include "rtc_base/network/ecn_marking.h"
@@ -38,7 +38,7 @@
   // lifetime of this ReceivedPacket.
   ReceivedPacket(rtc::ArrayView<const uint8_t> payload,
                  const SocketAddress& source_address,
-                 absl::optional<webrtc::Timestamp> arrival_time = absl::nullopt,
+                 std::optional<webrtc::Timestamp> arrival_time = std::nullopt,
                  EcnMarking ecn = EcnMarking::kNotEct,
                  DecryptionInfo decryption = kNotDecrypted);
 
@@ -50,7 +50,7 @@
 
   // Timestamp when this packet was received. Not available on all socket
   // implementations.
-  absl::optional<webrtc::Timestamp> arrival_time() const {
+  std::optional<webrtc::Timestamp> arrival_time() const {
     return arrival_time_;
   }
 
@@ -76,7 +76,7 @@
 
  private:
   rtc::ArrayView<const uint8_t> payload_;
-  absl::optional<webrtc::Timestamp> arrival_time_;
+  std::optional<webrtc::Timestamp> arrival_time_;
   const SocketAddress& source_address_;
   EcnMarking ecn_;
   DecryptionInfo decryption_info_;
diff --git a/rtc_base/network/sent_packet.h b/rtc_base/network/sent_packet.h
index 457fb96..3e6f0d0 100644
--- a/rtc_base/network/sent_packet.h
+++ b/rtc_base/network/sent_packet.h
@@ -14,7 +14,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "rtc_base/system/rtc_export.h"
 
 namespace rtc {
@@ -45,8 +46,8 @@
   bool included_in_allocation = false;
   PacketType packet_type = PacketType::kUnknown;
   PacketInfoProtocolType protocol = PacketInfoProtocolType::kUnknown;
-  // A unique id assigned by the network manager, and absl::nullopt if not set.
-  absl::optional<uint16_t> network_id;
+  // A unique id assigned by the network manager, and std::nullopt if not set.
+  std::optional<uint16_t> network_id;
   size_t packet_size_bytes = 0;
   size_t turn_overhead_bytes = 0;
   size_t ip_overhead_bytes = 0;
diff --git a/rtc_base/numerics/event_based_exponential_moving_average.h b/rtc_base/numerics/event_based_exponential_moving_average.h
index 69f4e61..7055a4d 100644
--- a/rtc_base/numerics/event_based_exponential_moving_average.h
+++ b/rtc_base/numerics/event_based_exponential_moving_average.h
@@ -14,8 +14,7 @@
 #include <cmath>
 #include <cstdint>
 #include <limits>
-
-#include "absl/types/optional.h"
+#include <optional>
 
 namespace rtc {
 
@@ -63,7 +62,7 @@
   double sample_variance_ = std::numeric_limits<double>::infinity();
   // This is the ratio between variance of the estimate and variance of samples.
   double estimator_variance_ = 1;
-  absl::optional<int64_t> last_observation_timestamp_;
+  std::optional<int64_t> last_observation_timestamp_;
 };
 
 }  // namespace rtc
diff --git a/rtc_base/numerics/histogram_percentile_counter.cc b/rtc_base/numerics/histogram_percentile_counter.cc
index 498bb4b..28f9174 100644
--- a/rtc_base/numerics/histogram_percentile_counter.cc
+++ b/rtc_base/numerics/histogram_percentile_counter.cc
@@ -14,8 +14,8 @@
 #include <cmath>
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 
 namespace rtc {
@@ -51,12 +51,12 @@
   Add(value, 1);
 }
 
-absl::optional<uint32_t> HistogramPercentileCounter::GetPercentile(
+std::optional<uint32_t> HistogramPercentileCounter::GetPercentile(
     float fraction) {
   RTC_CHECK_LE(fraction, 1.0);
   RTC_CHECK_GE(fraction, 0.0);
   if (total_elements_ == 0)
-    return absl::nullopt;
+    return std::nullopt;
   size_t elements_to_skip = static_cast<size_t>(
       std::max(0.0f, std::ceil(total_elements_ * fraction) - 1));
   if (elements_to_skip >= total_elements_)
@@ -76,7 +76,7 @@
     }
   }
   RTC_DCHECK_NOTREACHED();
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace rtc
diff --git a/rtc_base/numerics/histogram_percentile_counter.h b/rtc_base/numerics/histogram_percentile_counter.h
index 4787f2e..327ce0d 100644
--- a/rtc_base/numerics/histogram_percentile_counter.h
+++ b/rtc_base/numerics/histogram_percentile_counter.h
@@ -15,10 +15,9 @@
 #include <stdint.h>
 
 #include <map>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
-
 namespace rtc {
 // Calculates percentiles on the stream of data. Use `Add` methods to add new
 // values. Use `GetPercentile` to get percentile of the currently added values.
@@ -32,7 +31,7 @@
   void Add(uint32_t value, size_t count);
   void Add(const HistogramPercentileCounter& other);
   // Argument should be from 0 to 1.
-  absl::optional<uint32_t> GetPercentile(float fraction);
+  std::optional<uint32_t> GetPercentile(float fraction);
 
  private:
   std::vector<size_t> histogram_low_;
diff --git a/rtc_base/numerics/moving_average.cc b/rtc_base/numerics/moving_average.cc
index 126223e..f91926f 100644
--- a/rtc_base/numerics/moving_average.cc
+++ b/rtc_base/numerics/moving_average.cc
@@ -13,8 +13,8 @@
 #include <algorithm>
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 
 namespace rtc {
@@ -34,21 +34,21 @@
   history_[index] = sample;
 }
 
-absl::optional<int> MovingAverage::GetAverageRoundedDown() const {
+std::optional<int> MovingAverage::GetAverageRoundedDown() const {
   if (count_ == 0)
-    return absl::nullopt;
+    return std::nullopt;
   return sum_ / Size();
 }
 
-absl::optional<int> MovingAverage::GetAverageRoundedToClosest() const {
+std::optional<int> MovingAverage::GetAverageRoundedToClosest() const {
   if (count_ == 0)
-    return absl::nullopt;
+    return std::nullopt;
   return (sum_ + Size() / 2) / Size();
 }
 
-absl::optional<double> MovingAverage::GetUnroundedAverage() const {
+std::optional<double> MovingAverage::GetUnroundedAverage() const {
   if (count_ == 0)
-    return absl::nullopt;
+    return std::nullopt;
   return sum_ / static_cast<double>(Size());
 }
 
diff --git a/rtc_base/numerics/moving_average.h b/rtc_base/numerics/moving_average.h
index 41ce603..f9aa8ee 100644
--- a/rtc_base/numerics/moving_average.h
+++ b/rtc_base/numerics/moving_average.h
@@ -14,10 +14,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
-
 namespace rtc {
 
 // Calculates average over fixed size window. If there are less than window
@@ -38,13 +37,13 @@
   // Returns rounded down average of last `window_size` elements or all
   // elements if there are not enough of them. Returns nullopt if there were
   // no elements added.
-  absl::optional<int> GetAverageRoundedDown() const;
+  std::optional<int> GetAverageRoundedDown() const;
 
   // Same as above but rounded to the closest integer.
-  absl::optional<int> GetAverageRoundedToClosest() const;
+  std::optional<int> GetAverageRoundedToClosest() const;
 
   // Returns unrounded average over the window.
-  absl::optional<double> GetUnroundedAverage() const;
+  std::optional<double> GetUnroundedAverage() const;
 
   // Resets to the initial state before any elements were added.
   void Reset();
diff --git a/rtc_base/numerics/moving_average_unittest.cc b/rtc_base/numerics/moving_average_unittest.cc
index 5993401..163a778 100644
--- a/rtc_base/numerics/moving_average_unittest.cc
+++ b/rtc_base/numerics/moving_average_unittest.cc
@@ -10,7 +10,8 @@
 
 #include "rtc_base/numerics/moving_average.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "test/gtest.h"
 
 namespace test {
@@ -18,7 +19,7 @@
 TEST(MovingAverageTest, EmptyAverage) {
   rtc::MovingAverage moving_average(1);
   EXPECT_EQ(0u, moving_average.Size());
-  EXPECT_EQ(absl::nullopt, moving_average.GetAverageRoundedDown());
+  EXPECT_EQ(std::nullopt, moving_average.GetAverageRoundedDown());
 }
 
 // Test single value.
diff --git a/rtc_base/numerics/moving_max_counter.h b/rtc_base/numerics/moving_max_counter.h
index 5eb45d39..f35d360 100644
--- a/rtc_base/numerics/moving_max_counter.h
+++ b/rtc_base/numerics/moving_max_counter.h
@@ -15,9 +15,9 @@
 
 #include <deque>
 #include <limits>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 
 namespace rtc {
@@ -43,7 +43,7 @@
   // Advances the current time, and returns the maximum sample in the time
   // window ending at the current time. The new current time must be at least as
   // large as the old current time.
-  absl::optional<T> Max(int64_t current_time_ms);
+  std::optional<T> Max(int64_t current_time_ms);
   void Reset();
 
  private:
@@ -85,9 +85,9 @@
 }
 
 template <class T>
-absl::optional<T> MovingMaxCounter<T>::Max(int64_t current_time_ms) {
+std::optional<T> MovingMaxCounter<T>::Max(int64_t current_time_ms) {
   RollWindow(current_time_ms);
-  absl::optional<T> res;
+  std::optional<T> res;
   if (!samples_.empty()) {
     res.emplace(samples_.front().second);
   }
diff --git a/rtc_base/numerics/running_statistics.h b/rtc_base/numerics/running_statistics.h
index 134b895..c747c79 100644
--- a/rtc_base/numerics/running_statistics.h
+++ b/rtc_base/numerics/running_statistics.h
@@ -14,8 +14,8 @@
 #include <algorithm>
 #include <cmath>
 #include <cstdint>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/math_utils.h"
 
@@ -33,7 +33,7 @@
 // If you want a full-fledged moving window over N last samples,
 // please use webrtc::RollingAccumulator.
 //
-// The measures return absl::nullopt if no samples were fed (Size() == 0),
+// The measures return std::nullopt if no samples were fed (Size() == 0),
 // otherwise the returned optional is guaranteed to contain a value.
 //
 // [1]
@@ -108,50 +108,50 @@
 
   // Returns minimum among all seen samples, in O(1) time.
   // This isn't affected by RemoveSample().
-  absl::optional<T> GetMin() const {
+  std::optional<T> GetMin() const {
     if (size_ == 0) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return min_;
   }
 
   // Returns maximum among all seen samples, in O(1) time.
   // This isn't affected by RemoveSample().
-  absl::optional<T> GetMax() const {
+  std::optional<T> GetMax() const {
     if (size_ == 0) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return max_;
   }
 
   // Returns sum in O(1) time.
-  absl::optional<double> GetSum() const {
+  std::optional<double> GetSum() const {
     if (size_ == 0) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return sum_;
   }
 
   // Returns mean in O(1) time.
-  absl::optional<double> GetMean() const {
+  std::optional<double> GetMean() const {
     if (size_ == 0) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return mean_;
   }
 
   // Returns unbiased sample variance in O(1) time.
-  absl::optional<double> GetVariance() const {
+  std::optional<double> GetVariance() const {
     if (size_ == 0) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return cumul_ / size_;
   }
 
   // Returns unbiased standard deviation in O(1) time.
-  absl::optional<double> GetStandardDeviation() const {
+  std::optional<double> GetStandardDeviation() const {
     if (size_ == 0) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return std::sqrt(*GetVariance());
   }
diff --git a/rtc_base/numerics/sample_counter.cc b/rtc_base/numerics/sample_counter.cc
index 5e63b97..50e9f2a 100644
--- a/rtc_base/numerics/sample_counter.cc
+++ b/rtc_base/numerics/sample_counter.cc
@@ -12,8 +12,8 @@
 
 #include <cstdint>
 #include <limits>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_conversions.h"
 
@@ -54,25 +54,25 @@
     min_ = other.min_;
 }
 
-absl::optional<int> SampleCounter::Avg(int64_t min_required_samples) const {
+std::optional<int> SampleCounter::Avg(int64_t min_required_samples) const {
   RTC_DCHECK_GT(min_required_samples, 0);
   if (num_samples_ < min_required_samples)
-    return absl::nullopt;
+    return std::nullopt;
   return rtc::dchecked_cast<int>(sum_ / num_samples_);
 }
 
-absl::optional<int> SampleCounter::Max() const {
+std::optional<int> SampleCounter::Max() const {
   return max_;
 }
 
-absl::optional<int> SampleCounter::Min() const {
+std::optional<int> SampleCounter::Min() const {
   return min_;
 }
 
-absl::optional<int64_t> SampleCounter::Sum(int64_t min_required_samples) const {
+std::optional<int64_t> SampleCounter::Sum(int64_t min_required_samples) const {
   RTC_DCHECK_GT(min_required_samples, 0);
   if (num_samples_ < min_required_samples)
-    return absl::nullopt;
+    return std::nullopt;
   return sum_;
 }
 
@@ -87,11 +87,11 @@
 SampleCounterWithVariance::SampleCounterWithVariance() = default;
 SampleCounterWithVariance::~SampleCounterWithVariance() = default;
 
-absl::optional<int64_t> SampleCounterWithVariance::Variance(
+std::optional<int64_t> SampleCounterWithVariance::Variance(
     int64_t min_required_samples) const {
   RTC_DCHECK_GT(min_required_samples, 0);
   if (num_samples_ < min_required_samples)
-    return absl::nullopt;
+    return std::nullopt;
   // E[(x-mean)^2] = E[x^2] - mean^2
   int64_t mean = sum_ / num_samples_;
   return sum_squared_ / num_samples_ - mean * mean;
diff --git a/rtc_base/numerics/sample_counter.h b/rtc_base/numerics/sample_counter.h
index 2b41f95..fa58ce1 100644
--- a/rtc_base/numerics/sample_counter.h
+++ b/rtc_base/numerics/sample_counter.h
@@ -13,7 +13,7 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
 
 namespace rtc {
 
@@ -24,10 +24,10 @@
   SampleCounter();
   ~SampleCounter();
   void Add(int sample);
-  absl::optional<int> Avg(int64_t min_required_samples) const;
-  absl::optional<int> Max() const;
-  absl::optional<int> Min() const;
-  absl::optional<int64_t> Sum(int64_t min_required_samples) const;
+  std::optional<int> Avg(int64_t min_required_samples) const;
+  std::optional<int> Max() const;
+  std::optional<int> Min() const;
+  std::optional<int64_t> Sum(int64_t min_required_samples) const;
   int64_t NumSamples() const;
   void Reset();
   // Adds all the samples from the `other` SampleCounter as if they were all
@@ -37,8 +37,8 @@
  protected:
   int64_t sum_ = 0;
   int64_t num_samples_ = 0;
-  absl::optional<int> max_;
-  absl::optional<int> min_;
+  std::optional<int> max_;
+  std::optional<int> min_;
 };
 
 class SampleCounterWithVariance : public SampleCounter {
@@ -46,7 +46,7 @@
   SampleCounterWithVariance();
   ~SampleCounterWithVariance();
   void Add(int sample);
-  absl::optional<int64_t> Variance(int64_t min_required_samples) const;
+  std::optional<int64_t> Variance(int64_t min_required_samples) const;
   void Reset();
   // Adds all the samples from the `other` SampleCounter as if they were all
   // individually added using `Add(int)` method.
diff --git a/rtc_base/numerics/sample_counter_unittest.cc b/rtc_base/numerics/sample_counter_unittest.cc
index 6877f5e..82e61fd 100644
--- a/rtc_base/numerics/sample_counter_unittest.cc
+++ b/rtc_base/numerics/sample_counter_unittest.cc
@@ -11,8 +11,8 @@
 #include "rtc_base/numerics/sample_counter.h"
 
 #include <initializer_list>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
 
@@ -23,9 +23,9 @@
 TEST(SampleCounterTest, ProcessesNoSamples) {
   constexpr int kMinSamples = 1;
   SampleCounter counter;
-  EXPECT_THAT(counter.Avg(kMinSamples), Eq(absl::nullopt));
-  EXPECT_THAT(counter.Max(), Eq(absl::nullopt));
-  EXPECT_THAT(counter.Min(), Eq(absl::nullopt));
+  EXPECT_THAT(counter.Avg(kMinSamples), Eq(std::nullopt));
+  EXPECT_THAT(counter.Max(), Eq(std::nullopt));
+  EXPECT_THAT(counter.Min(), Eq(std::nullopt));
 }
 
 TEST(SampleCounterTest, NotEnoughSamples) {
@@ -34,8 +34,8 @@
   for (int value : {1, 2, 3, 4, 5}) {
     counter.Add(value);
   }
-  EXPECT_THAT(counter.Avg(kMinSamples), Eq(absl::nullopt));
-  EXPECT_THAT(counter.Sum(kMinSamples), Eq(absl::nullopt));
+  EXPECT_THAT(counter.Avg(kMinSamples), Eq(std::nullopt));
+  EXPECT_THAT(counter.Sum(kMinSamples), Eq(std::nullopt));
   EXPECT_THAT(counter.Max(), Eq(5));
   EXPECT_THAT(counter.Min(), Eq(1));
 }
@@ -72,8 +72,8 @@
     counter2.Add(value);
   }
   // Before aggregation there is not enough samples.
-  EXPECT_THAT(counter1.Avg(kMinSamples), Eq(absl::nullopt));
-  EXPECT_THAT(counter1.Variance(kMinSamples), Eq(absl::nullopt));
+  EXPECT_THAT(counter1.Avg(kMinSamples), Eq(std::nullopt));
+  EXPECT_THAT(counter1.Variance(kMinSamples), Eq(std::nullopt));
   // Aggregate counter2 in counter1.
   counter1.Add(counter2);
   EXPECT_THAT(counter1.Avg(kMinSamples), Eq(3));
diff --git a/rtc_base/numerics/sequence_number_unwrapper.h b/rtc_base/numerics/sequence_number_unwrapper.h
index fb21283..1def581 100644
--- a/rtc_base/numerics/sequence_number_unwrapper.h
+++ b/rtc_base/numerics/sequence_number_unwrapper.h
@@ -14,9 +14,9 @@
 #include <stdint.h>
 
 #include <limits>
+#include <optional>
 #include <type_traits>
 
-#include "absl/types/optional.h"
 #include "rtc_base/numerics/sequence_number_util.h"
 
 namespace webrtc {
@@ -70,7 +70,7 @@
   }
 
   int64_t last_unwrapped_ = 0;
-  absl::optional<T> last_value_;
+  std::optional<T> last_value_;
 };
 
 using RtpTimestampUnwrapper = SeqNumUnwrapper<uint32_t>;
diff --git a/rtc_base/openssl_stream_adapter.h b/rtc_base/openssl_stream_adapter.h
index 2116b2d..92e8c10 100644
--- a/rtc_base/openssl_stream_adapter.h
+++ b/rtc_base/openssl_stream_adapter.h
@@ -16,12 +16,12 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/functional/any_invocable.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "rtc_base/buffer.h"
 #ifdef OPENSSL_IS_BORINGSSL
 #include "rtc_base/boringssl_identity.h"
diff --git a/rtc_base/operations_chain.h b/rtc_base/operations_chain.h
index 0e8c068..012f3dd 100644
--- a/rtc_base/operations_chain.h
+++ b/rtc_base/operations_chain.h
@@ -13,12 +13,12 @@
 
 #include <functional>
 #include <memory>
+#include <optional>
 #include <queue>
 #include <set>
 #include <type_traits>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/ref_counted_base.h"
 #include "api/scoped_refptr.h"
 #include "api/sequence_checker.h"
@@ -194,7 +194,7 @@
   // to it.
   std::queue<std::unique_ptr<rtc_operations_chain_internal::Operation>>
       chained_operations_ RTC_GUARDED_BY(sequence_checker_);
-  absl::optional<std::function<void()>> on_chain_empty_callback_
+  std::optional<std::function<void()>> on_chain_empty_callback_
       RTC_GUARDED_BY(sequence_checker_);
 };
 
diff --git a/rtc_base/platform_thread.cc b/rtc_base/platform_thread.cc
index 6433323..6af1f3f 100644
--- a/rtc_base/platform_thread.cc
+++ b/rtc_base/platform_thread.cc
@@ -113,14 +113,14 @@
 
 PlatformThread::PlatformThread(PlatformThread&& rhs)
     : handle_(rhs.handle_), joinable_(rhs.joinable_) {
-  rhs.handle_ = absl::nullopt;
+  rhs.handle_ = std::nullopt;
 }
 
 PlatformThread& PlatformThread::operator=(PlatformThread&& rhs) {
   Finalize();
   handle_ = rhs.handle_;
   joinable_ = rhs.joinable_;
-  rhs.handle_ = absl::nullopt;
+  rhs.handle_ = std::nullopt;
   return *this;
 }
 
@@ -144,7 +144,7 @@
                      /*joinable=*/false);
 }
 
-absl::optional<PlatformThread::Handle> PlatformThread::GetHandle() const {
+std::optional<PlatformThread::Handle> PlatformThread::GetHandle() const {
   return handle_;
 }
 
@@ -167,7 +167,7 @@
   if (joinable_)
     RTC_CHECK_EQ(0, pthread_join(*handle_, nullptr));
 #endif
-  handle_ = absl::nullopt;
+  handle_ = std::nullopt;
 }
 
 PlatformThread PlatformThread::SpawnThread(
diff --git a/rtc_base/platform_thread.h b/rtc_base/platform_thread.h
index befd618..cfc9d17 100644
--- a/rtc_base/platform_thread.h
+++ b/rtc_base/platform_thread.h
@@ -17,8 +17,9 @@
 #include <pthread.h>
 #endif
 
+#include <optional>
+
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "rtc_base/platform_thread_types.h"
 
 namespace rtc {
@@ -97,7 +98,7 @@
       ThreadAttributes attributes = ThreadAttributes());
 
   // Returns the base platform thread handle of this thread.
-  absl::optional<Handle> GetHandle() const;
+  std::optional<Handle> GetHandle() const;
 
 #if defined(WEBRTC_WIN)
   // Queue a Windows APC function that runs when the thread is alertable.
@@ -111,7 +112,7 @@
                                     ThreadAttributes attributes,
                                     bool joinable);
 
-  absl::optional<Handle> handle_;
+  std::optional<Handle> handle_;
   bool joinable_ = false;
 };
 
diff --git a/rtc_base/platform_thread_unittest.cc b/rtc_base/platform_thread_unittest.cc
index 97b25e0..be4417a 100644
--- a/rtc_base/platform_thread_unittest.cc
+++ b/rtc_base/platform_thread_unittest.cc
@@ -10,7 +10,8 @@
 
 #include "rtc_base/platform_thread.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "rtc_base/event.h"
 #include "system_wrappers/include/sleep.h"
 #include "test/gmock.h"
@@ -19,13 +20,13 @@
 
 TEST(PlatformThreadTest, DefaultConstructedIsEmpty) {
   PlatformThread thread;
-  EXPECT_EQ(thread.GetHandle(), absl::nullopt);
+  EXPECT_EQ(thread.GetHandle(), std::nullopt);
   EXPECT_TRUE(thread.empty());
 }
 
 TEST(PlatformThreadTest, StartFinalize) {
   PlatformThread thread = PlatformThread::SpawnJoinable([] {}, "1");
-  EXPECT_NE(thread.GetHandle(), absl::nullopt);
+  EXPECT_NE(thread.GetHandle(), std::nullopt);
   EXPECT_FALSE(thread.empty());
   thread.Finalize();
   EXPECT_TRUE(thread.empty());
diff --git a/rtc_base/rate_limiter.cc b/rtc_base/rate_limiter.cc
index 0f3f343..26e1c30 100644
--- a/rtc_base/rate_limiter.cc
+++ b/rtc_base/rate_limiter.cc
@@ -11,8 +11,8 @@
 #include "rtc_base/rate_limiter.h"
 
 #include <limits>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "system_wrappers/include/clock.h"
 
 namespace webrtc {
@@ -33,7 +33,7 @@
 bool RateLimiter::TryUseRate(size_t packet_size_bytes) {
   MutexLock lock(&lock_);
   int64_t now_ms = clock_->TimeInMilliseconds();
-  absl::optional<uint32_t> current_rate = current_rate_.Rate(now_ms);
+  std::optional<uint32_t> current_rate = current_rate_.Rate(now_ms);
   if (current_rate) {
     // If there is a current rate, check if adding bytes would cause maximum
     // bitrate target to be exceeded. If there is NOT a valid current rate,
diff --git a/rtc_base/rate_statistics.cc b/rtc_base/rate_statistics.cc
index 5c83796..401ca24 100644
--- a/rtc_base/rate_statistics.cc
+++ b/rtc_base/rate_statistics.cc
@@ -84,7 +84,7 @@
   ++num_samples_;
 }
 
-absl::optional<int64_t> RateStatistics::Rate(int64_t now_ms) const {
+std::optional<int64_t> RateStatistics::Rate(int64_t now_ms) const {
   // Yeah, this const_cast ain't pretty, but the alternative is to declare most
   // of the members as mutable...
   const_cast<RateStatistics*>(this)->EraseOld(now_ms);
@@ -109,7 +109,7 @@
       (num_samples_ <= 1 &&
        rtc::SafeLt(active_window_size, current_window_size_ms_)) ||
       overflow_) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   float scale = static_cast<float>(scale_) / active_window_size;
@@ -117,7 +117,7 @@
 
   // Better return unavailable rate than garbage value (undefined behavior).
   if (result > static_cast<float>(std::numeric_limits<int64_t>::max())) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return rtc::dchecked_cast<int64_t>(result);
 }
diff --git a/rtc_base/rate_statistics.h b/rtc_base/rate_statistics.h
index e7ce8ad..7bcb001 100644
--- a/rtc_base/rate_statistics.h
+++ b/rtc_base/rate_statistics.h
@@ -16,8 +16,8 @@
 
 #include <deque>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
@@ -62,7 +62,7 @@
   // from a monotonic clock. Ie, it doesn't matter if this call moves the
   // window, since any subsequent call to Update or Rate would still have moved
   // the window as much or more.
-  absl::optional<int64_t> Rate(int64_t now_ms) const;
+  std::optional<int64_t> Rate(int64_t now_ms) const;
 
   // Update the size of the averaging window. The maximum allowed value for
   // window_size_ms is max_window_size_ms as supplied in the constructor.
diff --git a/rtc_base/rate_statistics_unittest.cc b/rtc_base/rate_statistics_unittest.cc
index 8f1a838..5f9707a 100644
--- a/rtc_base/rate_statistics_unittest.cc
+++ b/rtc_base/rate_statistics_unittest.cc
@@ -54,7 +54,7 @@
     // Approximately 1200 kbps expected. Not exact since when packets
     // are removed we will jump 10 ms to the next packet.
     if (i > kInterval) {
-      absl::optional<uint32_t> rate = stats_.Rate(now_ms);
+      std::optional<uint32_t> rate = stats_.Rate(now_ms);
       EXPECT_TRUE(static_cast<bool>(rate));
       uint32_t samples = i / kInterval + 1;
       uint64_t total_bits = samples * kPacketSize * 8;
@@ -79,7 +79,7 @@
   const uint32_t kExpectedBitrate = 8000000;
   // 1000 bytes per millisecond until plateau is reached.
   int prev_error = kExpectedBitrate;
-  absl::optional<uint32_t> bitrate;
+  std::optional<uint32_t> bitrate;
   while (++now_ms < 10000) {
     stats_.Update(1000, now_ms);
     bitrate = stats_.Rate(now_ms);
@@ -103,7 +103,7 @@
   // Zero bytes per millisecond until 0 is reached.
   while (++now_ms < 20000) {
     stats_.Update(0, now_ms);
-    absl::optional<uint32_t> new_bitrate = stats_.Rate(now_ms);
+    std::optional<uint32_t> new_bitrate = stats_.Rate(now_ms);
     if (static_cast<bool>(new_bitrate) && *new_bitrate != *bitrate) {
       // New bitrate must be lower than previous one.
       EXPECT_LT(*new_bitrate, *bitrate);
@@ -131,7 +131,7 @@
   const uint32_t kExpectedBitrate = 8000000;
   // 1000 bytes per millisecond until the window has been filled.
   int prev_error = kExpectedBitrate;
-  absl::optional<uint32_t> bitrate;
+  std::optional<uint32_t> bitrate;
   while (++now_ms < 10000) {
     stats_.Update(1000, now_ms);
     bitrate = stats_.Rate(now_ms);
@@ -215,7 +215,7 @@
 
   // Window size should be full, and the single data point should be accepted.
   ++now_ms;
-  absl::optional<uint32_t> bitrate = stats_.Rate(now_ms);
+  std::optional<uint32_t> bitrate = stats_.Rate(now_ms);
   EXPECT_TRUE(static_cast<bool>(bitrate));
   EXPECT_EQ(1000 * 8u, *bitrate);
 
@@ -241,7 +241,7 @@
   stats_.Update(kWindowMs, now_ms);
   now_ms += kWindowMs - 1;
   stats_.Update(0, now_ms);
-  absl::optional<uint32_t> bitrate = stats_.Rate(now_ms);
+  std::optional<uint32_t> bitrate = stats_.Rate(now_ms);
   EXPECT_TRUE(static_cast<bool>(bitrate));
   EXPECT_EQ(1000 * 8u, *bitrate);
 
@@ -264,7 +264,7 @@
 
   stats_.Update(0, now_ms);
   now_ms += kWindowMs - 1;
-  absl::optional<uint32_t> bitrate = stats_.Rate(now_ms);
+  std::optional<uint32_t> bitrate = stats_.Rate(now_ms);
   EXPECT_TRUE(static_cast<bool>(bitrate));
   EXPECT_EQ(0u, *bitrate);
 
diff --git a/rtc_base/rtc_certificate_generator.cc b/rtc_base/rtc_certificate_generator.cc
index ffc51aa..a0c6f5b 100644
--- a/rtc_base/rtc_certificate_generator.cc
+++ b/rtc_base/rtc_certificate_generator.cc
@@ -32,7 +32,7 @@
 // static
 scoped_refptr<RTCCertificate> RTCCertificateGenerator::GenerateCertificate(
     const KeyParams& key_params,
-    const absl::optional<uint64_t>& expires_ms) {
+    const std::optional<uint64_t>& expires_ms) {
   if (!key_params.IsValid()) {
     return nullptr;
   }
@@ -68,7 +68,7 @@
 
 void RTCCertificateGenerator::GenerateCertificateAsync(
     const KeyParams& key_params,
-    const absl::optional<uint64_t>& expires_ms,
+    const std::optional<uint64_t>& expires_ms,
     RTCCertificateGenerator::Callback callback) {
   RTC_DCHECK(signaling_thread_->IsCurrent());
   RTC_DCHECK(callback);
diff --git a/rtc_base/rtc_certificate_generator.h b/rtc_base/rtc_certificate_generator.h
index a881f1a..34c05b8 100644
--- a/rtc_base/rtc_certificate_generator.h
+++ b/rtc_base/rtc_certificate_generator.h
@@ -13,8 +13,9 @@
 
 #include <stdint.h>
 
+#include <optional>
+
 #include "absl/functional/any_invocable.h"
-#include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
 #include "rtc_base/rtc_certificate.h"
 #include "rtc_base/ssl_identity.h"
@@ -40,7 +41,7 @@
   // its own restrictions on the expiration time.
   virtual void GenerateCertificateAsync(
       const KeyParams& key_params,
-      const absl::optional<uint64_t>& expires_ms,
+      const std::optional<uint64_t>& expires_ms,
       Callback callback) = 0;
 };
 
@@ -58,7 +59,7 @@
   // specified, a default expiration time is used.
   static scoped_refptr<RTCCertificate> GenerateCertificate(
       const KeyParams& key_params,
-      const absl::optional<uint64_t>& expires_ms);
+      const std::optional<uint64_t>& expires_ms);
 
   RTCCertificateGenerator(Thread* signaling_thread, Thread* worker_thread);
   ~RTCCertificateGenerator() override {}
@@ -69,7 +70,7 @@
   // larger value than that is clamped down to a year. If `expires_ms` is not
   // specified, a default expiration time is used.
   void GenerateCertificateAsync(const KeyParams& key_params,
-                                const absl::optional<uint64_t>& expires_ms,
+                                const std::optional<uint64_t>& expires_ms,
                                 Callback callback) override;
 
  private:
diff --git a/rtc_base/rtc_certificate_generator_unittest.cc b/rtc_base/rtc_certificate_generator_unittest.cc
index fb7ec91..84a15d4 100644
--- a/rtc_base/rtc_certificate_generator_unittest.cc
+++ b/rtc_base/rtc_certificate_generator_unittest.cc
@@ -11,8 +11,8 @@
 #include "rtc_base/rtc_certificate_generator.h"
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/make_ref_counted.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/gunit.h"
@@ -73,18 +73,18 @@
 
 TEST_F(RTCCertificateGeneratorTest, GenerateECDSA) {
   EXPECT_TRUE(RTCCertificateGenerator::GenerateCertificate(KeyParams::ECDSA(),
-                                                           absl::nullopt));
+                                                           std::nullopt));
 }
 
 TEST_F(RTCCertificateGeneratorTest, GenerateRSA) {
   EXPECT_TRUE(RTCCertificateGenerator::GenerateCertificate(KeyParams::RSA(),
-                                                           absl::nullopt));
+                                                           std::nullopt));
 }
 
 TEST_F(RTCCertificateGeneratorTest, GenerateAsyncECDSA) {
   EXPECT_FALSE(fixture_.certificate());
   fixture_.generator()->GenerateCertificateAsync(
-      KeyParams::ECDSA(), absl::nullopt, fixture_.OnGenerated());
+      KeyParams::ECDSA(), std::nullopt, fixture_.OnGenerated());
   // Until generation has completed, the certificate is null. Since this is an
   // async call, generation must not have completed until we process messages
   // posted to this thread (which is done by `EXPECT_TRUE_WAIT`).
@@ -126,9 +126,9 @@
   EXPECT_FALSE(invalid_params.IsValid());
 
   EXPECT_FALSE(RTCCertificateGenerator::GenerateCertificate(invalid_params,
-                                                            absl::nullopt));
+                                                            std::nullopt));
 
-  fixture_.generator()->GenerateCertificateAsync(invalid_params, absl::nullopt,
+  fixture_.generator()->GenerateCertificateAsync(invalid_params, std::nullopt,
                                                  fixture_.OnGenerated());
   EXPECT_TRUE_WAIT(fixture_.GenerateAsyncCompleted(), kGenerationTimeoutMs);
   EXPECT_FALSE(fixture_.certificate());
diff --git a/rtc_base/socket.h b/rtc_base/socket.h
index 275294e..aeb4ad7 100644
--- a/rtc_base/socket.h
+++ b/rtc_base/socket.h
@@ -13,7 +13,8 @@
 
 #include <errno.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "rtc_base/checks.h"
 
 #if defined(WEBRTC_POSIX)
@@ -90,7 +91,7 @@
   struct ReceiveBuffer {
     ReceiveBuffer(Buffer& payload) : payload(payload) {}
 
-    absl::optional<webrtc::Timestamp> arrival_time;
+    std::optional<webrtc::Timestamp> arrival_time;
     SocketAddress source_address;
     EcnMarking ecn = EcnMarking::kNotEct;
     Buffer& payload;
diff --git a/rtc_base/string_encode.h b/rtc_base/string_encode.h
index 82a9dfd..a28559d 100644
--- a/rtc_base/string_encode.h
+++ b/rtc_base/string_encode.h
@@ -13,12 +13,12 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/string_to_number.h"
@@ -91,7 +91,7 @@
                                   int>::type = 0>
 static bool FromString(absl::string_view s, T* t) {
   RTC_DCHECK(t);
-  absl::optional<T> result = StringToNumber<T>(s);
+  std::optional<T> result = StringToNumber<T>(s);
 
   if (result)
     *t = *result;
diff --git a/rtc_base/string_to_number.cc b/rtc_base/string_to_number.cc
index 1209ece..b02288b 100644
--- a/rtc_base/string_to_number.cc
+++ b/rtc_base/string_to_number.cc
@@ -20,9 +20,9 @@
 namespace rtc {
 namespace string_to_number_internal {
 
-absl::optional<signed_type> ParseSigned(absl::string_view str, int base) {
+std::optional<signed_type> ParseSigned(absl::string_view str, int base) {
   if (str.empty())
-    return absl::nullopt;
+    return std::nullopt;
 
   if (isdigit(static_cast<unsigned char>(str[0])) || str[0] == '-') {
     std::string str_str(str);
@@ -35,12 +35,12 @@
       return value;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<unsigned_type> ParseUnsigned(absl::string_view str, int base) {
+std::optional<unsigned_type> ParseUnsigned(absl::string_view str, int base) {
   if (str.empty())
-    return absl::nullopt;
+    return std::nullopt;
 
   if (isdigit(static_cast<unsigned char>(str[0])) || str[0] == '-') {
     std::string str_str(str);
@@ -58,7 +58,7 @@
       return value;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 template <typename T>
@@ -80,12 +80,12 @@
 }
 
 template <typename T>
-absl::optional<T> ParseFloatingPoint(absl::string_view str) {
+std::optional<T> ParseFloatingPoint(absl::string_view str) {
   if (str.empty())
-    return absl::nullopt;
+    return std::nullopt;
 
   if (str[0] == '\0')
-    return absl::nullopt;
+    return std::nullopt;
   std::string str_str(str);
   char* end = nullptr;
   errno = 0;
@@ -93,12 +93,12 @@
   if (end == str_str.c_str() + str_str.size() && errno == 0) {
     return value;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-template absl::optional<float> ParseFloatingPoint(absl::string_view str);
-template absl::optional<double> ParseFloatingPoint(absl::string_view str);
-template absl::optional<long double> ParseFloatingPoint(absl::string_view str);
+template std::optional<float> ParseFloatingPoint(absl::string_view str);
+template std::optional<double> ParseFloatingPoint(absl::string_view str);
+template std::optional<long double> ParseFloatingPoint(absl::string_view str);
 
 }  // namespace string_to_number_internal
 }  // namespace rtc
diff --git a/rtc_base/string_to_number.h b/rtc_base/string_to_number.h
index 1d704ee..5e8aea5 100644
--- a/rtc_base/string_to_number.h
+++ b/rtc_base/string_to_number.h
@@ -12,11 +12,11 @@
 #define RTC_BASE_STRING_TO_NUMBER_H_
 
 #include <limits>
+#include <optional>
 #include <string>
 #include <type_traits>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 
 namespace rtc {
 
@@ -27,7 +27,7 @@
 // are disabled in WebRTC.
 //
 // Integers are parsed using:
-//   absl::optional<int-type> StringToNumber(absl::string_view str,
+//   std::optional<int-type> StringToNumber(absl::string_view str,
 //                                           int base = 10);
 //
 // These functions parse a value from the beginning of a string into one of the
@@ -44,16 +44,16 @@
 using unsigned_type = unsigned long long;  // NOLINT(runtime/int)
 using signed_type = long long;             // NOLINT(runtime/int)
 
-absl::optional<signed_type> ParseSigned(absl::string_view str, int base);
-absl::optional<unsigned_type> ParseUnsigned(absl::string_view str, int base);
+std::optional<signed_type> ParseSigned(absl::string_view str, int base);
+std::optional<unsigned_type> ParseUnsigned(absl::string_view str, int base);
 
 template <typename T>
-absl::optional<T> ParseFloatingPoint(absl::string_view str);
+std::optional<T> ParseFloatingPoint(absl::string_view str);
 }  // namespace string_to_number_internal
 
 template <typename T>
 typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value,
-                        absl::optional<T>>::type
+                        std::optional<T>>::type
 StringToNumber(absl::string_view str, int base = 10) {
   using string_to_number_internal::signed_type;
   static_assert(
@@ -62,36 +62,36 @@
           std::numeric_limits<T>::lowest() >=
               std::numeric_limits<signed_type>::lowest(),
       "StringToNumber only supports signed integers as large as long long int");
-  absl::optional<signed_type> value =
+  std::optional<signed_type> value =
       string_to_number_internal::ParseSigned(str, base);
   if (value && *value >= std::numeric_limits<T>::lowest() &&
       *value <= std::numeric_limits<T>::max()) {
     return static_cast<T>(*value);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 template <typename T>
 typename std::enable_if<std::is_integral<T>::value &&
                             std::is_unsigned<T>::value,
-                        absl::optional<T>>::type
+                        std::optional<T>>::type
 StringToNumber(absl::string_view str, int base = 10) {
   using string_to_number_internal::unsigned_type;
   static_assert(std::numeric_limits<T>::max() <=
                     std::numeric_limits<unsigned_type>::max(),
                 "StringToNumber only supports unsigned integers as large as "
                 "unsigned long long int");
-  absl::optional<unsigned_type> value =
+  std::optional<unsigned_type> value =
       string_to_number_internal::ParseUnsigned(str, base);
   if (value && *value <= std::numeric_limits<T>::max()) {
     return static_cast<T>(*value);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 template <typename T>
 typename std::enable_if<std::is_floating_point<T>::value,
-                        absl::optional<T>>::type
+                        std::optional<T>>::type
 StringToNumber(absl::string_view str, int base = 10) {
   static_assert(
       std::numeric_limits<T>::max() <= std::numeric_limits<long double>::max(),
diff --git a/rtc_base/string_to_number_unittest.cc b/rtc_base/string_to_number_unittest.cc
index edfdbf6..0c6164d 100644
--- a/rtc_base/string_to_number_unittest.cc
+++ b/rtc_base/string_to_number_unittest.cc
@@ -13,10 +13,10 @@
 #include <stdint.h>
 
 #include <limits>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "test/gtest.h"
 
 namespace rtc {
@@ -71,10 +71,10 @@
       (min_value == 0) ? "-2" : (std::to_string(min_value) + "1");
   // Make the large value approximately ten times larger than the maximum.
   const std::string too_large_string = std::to_string(max_value) + "1";
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(too_low_string));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(too_low_string.c_str()));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(too_large_string));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(too_large_string.c_str()));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(too_low_string));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(too_low_string.c_str()));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(too_large_string));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(too_large_string.c_str()));
 }
 
 TYPED_TEST_P(BasicNumberTest, TestInvalidInputs) {
@@ -86,33 +86,33 @@
   const char kBeginningEmbeddedNul[] = {'\0', '1', '2', '3', '4'};
   const char kTrailingEmbeddedNul[] = {'1', '2', '3', '4', '\0'};
 
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(kInvalidCharArray));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(std::string(kInvalidCharArray)));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(kPlusMinusCharArray));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(std::string(kPlusMinusCharArray)));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(kNumberFollowedByCruft));
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(kInvalidCharArray));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(std::string(kInvalidCharArray)));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(kPlusMinusCharArray));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(std::string(kPlusMinusCharArray)));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(kNumberFollowedByCruft));
+  EXPECT_EQ(std::nullopt,
             StringToNumber<T>(std::string(kNumberFollowedByCruft)));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(" 5"));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(" - 5"));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>("- 5"));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(" -5"));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>("5 "));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(" 5"));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(" - 5"));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>("- 5"));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(" -5"));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>("5 "));
   // Test various types of empty inputs
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>({nullptr, 0}));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(""));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(std::string()));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(std::string("")));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(absl::string_view()));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(absl::string_view(nullptr, 0)));
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(absl::string_view("")));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>({nullptr, 0}));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(""));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(std::string()));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(std::string("")));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(absl::string_view()));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(absl::string_view(nullptr, 0)));
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(absl::string_view("")));
   // Test strings with embedded nuls.
-  EXPECT_EQ(absl::nullopt, StringToNumber<T>(absl::string_view(
-                               kEmbeddedNul, sizeof(kEmbeddedNul))));
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt, StringToNumber<T>(absl::string_view(
+                              kEmbeddedNul, sizeof(kEmbeddedNul))));
+  EXPECT_EQ(std::nullopt,
             StringToNumber<T>(absl::string_view(
                 kBeginningEmbeddedNul, sizeof(kBeginningEmbeddedNul))));
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             StringToNumber<T>(absl::string_view(kTrailingEmbeddedNul,
                                                 sizeof(kTrailingEmbeddedNul))));
 }
@@ -129,10 +129,10 @@
                                IntegerTypes);
 
 TEST(StringToNumberTest, TestSpecificValues) {
-  EXPECT_EQ(absl::nullopt, StringToNumber<uint8_t>("256"));
-  EXPECT_EQ(absl::nullopt, StringToNumber<uint8_t>("-256"));
-  EXPECT_EQ(absl::nullopt, StringToNumber<int8_t>("256"));
-  EXPECT_EQ(absl::nullopt, StringToNumber<int8_t>("-256"));
+  EXPECT_EQ(std::nullopt, StringToNumber<uint8_t>("256"));
+  EXPECT_EQ(std::nullopt, StringToNumber<uint8_t>("-256"));
+  EXPECT_EQ(std::nullopt, StringToNumber<int8_t>("256"));
+  EXPECT_EQ(std::nullopt, StringToNumber<int8_t>("-256"));
 }
 
 }  // namespace rtc
diff --git a/rtc_base/synchronization/mutex_pthread.h b/rtc_base/synchronization/mutex_pthread.h
index c749a20..a532bd2 100644
--- a/rtc_base/synchronization/mutex_pthread.h
+++ b/rtc_base/synchronization/mutex_pthread.h
@@ -76,8 +76,8 @@
     }
 
    private:
-    // Use two separate primitive types, rather than absl::optional, since the
-    // data race described below might invalidate absl::optional invariants.
+    // Use two separate primitive types, rather than std::optional, since the
+    // data race described below might invalidate std::optional invariants.
     bool is_owned_ = false;
     pthread_t latest_owner_ = pthread_self();
 #endif
diff --git a/rtc_base/system/BUILD.gn b/rtc_base/system/BUILD.gn
index eef2754..b18114f 100644
--- a/rtc_base/system/BUILD.gn
+++ b/rtc_base/system/BUILD.gn
@@ -30,7 +30,6 @@
     "..:criticalsection",
     "..:safe_conversions",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/rtc_base/system/file_wrapper.cc b/rtc_base/system/file_wrapper.cc
index b768ad0..12c27a5 100644
--- a/rtc_base/system/file_wrapper.cc
+++ b/rtc_base/system/file_wrapper.cc
@@ -14,10 +14,10 @@
 
 #include <cerrno>
 #include <cstdint>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_conversions.h"
 
@@ -82,19 +82,19 @@
   return fseek(file_, rtc::checked_cast<long>(position), SEEK_SET) == 0;
 }
 
-absl::optional<size_t> FileWrapper::FileSize() {
+std::optional<size_t> FileWrapper::FileSize() {
   if (file_ == nullptr)
-    return absl::nullopt;
+    return std::nullopt;
   long original_position = ftell(file_);
   if (original_position < 0)
-    return absl::nullopt;
+    return std::nullopt;
   int seek_error = fseek(file_, 0, SEEK_END);
   if (seek_error)
-    return absl::nullopt;
+    return std::nullopt;
   long file_size = ftell(file_);
   seek_error = fseek(file_, original_position, SEEK_SET);
   if (seek_error)
-    return absl::nullopt;
+    return std::nullopt;
   return rtc::checked_cast<size_t>(file_size);
 }
 
diff --git a/rtc_base/system/file_wrapper.h b/rtc_base/system/file_wrapper.h
index 882393b..a1553ff 100644
--- a/rtc_base/system/file_wrapper.h
+++ b/rtc_base/system/file_wrapper.h
@@ -15,10 +15,10 @@
 #include <stdint.h>
 #include <stdio.h>
 
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 
 // Implementation that can read (exclusive) or write from/to a file.
 
@@ -90,7 +90,7 @@
   // Returns the file size or -1 if a size could not be determined.
   // (A file size might not exists for non-seekable files or file-like
   // objects, for example /dev/tty on unix.)
-  absl::optional<size_t> FileSize();
+  std::optional<size_t> FileSize();
 
   // Returns number of bytes read. Short count indicates EOF or error.
   size_t Read(void* buf, size_t length);
diff --git a/rtc_base/task_queue_win.cc b/rtc_base/task_queue_win.cc
index 7e46d58..513ccd7 100644
--- a/rtc_base/task_queue_win.cc
+++ b/rtc_base/task_queue_win.cc
@@ -26,12 +26,12 @@
 #include <algorithm>
 #include <functional>
 #include <memory>
+#include <optional>
 #include <queue>
 #include <utility>
 
 #include "absl/functional/any_invocable.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -210,7 +210,7 @@
 
 void TaskQueueWin::Delete() {
   RTC_DCHECK(!IsCurrent());
-  RTC_CHECK(thread_.GetHandle() != absl::nullopt);
+  RTC_CHECK(thread_.GetHandle() != std::nullopt);
   while (
       !::PostThreadMessage(GetThreadId(*thread_.GetHandle()), WM_QUIT, 0, 0)) {
     RTC_CHECK_EQ(ERROR_NOT_ENOUGH_QUOTA, ::GetLastError());
@@ -239,7 +239,7 @@
   }
 
   auto* task_info = new DelayedTaskInfo(delay, std::move(task));
-  RTC_CHECK(thread_.GetHandle() != absl::nullopt);
+  RTC_CHECK(thread_.GetHandle() != std::nullopt);
   if (!::PostThreadMessage(GetThreadId(*thread_.GetHandle()),
                            WM_QUEUE_DELAYED_TASK, 0,
                            reinterpret_cast<LPARAM>(task_info))) {
diff --git a/rtc_base/task_utils/BUILD.gn b/rtc_base/task_utils/BUILD.gn
index 073d545..ee6abc3 100644
--- a/rtc_base/task_utils/BUILD.gn
+++ b/rtc_base/task_utils/BUILD.gn
@@ -41,7 +41,6 @@
       "../../system_wrappers:system_wrappers",
       "../../test:test_support",
       "//third_party/abseil-cpp/absl/functional:any_invocable",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
diff --git a/rtc_base/task_utils/repeating_task_unittest.cc b/rtc_base/task_utils/repeating_task_unittest.cc
index de6cfdb..202a6f5 100644
--- a/rtc_base/task_utils/repeating_task_unittest.cc
+++ b/rtc_base/task_utils/repeating_task_unittest.cc
@@ -12,9 +12,9 @@
 
 #include <atomic>
 #include <memory>
+#include <optional>
 
 #include "absl/functional/any_invocable.h"
-#include "absl/types/optional.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/task_queue/test/mock_task_queue_base.h"
 #include "api/units/time_delta.h"
@@ -63,7 +63,7 @@
                     const PostTaskTraits& /*traits*/,
                     const Location& /*location*/) override {
     last_task_ = std::move(task);
-    last_precision_ = absl::nullopt;
+    last_precision_ = std::nullopt;
     last_delay_ = TimeDelta::Zero();
   }
 
@@ -95,7 +95,7 @@
     return last_delay_;
   }
 
-  absl::optional<TaskQueueBase::DelayPrecision> last_precision() const {
+  std::optional<TaskQueueBase::DelayPrecision> last_precision() const {
     return last_precision_;
   }
 
@@ -104,7 +104,7 @@
   SimulatedClock* clock_;
   absl::AnyInvocable<void() &&> last_task_;
   TimeDelta last_delay_ = TimeDelta::MinusInfinity();
-  absl::optional<TaskQueueBase::DelayPrecision> last_precision_;
+  std::optional<TaskQueueBase::DelayPrecision> last_precision_;
 };
 
 // NOTE: Since this utility class holds a raw pointer to a variable that likely
diff --git a/rtc_base/test_client.cc b/rtc_base/test_client.cc
index 87c9465..3bcc509 100644
--- a/rtc_base/test_client.cc
+++ b/rtc_base/test_client.cc
@@ -113,7 +113,7 @@
 }
 
 bool TestClient::CheckTimestamp(
-    absl::optional<webrtc::Timestamp> packet_timestamp) {
+    std::optional<webrtc::Timestamp> packet_timestamp) {
   bool res = true;
   if (!packet_timestamp) {
     res = false;
diff --git a/rtc_base/test_client.h b/rtc_base/test_client.h
index 6fe6fd5..56c4b7b 100644
--- a/rtc_base/test_client.h
+++ b/rtc_base/test_client.h
@@ -34,7 +34,7 @@
 
     SocketAddress addr;
     Buffer buf;
-    absl::optional<webrtc::Timestamp> packet_time;
+    std::optional<webrtc::Timestamp> packet_time;
   };
 
   // Default timeout for NextPacket reads.
@@ -98,7 +98,7 @@
   void OnPacket(AsyncPacketSocket* socket,
                 const rtc::ReceivedPacket& received_packet);
   void OnReadyToSend(AsyncPacketSocket* socket);
-  bool CheckTimestamp(absl::optional<webrtc::Timestamp> packet_timestamp);
+  bool CheckTimestamp(std::optional<webrtc::Timestamp> packet_timestamp);
   void AdvanceTime(int ms);
 
   ThreadProcessingFakeClock* fake_clock_ = nullptr;
@@ -106,7 +106,7 @@
   std::unique_ptr<AsyncPacketSocket> socket_;
   std::vector<std::unique_ptr<Packet>> packets_;
   int ready_to_send_count_ = 0;
-  absl::optional<webrtc::Timestamp> prev_packet_timestamp_;
+  std::optional<webrtc::Timestamp> prev_packet_timestamp_;
 };
 
 }  // namespace rtc
diff --git a/rtc_base/unique_id_generator.cc b/rtc_base/unique_id_generator.cc
index c80a843..b29f4c6 100644
--- a/rtc_base/unique_id_generator.cc
+++ b/rtc_base/unique_id_generator.cc
@@ -59,7 +59,7 @@
 bool UniqueStringGenerator::AddKnownId(absl::string_view value) {
   // TODO(webrtc:13579): remove string copy here once absl::string_view version
   // of StringToNumber is available.
-  absl::optional<uint32_t> int_value =
+  std::optional<uint32_t> int_value =
       StringToNumber<uint32_t>(std::string(value));
   // The underlying generator works for uint32_t values, so if the provided
   // value is not a uint32_t it will never be generated anyway.
diff --git a/rtc_base/virtual_socket_server.cc b/rtc_base/virtual_socket_server.cc
index bec7d97..dd02281 100644
--- a/rtc_base/virtual_socket_server.cc
+++ b/rtc_base/virtual_socket_server.cc
@@ -160,7 +160,7 @@
     for (const SocketAddress& remote_addr : *listen_queue_) {
       server->Disconnect(remote_addr);
     }
-    listen_queue_ = absl::nullopt;
+    listen_queue_ = std::nullopt;
   }
 
   // Cancel potential connects
diff --git a/rtc_base/virtual_socket_server.h b/rtc_base/virtual_socket_server.h
index 93ef288..7704abf 100644
--- a/rtc_base/virtual_socket_server.h
+++ b/rtc_base/virtual_socket_server.h
@@ -13,9 +13,9 @@
 
 #include <deque>
 #include <map>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/make_ref_counted.h"
 #include "api/ref_counted_base.h"
 #include "api/scoped_refptr.h"
@@ -151,7 +151,7 @@
     std::list<std::unique_ptr<Packet>> recv_buffer_ RTC_GUARDED_BY(mutex_);
 
     // Pending sockets which can be Accepted
-    absl::optional<std::deque<SocketAddress>> listen_queue_
+    std::optional<std::deque<SocketAddress>> listen_queue_
         RTC_GUARDED_BY(mutex_);
   };
 
diff --git a/rtc_tools/BUILD.gn b/rtc_tools/BUILD.gn
index 50a42f6..bfd8085 100644
--- a/rtc_tools/BUILD.gn
+++ b/rtc_tools/BUILD.gn
@@ -63,7 +63,6 @@
     "../rtc_base:refcount",
     "../rtc_base:stringutils",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -109,7 +108,6 @@
     "../common_video",
     "../rtc_base:checks",
     "../rtc_base:logging",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/libyuv",
   ]
 }
@@ -411,7 +409,6 @@
         "//third_party/abseil-cpp/absl/base:core_headers",
         "//third_party/abseil-cpp/absl/functional:bind_front",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
 
@@ -444,7 +441,6 @@
         "//rtc_base/system:file_wrapper",
         "//test:fileutils",
         "//test:test_support",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
   }
@@ -512,7 +508,6 @@
           "//third_party/abseil-cpp/absl/flags:parse",
           "//third_party/abseil-cpp/absl/flags:usage",
           "//third_party/abseil-cpp/absl/strings",
-          "//third_party/abseil-cpp/absl/types:optional",
         ]
       }
 
diff --git a/rtc_tools/frame_analyzer/linear_least_squares.h b/rtc_tools/frame_analyzer/linear_least_squares.h
index 7006db1..5b5a783 100644
--- a/rtc_tools/frame_analyzer/linear_least_squares.h
+++ b/rtc_tools/frame_analyzer/linear_least_squares.h
@@ -13,11 +13,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <valarray>
 #include <vector>
 
-#include "absl/types/optional.h"
-
 namespace webrtc {
 namespace test {
 
@@ -45,9 +44,9 @@
 
  private:
   // Running sum of x^T * x.
-  absl::optional<std::valarray<std::valarray<uint64_t>>> sum_xx;
+  std::optional<std::valarray<std::valarray<uint64_t>>> sum_xx;
   // Running sum of x^T * y.
-  absl::optional<std::valarray<std::valarray<uint64_t>>> sum_xy;
+  std::optional<std::valarray<std::valarray<uint64_t>>> sum_xy;
 };
 
 }  // namespace test
diff --git a/rtc_tools/network_tester/BUILD.gn b/rtc_tools/network_tester/BUILD.gn
index ab622cc..995c3d0 100644
--- a/rtc_tools/network_tester/BUILD.gn
+++ b/rtc_tools/network_tester/BUILD.gn
@@ -60,7 +60,6 @@
       "../../rtc_base/synchronization:mutex",
       "../../rtc_base/system:no_unique_address",
       "//third_party/abseil-cpp/absl/functional:any_invocable",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
diff --git a/rtc_tools/network_tester/config_reader.cc b/rtc_tools/network_tester/config_reader.cc
index 16ae458..5ee1676 100644
--- a/rtc_tools/network_tester/config_reader.cc
+++ b/rtc_tools/network_tester/config_reader.cc
@@ -33,10 +33,10 @@
 
 ConfigReader::~ConfigReader() = default;
 
-absl::optional<ConfigReader::Config> ConfigReader::GetNextConfig() {
+std::optional<ConfigReader::Config> ConfigReader::GetNextConfig() {
 #ifdef WEBRTC_NETWORK_TESTER_PROTO
   if (proto_config_index_ >= proto_all_configs_.configs_size())
-    return absl::nullopt;
+    return std::nullopt;
   auto proto_config = proto_all_configs_.configs(proto_config_index_++);
   RTC_DCHECK(proto_config.has_packet_send_interval_ms());
   RTC_DCHECK(proto_config.has_packet_size());
@@ -47,7 +47,7 @@
   config.execution_time_ms = proto_config.execution_time_ms();
   return config;
 #else
-  return absl::nullopt;
+  return std::nullopt;
 #endif  //  WEBRTC_NETWORK_TESTER_PROTO
 }
 
diff --git a/rtc_tools/network_tester/config_reader.h b/rtc_tools/network_tester/config_reader.h
index 3903613..936da82 100644
--- a/rtc_tools/network_tester/config_reader.h
+++ b/rtc_tools/network_tester/config_reader.h
@@ -12,10 +12,9 @@
 #define RTC_TOOLS_NETWORK_TESTER_CONFIG_READER_H_
 
 #include <fstream>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
-
 #ifdef WEBRTC_NETWORK_TESTER_PROTO
 #include "rtc_tools/network_tester/network_tester_config.pb.h"
 using webrtc::network_tester::config::NetworkTesterAllConfigs;
@@ -38,7 +37,7 @@
   ConfigReader(const ConfigReader&) = delete;
   ConfigReader& operator=(const ConfigReader&) = delete;
 
-  absl::optional<Config> GetNextConfig();
+  std::optional<Config> GetNextConfig();
 
  private:
   NetworkTesterAllConfigs proto_all_configs_;
diff --git a/rtc_tools/network_tester/packet_sender.cc b/rtc_tools/network_tester/packet_sender.cc
index c991737..eed185b 100644
--- a/rtc_tools/network_tester/packet_sender.cc
+++ b/rtc_tools/network_tester/packet_sender.cc
@@ -54,7 +54,7 @@
     if (!task_safety_flag->alive()) {
       return;
     }
-    if (absl::optional<ConfigReader::Config> config =
+    if (std::optional<ConfigReader::Config> config =
             config_reader->GetNextConfig()) {
       packet_sender->UpdateTestSetting(config->packet_size,
                                        config->packet_send_interval_ms);
diff --git a/rtc_tools/network_tester/test_controller.cc b/rtc_tools/network_tester/test_controller.cc
index f8641aa..7b948df 100644
--- a/rtc_tools/network_tester/test_controller.cc
+++ b/rtc_tools/network_tester/test_controller.cc
@@ -11,8 +11,8 @@
 #include "rtc_tools/network_tester/test_controller.h"
 
 #include <limits>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/units/timestamp.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/internal/default_socket_server.h"
@@ -64,14 +64,14 @@
   remote_address_ = rtc::SocketAddress(hostname, port);
   NetworkTesterPacket packet;
   packet.set_type(NetworkTesterPacket::HAND_SHAKING);
-  SendData(packet, absl::nullopt);
+  SendData(packet, std::nullopt);
   MutexLock scoped_lock(&test_done_lock_);
   local_test_done_ = false;
   remote_test_done_ = false;
 }
 
 void TestController::SendData(const NetworkTesterPacket& packet,
-                              absl::optional<size_t> data_size) {
+                              std::optional<size_t> data_size) {
   if (!packet_sender_thread_->IsCurrent()) {
     packet_sender_thread_->PostTask(SafeTask(
         task_safety_flag_,
@@ -96,7 +96,7 @@
   RTC_DCHECK_RUN_ON(packet_sender_thread_.get());
   NetworkTesterPacket packet;
   packet.set_type(NetworkTesterPacket::TEST_DONE);
-  SendData(packet, absl::nullopt);
+  SendData(packet, std::nullopt);
   MutexLock scoped_lock(&test_done_lock_);
   local_test_done_ = true;
 }
@@ -123,7 +123,7 @@
       NetworkTesterPacket packet;
       packet.set_type(NetworkTesterPacket::TEST_START);
       remote_address_ = received_packet.source_address();
-      SendData(packet, absl::nullopt);
+      SendData(packet, std::nullopt);
       packet_sender_.reset(new PacketSender(this, packet_sender_thread_.get(),
                                             task_safety_flag_,
                                             config_file_path_));
diff --git a/rtc_tools/network_tester/test_controller.h b/rtc_tools/network_tester/test_controller.h
index 423eb08..ce4d793 100644
--- a/rtc_tools/network_tester/test_controller.h
+++ b/rtc_tools/network_tester/test_controller.h
@@ -16,9 +16,9 @@
 
 #include <array>
 #include <memory>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/sequence_checker.h"
 #include "p2p/base/basic_packet_socket_factory.h"
 #include "rtc_base/async_packet_socket.h"
@@ -57,7 +57,7 @@
   void SendConnectTo(const std::string& hostname, int port);
 
   void SendData(const NetworkTesterPacket& packet,
-                absl::optional<size_t> data_size);
+                std::optional<size_t> data_size);
 
   void OnTestDone();
 
diff --git a/rtc_tools/rtc_event_log_visualizer/alerts.cc b/rtc_tools/rtc_event_log_visualizer/alerts.cc
index 98ffbd3..9137d0b 100644
--- a/rtc_tools/rtc_event_log_visualizer/alerts.cc
+++ b/rtc_tools/rtc_event_log_visualizer/alerts.cc
@@ -17,9 +17,9 @@
 #include <cstdlib>
 #include <functional>
 #include <map>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/units/timestamp.h"
 #include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
 #include "logging/rtc_event_log/rtc_event_log_parser.h"
@@ -132,7 +132,7 @@
     for (const LoggedRtpPacket& rtp_packet : stream.packet_view)
       rtp_in_direction.emplace(rtp_packet.log_time_us(), &rtp_packet);
   }
-  absl::optional<int64_t> last_rtp_time;
+  std::optional<int64_t> last_rtp_time;
   for (const auto& kv : rtp_in_direction) {
     int64_t timestamp = kv.first;
     if (timestamp > segment_end_us) {
@@ -148,7 +148,7 @@
     last_rtp_time.emplace(timestamp);
   }
 
-  absl::optional<int64_t> last_rtcp_time;
+  std::optional<int64_t> last_rtcp_time;
   if (direction == kIncomingPacket) {
     for (const auto& rtcp : parsed_log.incoming_rtcp_packets()) {
       if (rtcp.log_time_us() > segment_end_us) {
diff --git a/rtc_tools/rtc_event_log_visualizer/analyze_audio.cc b/rtc_tools/rtc_event_log_visualizer/analyze_audio.cc
index cba8998..4fbe9a6 100644
--- a/rtc_tools/rtc_event_log_visualizer/analyze_audio.cc
+++ b/rtc_tools/rtc_event_log_visualizer/analyze_audio.cc
@@ -13,13 +13,13 @@
 #include <cstdint>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "api/audio_codecs/audio_decoder_factory.h"
@@ -53,11 +53,11 @@
   TimeSeries time_series("Audio encoder target bitrate", LineStyle::kLine,
                          PointStyle::kHighlight);
   auto GetAnaBitrateBps = [](const LoggedAudioNetworkAdaptationEvent& ana_event)
-      -> absl::optional<float> {
+      -> std::optional<float> {
     if (ana_event.config.bitrate_bps)
-      return absl::optional<float>(
+      return std::optional<float>(
           static_cast<float>(*ana_event.config.bitrate_bps));
-    return absl::nullopt;
+    return std::nullopt;
   };
   auto ToCallTime = [config](const LoggedAudioNetworkAdaptationEvent& packet) {
     return config.GetCallTimeSec(packet.log_time());
@@ -80,9 +80,9 @@
   auto GetAnaFrameLengthMs =
       [](const LoggedAudioNetworkAdaptationEvent& ana_event) {
         if (ana_event.config.frame_length_ms)
-          return absl::optional<float>(
+          return std::optional<float>(
               static_cast<float>(*ana_event.config.frame_length_ms));
-        return absl::optional<float>();
+        return std::optional<float>();
       };
   auto ToCallTime = [config](const LoggedAudioNetworkAdaptationEvent& packet) {
     return config.GetCallTimeSec(packet.log_time());
@@ -105,9 +105,9 @@
   auto GetAnaPacketLoss =
       [](const LoggedAudioNetworkAdaptationEvent& ana_event) {
         if (ana_event.config.uplink_packet_loss_fraction)
-          return absl::optional<float>(static_cast<float>(
+          return std::optional<float>(static_cast<float>(
               *ana_event.config.uplink_packet_loss_fraction));
-        return absl::optional<float>();
+        return std::optional<float>();
       };
   auto ToCallTime = [config](const LoggedAudioNetworkAdaptationEvent& packet) {
     return config.GetCallTimeSec(packet.log_time());
@@ -131,9 +131,9 @@
   auto GetAnaFecEnabled =
       [](const LoggedAudioNetworkAdaptationEvent& ana_event) {
         if (ana_event.config.enable_fec)
-          return absl::optional<float>(
+          return std::optional<float>(
               static_cast<float>(*ana_event.config.enable_fec));
-        return absl::optional<float>();
+        return std::optional<float>();
       };
   auto ToCallTime = [config](const LoggedAudioNetworkAdaptationEvent& packet) {
     return config.GetCallTimeSec(packet.log_time());
@@ -156,9 +156,9 @@
   auto GetAnaDtxEnabled =
       [](const LoggedAudioNetworkAdaptationEvent& ana_event) {
         if (ana_event.config.enable_dtx)
-          return absl::optional<float>(
+          return std::optional<float>(
               static_cast<float>(*ana_event.config.enable_dtx));
-        return absl::optional<float>();
+        return std::optional<float>();
       };
   auto ToCallTime = [config](const LoggedAudioNetworkAdaptationEvent& packet) {
     return config.GetCallTimeSec(packet.log_time());
@@ -181,9 +181,9 @@
   auto GetAnaNumChannels =
       [](const LoggedAudioNetworkAdaptationEvent& ana_event) {
         if (ana_event.config.num_channels)
-          return absl::optional<float>(
+          return std::optional<float>(
               static_cast<float>(*ana_event.config.num_channels));
-        return absl::optional<float>();
+        return std::optional<float>();
       };
   auto ToCallTime = [config](const LoggedAudioNetworkAdaptationEvent& packet) {
     return config.GetCallTimeSec(packet.log_time());
@@ -221,7 +221,7 @@
 
   std::unique_ptr<AudioDecoder> MakeAudioDecoder(
       const SdpAudioFormat& format,
-      absl::optional<AudioCodecPairId> codec_pair_id) override {
+      std::optional<AudioCodecPairId> codec_pair_id) override {
     auto replacement_file = std::make_unique<test::ResampleInputAudioFile>(
         replacement_file_name_, file_sample_rate_hz_);
     replacement_file->set_output_rate_hz(48000);
diff --git a/rtc_tools/rtc_event_log_visualizer/analyzer.cc b/rtc_tools/rtc_event_log_visualizer/analyzer.cc
index 62868ff8..d481f3a 100644
--- a/rtc_tools/rtc_event_log_visualizer/analyzer.cc
+++ b/rtc_tools/rtc_event_log_visualizer/analyzer.cc
@@ -18,6 +18,7 @@
 #include <limits>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <unordered_set>
@@ -27,7 +28,6 @@
 #include "absl/algorithm/container.h"
 #include "absl/functional/bind_front.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/candidate.h"
 #include "api/dtls_transport_interface.h"
 #include "api/environment/environment_factory.h"
@@ -136,7 +136,7 @@
 
 // This is much more reliable for outgoing streams than for incoming streams.
 template <typename RtpPacketContainer>
-absl::optional<uint32_t> EstimateRtpClockFrequency(
+std::optional<uint32_t> EstimateRtpClockFrequency(
     const RtpPacketContainer& packets,
     int64_t end_time_us) {
   RTC_CHECK(packets.size() >= 2);
@@ -157,7 +157,7 @@
         << "Failed to estimate RTP clock frequency: Stream too short. ("
         << packets.size() << " packets, "
         << last_log_timestamp - first_log_timestamp << " us)";
-    return absl::nullopt;
+    return std::nullopt;
   }
   double duration =
       static_cast<double>(last_log_timestamp - first_log_timestamp) /
@@ -174,10 +174,10 @@
                       << " not close to any standard RTP frequency."
                       << " Last timestamp " << last_rtp_timestamp
                       << " first timestamp " << first_rtp_timestamp;
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<double> NetworkDelayDiff_AbsSendTime(
+std::optional<double> NetworkDelayDiff_AbsSendTime(
     const LoggedRtpPacketIncoming& old_packet,
     const LoggedRtpPacketIncoming& new_packet) {
   if (old_packet.rtp.header.extension.hasAbsoluteSendTime &&
@@ -191,11 +191,11 @@
         recv_time_diff - AbsSendTimeToMicroseconds(send_time_diff);
     return delay_change_us / 1000;
   } else {
-    return absl::nullopt;
+    return std::nullopt;
   }
 }
 
-absl::optional<double> NetworkDelayDiff_CaptureTime(
+std::optional<double> NetworkDelayDiff_CaptureTime(
     const LoggedRtpPacketIncoming& old_packet,
     const LoggedRtpPacketIncoming& new_packet,
     const double sample_rate) {
@@ -716,7 +716,7 @@
     TimeSeries time_series(GetStreamName(parsed_log_, direction, stream.ssrc),
                            LineStyle::kBar);
     auto GetPacketSize = [](const LoggedRtpPacket& packet) {
-      return absl::optional<float>(packet.total_length);
+      return std::optional<float>(packet.total_length);
     };
     auto ToCallTime = [this](const LoggedRtpPacket& packet) {
       return this->config_.GetCallTimeSec(packet.timestamp);
@@ -902,7 +902,7 @@
     uint32_t ssrc = playout_stream.first;
     if (!MatchingSsrc(ssrc, desired_ssrc_))
       continue;
-    absl::optional<int64_t> last_playout_ms;
+    std::optional<int64_t> last_playout_ms;
     TimeSeries time_series(SsrcToString(ssrc), LineStyle::kBar);
     for (const auto& playout_event : playout_stream.second) {
       float x = config_.GetCallTimeSec(playout_event.log_time());
@@ -1084,7 +1084,7 @@
       continue;
     }
     int64_t segment_end_us = parsed_log_.first_log_segment().stop_time_us();
-    absl::optional<uint32_t> estimated_frequency =
+    std::optional<uint32_t> estimated_frequency =
         EstimateRtpClockFrequency(packets, segment_end_us);
     if (!estimated_frequency)
       continue;
@@ -1462,7 +1462,7 @@
   std::map<LayerDescription, TimeSeries> time_series;
   const auto& xr_list = parsed_log_.extended_reports(direction);
   for (const auto& rtcp : xr_list) {
-    const absl::optional<rtcp::TargetBitrate>& target_bitrate =
+    const std::optional<rtcp::TargetBitrate>& target_bitrate =
         rtcp.xr.target_bitrate();
     if (!target_bitrate.has_value())
       continue;
@@ -1795,20 +1795,20 @@
             raw_acked_bitrate.Update(packet.sent_packet.size.bytes(),
                                      packet.receive_time.ms());
           }
-          absl::optional<uint32_t> raw_bitrate_bps =
+          std::optional<uint32_t> raw_bitrate_bps =
               raw_acked_bitrate.Rate(feedback.back().receive_time.ms());
           float x = config_.GetCallTimeSec(clock.CurrentTime());
           if (raw_bitrate_bps) {
             float y = raw_bitrate_bps.value() / 1000;
             acked_time_series.points.emplace_back(x, y);
           }
-          absl::optional<DataRate> robust_estimate =
+          std::optional<DataRate> robust_estimate =
               robust_throughput_estimator->bitrate();
           if (robust_estimate) {
             float y = robust_estimate.value().kbps();
             robust_time_series.points.emplace_back(x, y);
           }
-          absl::optional<DataRate> acked_estimate =
+          std::optional<DataRate> acked_estimate =
               acknowledged_bitrate_estimator->bitrate();
           if (acked_estimate) {
             float y = acked_estimate.value().kbps();
@@ -1905,7 +1905,7 @@
     rscc.OnReceivedPacket(rtp_packet, MediaType::VIDEO);
     int64_t arrival_time_ms = packet.rtp.log_time().ms();
     acked_bitrate.Update(packet.rtp.total_length, arrival_time_ms);
-    absl::optional<uint32_t> bitrate_bps = acked_bitrate.Rate(arrival_time_ms);
+    std::optional<uint32_t> bitrate_bps = acked_bitrate.Rate(arrival_time_ms);
     if (bitrate_bps) {
       uint32_t y = *bitrate_bps / 1000;
       float x = config_.GetCallTimeSec(clock.CurrentTime());
@@ -1987,7 +1987,7 @@
       continue;
     }
     int64_t segment_end_us = parsed_log_.first_log_segment().stop_time_us();
-    absl::optional<uint32_t> estimated_frequency =
+    std::optional<uint32_t> estimated_frequency =
         EstimateRtpClockFrequency(packets, segment_end_us);
     if (!estimated_frequency)
       continue;
diff --git a/rtc_tools/rtc_event_log_visualizer/analyzer_bindings_unittest.cc b/rtc_tools/rtc_event_log_visualizer/analyzer_bindings_unittest.cc
index 5d61845..cb9f76a 100644
--- a/rtc_tools/rtc_event_log_visualizer/analyzer_bindings_unittest.cc
+++ b/rtc_tools/rtc_event_log_visualizer/analyzer_bindings_unittest.cc
@@ -13,10 +13,10 @@
 #include <cstddef>
 #include <cstdint>
 #include <cstring>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "rtc_base/protobuf_utils.h"
 #include "rtc_base/system/file_wrapper.h"
 #include "test/gtest.h"
@@ -36,7 +36,7 @@
     webrtc::FileWrapper file = webrtc::FileWrapper::OpenReadOnly(file_name);
     ASSERT_TRUE(file.is_open());
 
-    absl::optional<size_t> file_size = file.FileSize();
+    std::optional<size_t> file_size = file.FileSize();
     ASSERT_TRUE(file_size.has_value());
     constexpr size_t kMaxFileSize = 1'000'000;
     ASSERT_GT(*file_size, 0u);
diff --git a/rtc_tools/rtc_event_log_visualizer/analyzer_common.h b/rtc_tools/rtc_event_log_visualizer/analyzer_common.h
index 5f778cb..1513ace 100644
--- a/rtc_tools/rtc_event_log_visualizer/analyzer_common.h
+++ b/rtc_tools/rtc_event_log_visualizer/analyzer_common.h
@@ -13,9 +13,9 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/function_view.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -104,13 +104,13 @@
 // store the result in a TimeSeries.
 template <typename DataType, typename IterableType>
 void ProcessPoints(rtc::FunctionView<float(const DataType&)> fx,
-                   rtc::FunctionView<absl::optional<float>(const DataType&)> fy,
+                   rtc::FunctionView<std::optional<float>(const DataType&)> fy,
                    const IterableType& data_view,
                    TimeSeries* result) {
   for (size_t i = 0; i < data_view.size(); i++) {
     const DataType& elem = data_view[i];
     float x = fx(elem);
-    absl::optional<float> y = fy(elem);
+    std::optional<float> y = fy(elem);
     if (y)
       result->points.emplace_back(x, *y);
   }
@@ -122,13 +122,13 @@
 template <typename DataType, typename ResultType, typename IterableType>
 void ProcessPairs(
     rtc::FunctionView<float(const DataType&)> fx,
-    rtc::FunctionView<absl::optional<ResultType>(const DataType&,
-                                                 const DataType&)> fy,
+    rtc::FunctionView<std::optional<ResultType>(const DataType&,
+                                                const DataType&)> fy,
     const IterableType& data,
     TimeSeries* result) {
   for (size_t i = 1; i < data.size(); i++) {
     float x = fx(data[i]);
-    absl::optional<ResultType> y = fy(data[i - 1], data[i]);
+    std::optional<ResultType> y = fy(data[i - 1], data[i]);
     if (y)
       result->points.emplace_back(x, static_cast<float>(*y));
   }
@@ -140,14 +140,14 @@
 template <typename DataType, typename ResultType, typename IterableType>
 void AccumulatePairs(
     rtc::FunctionView<float(const DataType&)> fx,
-    rtc::FunctionView<absl::optional<ResultType>(const DataType&,
-                                                 const DataType&)> fy,
+    rtc::FunctionView<std::optional<ResultType>(const DataType&,
+                                                const DataType&)> fy,
     const IterableType& data,
     TimeSeries* result) {
   ResultType sum = 0;
   for (size_t i = 1; i < data.size(); i++) {
     float x = fx(data[i]);
-    absl::optional<ResultType> y = fy(data[i - 1], data[i]);
+    std::optional<ResultType> y = fy(data[i - 1], data[i]);
     if (y) {
       sum += *y;
       result->points.emplace_back(x, static_cast<float>(sum));
@@ -161,7 +161,7 @@
 // during the preceding `window_duration_us` microseconds.
 template <typename DataType, typename ResultType, typename IterableType>
 void MovingAverage(
-    rtc::FunctionView<absl::optional<ResultType>(const DataType&)> fy,
+    rtc::FunctionView<std::optional<ResultType>(const DataType&)> fy,
     const IterableType& data_view,
     AnalyzerConfig config,
     TimeSeries* result) {
@@ -173,7 +173,7 @@
        t += config.step_) {
     while (window_index_end < data_view.size() &&
            data_view[window_index_end].log_time() < t) {
-      absl::optional<ResultType> value = fy(data_view[window_index_end]);
+      std::optional<ResultType> value = fy(data_view[window_index_end]);
       if (value)
         sum_in_window += *value;
       ++window_index_end;
@@ -181,7 +181,7 @@
     while (window_index_begin < data_view.size() &&
            data_view[window_index_begin].log_time() <
                t - config.window_duration_) {
-      absl::optional<ResultType> value = fy(data_view[window_index_begin]);
+      std::optional<ResultType> value = fy(data_view[window_index_begin]);
       if (value)
         sum_in_window -= *value;
       ++window_index_begin;
diff --git a/rtc_tools/rtc_event_log_visualizer/main.cc b/rtc_tools/rtc_event_log_visualizer/main.cc
index feded78..5ddaff8 100644
--- a/rtc_tools/rtc_event_log_visualizer/main.cc
+++ b/rtc_tools/rtc_event_log_visualizer/main.cc
@@ -16,6 +16,7 @@
 #include <iostream>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -27,7 +28,6 @@
 #include "absl/flags/usage_config.h"
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/neteq/neteq.h"
 #include "api/units/time_delta.h"
 #include "logging/rtc_event_log/rtc_event_log_parser.h"
@@ -324,7 +324,7 @@
   //  * cache the simulation results between different plots
   //  * open and read files
   //  * dont have a 1-to-1 mapping between IDs and charts.
-  absl::optional<webrtc::NetEqStatsGetterMap> neteq_stats;
+  std::optional<webrtc::NetEqStatsGetterMap> neteq_stats;
   if (absl::c_find(plot_names, "simulated_neteq_expand_rate") !=
       plot_names.end()) {
     if (!neteq_stats) {
diff --git a/rtc_tools/rtc_event_log_visualizer/plot_base.h b/rtc_tools/rtc_event_log_visualizer/plot_base.h
index aacffa4..722a79d 100644
--- a/rtc_tools/rtc_event_log_visualizer/plot_base.h
+++ b/rtc_tools/rtc_event_log_visualizer/plot_base.h
@@ -12,13 +12,13 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/base/attributes.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 
 // Generated at build-time by the protobuf compiler.
 #include "rtc_tools/rtc_event_log_visualizer/proto/chart.pb.h"
@@ -213,7 +213,7 @@
 
  protected:
   std::vector<std::unique_ptr<Plot>> plots_;
-  absl::optional<int64_t> calltime_to_utc_ms_;
+  std::optional<int64_t> calltime_to_utc_ms_;
 };
 
 }  // namespace webrtc
diff --git a/rtc_tools/rtp_generator/main.cc b/rtc_tools/rtp_generator/main.cc
index df49576..7c4fcdf 100644
--- a/rtc_tools/rtp_generator/main.cc
+++ b/rtc_tools/rtp_generator/main.cc
@@ -35,7 +35,7 @@
     return EXIT_FAILURE;
   }
 
-  absl::optional<webrtc::RtpGeneratorOptions> options =
+  std::optional<webrtc::RtpGeneratorOptions> options =
       webrtc::ParseRtpGeneratorOptionsFromFile(config_path);
   if (!options.has_value()) {
     return EXIT_FAILURE;
diff --git a/rtc_tools/rtp_generator/rtp_generator.cc b/rtc_tools/rtp_generator/rtp_generator.cc
index ade169a..66ab032 100644
--- a/rtc_tools/rtp_generator/rtp_generator.cc
+++ b/rtc_tools/rtp_generator/rtp_generator.cc
@@ -69,7 +69,7 @@
 }
 
 // Creates a single VideoSendStream configuration.
-absl::optional<RtpGeneratorOptions::VideoSendStreamConfig>
+std::optional<RtpGeneratorOptions::VideoSendStreamConfig>
 ParseVideoSendStreamConfig(const Json::Value& json) {
   RtpGeneratorOptions::VideoSendStreamConfig config;
 
@@ -100,16 +100,16 @@
   Json::Value rtp_json;
   if (!rtc::GetValueFromJsonObject(json, "rtp", &rtp_json)) {
     RTC_LOG(LS_ERROR) << "video_streams must have an rtp section";
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (!rtc::GetStringFromJsonObject(rtp_json, "payload_name",
                                     &config.rtp.payload_name)) {
     RTC_LOG(LS_ERROR) << "rtp.payload_name must be specified";
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (!IsValidCodecType(config.rtp.payload_name)) {
     RTC_LOG(LS_ERROR) << "rtp.payload_name must be VP8,VP9 or H264";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   config.rtp.payload_type =
@@ -126,11 +126,11 @@
 
 }  // namespace
 
-absl::optional<RtpGeneratorOptions> ParseRtpGeneratorOptionsFromFile(
+std::optional<RtpGeneratorOptions> ParseRtpGeneratorOptionsFromFile(
     const std::string& options_file) {
   if (!test::FileExists(options_file)) {
     RTC_LOG(LS_ERROR) << " configuration file does not exist";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Read the configuration file from disk.
@@ -140,7 +140,7 @@
       config_file.Read(raw_json_buffer.data(), raw_json_buffer.size() - 1);
   if (bytes_read == 0) {
     RTC_LOG(LS_ERROR) << "Unable to read the configuration file.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Parse the file as JSON
@@ -153,16 +153,16 @@
                           &json, &error_message)) {
     RTC_LOG(LS_ERROR) << "Unable to parse the corpus config json file. Error:"
                       << error_message;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   RtpGeneratorOptions gen_options;
   for (const auto& video_stream_json : json["video_streams"]) {
-    absl::optional<RtpGeneratorOptions::VideoSendStreamConfig>
+    std::optional<RtpGeneratorOptions::VideoSendStreamConfig>
         video_stream_config = ParseVideoSendStreamConfig(video_stream_json);
     if (!video_stream_config.has_value()) {
       RTC_LOG(LS_ERROR) << "Unable to parse the corpus config json file";
-      return absl::nullopt;
+      return std::nullopt;
     }
     gen_options.video_streams.push_back(*video_stream_config);
   }
@@ -243,7 +243,7 @@
             &env_.clock(),
             test::CreateSquareFrameGenerator(send_config.video_width,
                                              send_config.video_height,
-                                             absl::nullopt, absl::nullopt),
+                                             std::nullopt, std::nullopt),
             send_config.video_fps, env_.task_queue_factory());
     frame_generator->Init();
 
diff --git a/rtc_tools/rtp_generator/rtp_generator.h b/rtc_tools/rtp_generator/rtp_generator.h
index 2f178d3..9a37f39 100644
--- a/rtc_tools/rtp_generator/rtp_generator.h
+++ b/rtc_tools/rtp_generator/rtp_generator.h
@@ -54,8 +54,8 @@
 };
 
 // Attempts to parse RtpGeneratorOptions from a JSON file. Any failures
-// will result in absl::nullopt.
-absl::optional<RtpGeneratorOptions> ParseRtpGeneratorOptionsFromFile(
+// will result in std::nullopt.
+std::optional<RtpGeneratorOptions> ParseRtpGeneratorOptionsFromFile(
     const std::string& options_file);
 
 // The RtpGenerator allows generating of corpus material intended to be
diff --git a/rtc_tools/video_encoder/encoded_image_file_writer.cc b/rtc_tools/video_encoder/encoded_image_file_writer.cc
index 624bce3..e495ca3 100644
--- a/rtc_tools/video_encoder/encoded_image_file_writer.cc
+++ b/rtc_tools/video_encoder/encoded_image_file_writer.cc
@@ -22,7 +22,7 @@
       CodecTypeToPayloadString(video_codec_setting.codecType);
 
   // Retrieve scalability mode information.
-  absl::optional<ScalabilityMode> scalability_mode =
+  std::optional<ScalabilityMode> scalability_mode =
       video_codec_setting.GetScalabilityMode();
   RTC_CHECK(scalability_mode);
   spatial_layers_ = ScalabilityModeToNumSpatialLayers(*scalability_mode);
diff --git a/rtc_tools/video_encoder/video_encoder.cc b/rtc_tools/video_encoder/video_encoder.cc
index 7e8a3d6..a6317d3 100644
--- a/rtc_tools/video_encoder/video_encoder.cc
+++ b/rtc_tools/video_encoder/video_encoder.cc
@@ -377,7 +377,7 @@
     RTC_CHECK_NE(codec_type, kVideoCodecGeneric);
 
     // Retrieve scalability mode information.
-    absl::optional<ScalabilityMode> scalability_mode =
+    std::optional<ScalabilityMode> scalability_mode =
         ScalabilityModeFromString(scalability_mode_string);
     RTC_CHECK(scalability_mode);
 
@@ -641,7 +641,7 @@
       frame_buffer_generator = webrtc::test::CreateSquareFrameGenerator(
           width, height,
           webrtc::test::FrameGeneratorInterface::OutputType::kI420,
-          absl::nullopt);
+          std::nullopt);
       RTC_CHECK(frame_buffer_generator);
 
       RTC_LOG(LS_INFO) << "CreateSquareFrameGenerator: " << width << "x"
diff --git a/rtc_tools/video_file_reader.cc b/rtc_tools/video_file_reader.cc
index 66fed42..5ec2bfd 100644
--- a/rtc_tools/video_file_reader.cc
+++ b/rtc_tools/video_file_reader.cc
@@ -11,11 +11,11 @@
 #include "rtc_tools/video_file_reader.h"
 
 #include <cstdio>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/make_ref_counted.h"
 #include "api/video/i420_buffer.h"
 #include "rtc_base/checks.h"
@@ -144,9 +144,9 @@
     header_line.push_back(static_cast<char>(c));
   }
 
-  absl::optional<int> width;
-  absl::optional<int> height;
-  absl::optional<float> fps;
+  std::optional<int> width;
+  std::optional<int> height;
+  std::optional<float> fps;
 
   std::vector<std::string> fields;
   rtc::tokenize(header_line, ' ', &fields);
@@ -173,9 +173,9 @@
         std::vector<std::string> fraction;
         rtc::tokenize(suffix, ':', &fraction);
         if (fraction.size() == 2) {
-          const absl::optional<int> numerator =
+          const std::optional<int> numerator =
               rtc::StringToNumber<int>(fraction[0]);
-          const absl::optional<int> denominator =
+          const std::optional<int> denominator =
               rtc::StringToNumber<int>(fraction[1]);
           if (numerator && denominator && *denominator != 0)
             fps = *numerator / static_cast<float>(*denominator);
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index a03d737..6a48cbf 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -36,7 +36,6 @@
   deps = [
     "../api:audio_options_api",
     "../api:libjingle_peerconnection_api",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -453,7 +452,6 @@
           "../media:rtc_media_base",
           "../rtc_base:checks",
           "../rtc_base:logging",
-          "//third_party/abseil-cpp/absl/types:optional",
         ]
 
         configs += [
diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn
index 9add4ae..f95c749 100644
--- a/sdk/android/BUILD.gn
+++ b/sdk/android/BUILD.gn
@@ -588,7 +588,6 @@
       "../../system_wrappers:field_trial",
       "../../system_wrappers:metrics",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
       "//third_party/jni_zero",
     ]
   }
@@ -690,7 +689,6 @@
       "../../rtc_base:timeutils",
       "../../rtc_base/synchronization:mutex",
       "//third_party/abseil-cpp/absl/memory",
-      "//third_party/abseil-cpp/absl/types:optional",
       "//third_party/jni_zero",
       "//third_party/libyuv",
     ]
@@ -811,7 +809,6 @@
       "../../stats:rtc_stats",
       "../../system_wrappers:field_trial",
       "//third_party/abseil-cpp/absl/memory",
-      "//third_party/abseil-cpp/absl/types:optional",
       "//third_party/jni_zero",
     ]
   }
@@ -959,7 +956,6 @@
       "../../api:sequence_checker",
       "//api:array_view",
       "//rtc_base:checks",
-      "//third_party/abseil-cpp/absl/types:optional",
       "//third_party/jni_zero",
     ]
   }
@@ -1190,7 +1186,6 @@
       "../../rtc_base:checks",
       "../../rtc_base:logging",
       "../../system_wrappers:metrics",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -1217,7 +1212,6 @@
       "../../rtc_base:timeutils",
       "../../system_wrappers:field_trial",
       "../../system_wrappers:metrics",
-      "//third_party/abseil-cpp/absl/types:optional",
       "//third_party/jni_zero",
     ]
   }
@@ -1278,7 +1272,6 @@
       "../../rtc_base:macromagic",
       "../../rtc_base:platform_thread",
       "../../rtc_base:timeutils",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
diff --git a/sdk/android/native_api/jni/java_types.cc b/sdk/android/native_api/jni/java_types.cc
index 540963f..ab730c4 100644
--- a/sdk/android/native_api/jni/java_types.cc
+++ b/sdk/android/native_api/jni/java_types.cc
@@ -132,27 +132,27 @@
   return JNI_Long::Java_Long_longValue(env, j_long);
 }
 
-absl::optional<bool> JavaToNativeOptionalBool(
+std::optional<bool> JavaToNativeOptionalBool(
     JNIEnv* jni,
     const jni_zero::JavaRef<jobject>& boolean) {
   if (IsNull(jni, boolean))
-    return absl::nullopt;
+    return std::nullopt;
   return JNI_Boolean::Java_Boolean_booleanValue(jni, boolean);
 }
 
-absl::optional<double> JavaToNativeOptionalDouble(
+std::optional<double> JavaToNativeOptionalDouble(
     JNIEnv* jni,
     const jni_zero::JavaRef<jobject>& j_double) {
   if (IsNull(jni, j_double))
-    return absl::nullopt;
+    return std::nullopt;
   return JNI_Double::Java_Double_doubleValue(jni, j_double);
 }
 
-absl::optional<int32_t> JavaToNativeOptionalInt(
+std::optional<int32_t> JavaToNativeOptionalInt(
     JNIEnv* jni,
     const jni_zero::JavaRef<jobject>& integer) {
   if (IsNull(jni, integer))
-    return absl::nullopt;
+    return std::nullopt;
   return JNI_Integer::Java_Integer_intValue(jni, integer);
 }
 
@@ -213,19 +213,19 @@
 
 ScopedJavaLocalRef<jobject> NativeToJavaDouble(
     JNIEnv* jni,
-    const absl::optional<double>& optional_double) {
+    const std::optional<double>& optional_double) {
   return optional_double ? NativeToJavaDouble(jni, *optional_double) : nullptr;
 }
 
 ScopedJavaLocalRef<jobject> NativeToJavaInteger(
     JNIEnv* jni,
-    const absl::optional<int32_t>& optional_int) {
+    const std::optional<int32_t>& optional_int) {
   return optional_int ? NativeToJavaInteger(jni, *optional_int) : nullptr;
 }
 
 ScopedJavaLocalRef<jstring> NativeToJavaString(
     JNIEnv* jni,
-    const absl::optional<std::string>& str) {
+    const std::optional<std::string>& str) {
   return str ? NativeToJavaString(jni, *str) : nullptr;
 }
 
diff --git a/sdk/android/native_api/jni/java_types.h b/sdk/android/native_api/jni/java_types.h
index a4deda1..13dc6ae 100644
--- a/sdk/android/native_api/jni/java_types.h
+++ b/sdk/android/native_api/jni/java_types.h
@@ -21,10 +21,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/sequence_checker.h"
 #include "rtc_base/checks.h"
@@ -134,13 +134,13 @@
 
 int64_t JavaToNativeLong(JNIEnv* env, const jni_zero::JavaRef<jobject>& j_long);
 
-absl::optional<bool> JavaToNativeOptionalBool(
+std::optional<bool> JavaToNativeOptionalBool(
     JNIEnv* jni,
     const jni_zero::JavaRef<jobject>& boolean);
-absl::optional<double> JavaToNativeOptionalDouble(
+std::optional<double> JavaToNativeOptionalDouble(
     JNIEnv* jni,
     const jni_zero::JavaRef<jobject>& j_double);
-absl::optional<int32_t> JavaToNativeOptionalInt(
+std::optional<int32_t> JavaToNativeOptionalInt(
     JNIEnv* jni,
     const jni_zero::JavaRef<jobject>& integer);
 
@@ -211,13 +211,13 @@
 
 ScopedJavaLocalRef<jobject> NativeToJavaDouble(
     JNIEnv* jni,
-    const absl::optional<double>& optional_double);
+    const std::optional<double>& optional_double);
 ScopedJavaLocalRef<jobject> NativeToJavaInteger(
     JNIEnv* jni,
-    const absl::optional<int32_t>& optional_int);
+    const std::optional<int32_t>& optional_int);
 ScopedJavaLocalRef<jstring> NativeToJavaString(
     JNIEnv* jni,
-    const absl::optional<std::string>& str);
+    const std::optional<std::string>& str);
 
 // Helper function for converting std::vector<T> into a Java array.
 template <typename T, typename Convert>
diff --git a/sdk/android/native_api/video/video_source.cc b/sdk/android/native_api/video/video_source.cc
index e967c2a..6f66bd1 100644
--- a/sdk/android/native_api/video/video_source.cc
+++ b/sdk/android/native_api/video/video_source.cc
@@ -76,7 +76,7 @@
     return android_video_track_source_->is_screencast();
   }
 
-  absl::optional<bool> needs_denoising() const override {
+  std::optional<bool> needs_denoising() const override {
     return android_video_track_source_->needs_denoising();
   }
 
diff --git a/sdk/android/src/jni/android_network_monitor.cc b/sdk/android/src/jni/android_network_monitor.cc
index a656a34..f7a9f69 100644
--- a/sdk/android/src/jni/android_network_monitor.cc
+++ b/sdk/android/src/jni/android_network_monitor.cc
@@ -317,7 +317,7 @@
     return rtc::NetworkBindingResult::NOT_IMPLEMENTED;
   }
 
-  absl::optional<NetworkHandle> network_handle =
+  std::optional<NetworkHandle> network_handle =
       FindNetworkHandleFromAddressOrName(address, if_name);
   if (!network_handle) {
     RTC_LOG(LS_WARNING)
@@ -445,7 +445,7 @@
   InvokeNetworksChangedCallback();
 }
 
-absl::optional<NetworkHandle>
+std::optional<NetworkHandle>
 AndroidNetworkMonitor::FindNetworkHandleFromAddressOrName(
     const rtc::IPAddress& ip_address,
     absl::string_view if_name) const {
@@ -458,21 +458,20 @@
                                        return AddressMatch(ip_address, address);
                                      });
       if (address_it != addresses.end()) {
-        return absl::make_optional(iter.first);
+        return std::make_optional(iter.first);
       }
     }
   } else {
     auto iter = network_handle_by_address_.find(ip_address);
     if (iter != network_handle_by_address_.end()) {
-      return absl::make_optional(iter->second);
+      return std::make_optional(iter->second);
     }
   }
 
   return FindNetworkHandleFromIfname(if_name);
 }
 
-absl::optional<NetworkHandle>
-AndroidNetworkMonitor::FindNetworkHandleFromIfname(
+std::optional<NetworkHandle> AndroidNetworkMonitor::FindNetworkHandleFromIfname(
     absl::string_view if_name) const {
   RTC_DCHECK_RUN_ON(network_thread_);
 
@@ -486,12 +485,12 @@
       // Use substring match so that e.g if_name="v4-wlan0" is matched
       // agains iter="wlan0"
       if (if_name.find(iter.first) != absl::string_view::npos) {
-        return absl::make_optional(iter.second);
+        return std::make_optional(iter.second);
       }
     }
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void AndroidNetworkMonitor::OnNetworkDisconnected_n(NetworkHandle handle) {
diff --git a/sdk/android/src/jni/android_network_monitor.h b/sdk/android/src/jni/android_network_monitor.h
index f94650b..0d1374a 100644
--- a/sdk/android/src/jni/android_network_monitor.h
+++ b/sdk/android/src/jni/android_network_monitor.h
@@ -14,11 +14,11 @@
 #include <stdint.h>
 
 #include <map>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/task_queue/pending_task_safety_flag.h"
 #include "rtc_base/network_monitor.h"
@@ -118,7 +118,7 @@
   void OnNetworkConnected_n(const NetworkInformation& network_info);
 
   // Visible for testing.
-  absl::optional<NetworkHandle> FindNetworkHandleFromAddressOrName(
+  std::optional<NetworkHandle> FindNetworkHandleFromAddressOrName(
       const rtc::IPAddress& address,
       absl::string_view ifname) const;
 
@@ -129,7 +129,7 @@
                              rtc::NetworkPreference preference);
 
   rtc::NetworkPreference GetNetworkPreference(rtc::AdapterType) const;
-  absl::optional<NetworkHandle> FindNetworkHandleFromIfname(
+  std::optional<NetworkHandle> FindNetworkHandleFromIfname(
       absl::string_view ifname) const;
 
   const int android_sdk_int_;
diff --git a/sdk/android/src/jni/android_video_track_source.cc b/sdk/android/src/jni/android_video_track_source.cc
index e7bf5b9..c009ca8 100644
--- a/sdk/android/src/jni/android_video_track_source.cc
+++ b/sdk/android/src/jni/android_video_track_source.cc
@@ -29,11 +29,11 @@
   return static_cast<VideoRotation>(rotation);
 }
 
-absl::optional<std::pair<int, int>> OptionalAspectRatio(jint j_width,
-                                                        jint j_height) {
+std::optional<std::pair<int, int>> OptionalAspectRatio(jint j_width,
+                                                       jint j_height) {
   if (j_width > 0 && j_height > 0)
     return std::pair<int, int>(j_width, j_height);
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace
@@ -54,7 +54,7 @@
   return is_screencast_.load();
 }
 
-absl::optional<bool> AndroidVideoTrackSource::needs_denoising() const {
+std::optional<bool> AndroidVideoTrackSource::needs_denoising() const {
   return false;
 }
 
diff --git a/sdk/android/src/jni/android_video_track_source.h b/sdk/android/src/jni/android_video_track_source.h
index 9099ce6..b69a23a 100644
--- a/sdk/android/src/jni/android_video_track_source.h
+++ b/sdk/android/src/jni/android_video_track_source.h
@@ -41,7 +41,7 @@
   // Indicates that the encoder should denoise video before encoding it.
   // If it is not set, the default configuration is used which is different
   // depending on video codec.
-  absl::optional<bool> needs_denoising() const override;
+  std::optional<bool> needs_denoising() const override;
 
   void SetState(SourceState state);
 
diff --git a/sdk/android/src/jni/audio_device/aaudio_player.cc b/sdk/android/src/jni/audio_device/aaudio_player.cc
index 2b745b3..c7bae74 100644
--- a/sdk/android/src/jni/audio_device/aaudio_player.cc
+++ b/sdk/android/src/jni/audio_device/aaudio_player.cc
@@ -133,16 +133,16 @@
   return -1;
 }
 
-absl::optional<uint32_t> AAudioPlayer::SpeakerVolume() const {
-  return absl::nullopt;
+std::optional<uint32_t> AAudioPlayer::SpeakerVolume() const {
+  return std::nullopt;
 }
 
-absl::optional<uint32_t> AAudioPlayer::MaxSpeakerVolume() const {
-  return absl::nullopt;
+std::optional<uint32_t> AAudioPlayer::MaxSpeakerVolume() const {
+  return std::nullopt;
 }
 
-absl::optional<uint32_t> AAudioPlayer::MinSpeakerVolume() const {
-  return absl::nullopt;
+std::optional<uint32_t> AAudioPlayer::MinSpeakerVolume() const {
+  return std::nullopt;
 }
 
 void AAudioPlayer::OnErrorCallback(aaudio_result_t error) {
diff --git a/sdk/android/src/jni/audio_device/aaudio_player.h b/sdk/android/src/jni/audio_device/aaudio_player.h
index ddf948c..1fe581b 100644
--- a/sdk/android/src/jni/audio_device/aaudio_player.h
+++ b/sdk/android/src/jni/audio_device/aaudio_player.h
@@ -14,8 +14,8 @@
 #include <aaudio/AAudio.h>
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_device_defines.h"
 #include "api/sequence_checker.h"
 #include "api/task_queue/task_queue_base.h"
@@ -71,9 +71,9 @@
   // Not implemented in AAudio.
   bool SpeakerVolumeIsAvailable() override;
   int SetSpeakerVolume(uint32_t volume) override;
-  absl::optional<uint32_t> SpeakerVolume() const override;
-  absl::optional<uint32_t> MaxSpeakerVolume() const override;
-  absl::optional<uint32_t> MinSpeakerVolume() const override;
+  std::optional<uint32_t> SpeakerVolume() const override;
+  std::optional<uint32_t> MaxSpeakerVolume() const override;
+  std::optional<uint32_t> MinSpeakerVolume() const override;
 
  protected:
   // AAudioObserverInterface implementation.
diff --git a/sdk/android/src/jni/audio_device/audio_device_module.cc b/sdk/android/src/jni/audio_device/audio_device_module.cc
index 3c910b8..eb1c150 100644
--- a/sdk/android/src/jni/audio_device/audio_device_module.cc
+++ b/sdk/android/src/jni/audio_device/audio_device_module.cc
@@ -353,7 +353,7 @@
     RTC_DLOG(LS_INFO) << __FUNCTION__;
     if (!initialized_)
       return -1;
-    absl::optional<uint32_t> volume = output_->SpeakerVolume();
+    std::optional<uint32_t> volume = output_->SpeakerVolume();
     if (!volume)
       return -1;
     *output_volume = *volume;
@@ -365,7 +365,7 @@
     RTC_DLOG(LS_INFO) << __FUNCTION__;
     if (!initialized_)
       return -1;
-    absl::optional<uint32_t> max_volume = output_->MaxSpeakerVolume();
+    std::optional<uint32_t> max_volume = output_->MaxSpeakerVolume();
     if (!max_volume)
       return -1;
     *output_max_volume = *max_volume;
@@ -376,7 +376,7 @@
     RTC_DLOG(LS_INFO) << __FUNCTION__;
     if (!initialized_)
       return -1;
-    absl::optional<uint32_t> min_volume = output_->MinSpeakerVolume();
+    std::optional<uint32_t> min_volume = output_->MinSpeakerVolume();
     if (!min_volume)
       return -1;
     *output_min_volume = *min_volume;
@@ -575,9 +575,9 @@
     return output_->GetPlayoutUnderrunCount();
   }
 
-  absl::optional<Stats> GetStats() const override {
+  std::optional<Stats> GetStats() const override {
     if (!initialized_)
-      return absl::nullopt;
+      return std::nullopt;
     return output_->GetStats();
   }
 
diff --git a/sdk/android/src/jni/audio_device/audio_device_module.h b/sdk/android/src/jni/audio_device/audio_device_module.h
index 92dbb21..c06991f 100644
--- a/sdk/android/src/jni/audio_device/audio_device_module.h
+++ b/sdk/android/src/jni/audio_device/audio_device_module.h
@@ -12,8 +12,8 @@
 #define SDK_ANDROID_SRC_JNI_AUDIO_DEVICE_AUDIO_DEVICE_MODULE_H_
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_device.h"
 #include "sdk/android/native_api/jni/scoped_java_ref.h"
 
@@ -61,13 +61,13 @@
   virtual bool Playing() const = 0;
   virtual bool SpeakerVolumeIsAvailable() = 0;
   virtual int SetSpeakerVolume(uint32_t volume) = 0;
-  virtual absl::optional<uint32_t> SpeakerVolume() const = 0;
-  virtual absl::optional<uint32_t> MaxSpeakerVolume() const = 0;
-  virtual absl::optional<uint32_t> MinSpeakerVolume() const = 0;
+  virtual std::optional<uint32_t> SpeakerVolume() const = 0;
+  virtual std::optional<uint32_t> MaxSpeakerVolume() const = 0;
+  virtual std::optional<uint32_t> MinSpeakerVolume() const = 0;
   virtual void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) = 0;
   virtual int GetPlayoutUnderrunCount() = 0;
-  virtual absl::optional<AudioDeviceModule::Stats> GetStats() const {
-    return absl::nullopt;
+  virtual std::optional<AudioDeviceModule::Stats> GetStats() const {
+    return std::nullopt;
   }
 };
 
diff --git a/sdk/android/src/jni/audio_device/audio_track_jni.cc b/sdk/android/src/jni/audio_device/audio_track_jni.cc
index 4554b11..464805f 100644
--- a/sdk/android/src/jni/audio_device/audio_track_jni.cc
+++ b/sdk/android/src/jni/audio_device/audio_track_jni.cc
@@ -194,17 +194,17 @@
              : -1;
 }
 
-absl::optional<uint32_t> AudioTrackJni::MaxSpeakerVolume() const {
+std::optional<uint32_t> AudioTrackJni::MaxSpeakerVolume() const {
   RTC_DCHECK(thread_checker_.IsCurrent());
   return Java_WebRtcAudioTrack_getStreamMaxVolume(env_, j_audio_track_);
 }
 
-absl::optional<uint32_t> AudioTrackJni::MinSpeakerVolume() const {
+std::optional<uint32_t> AudioTrackJni::MinSpeakerVolume() const {
   RTC_DCHECK(thread_checker_.IsCurrent());
   return 0;
 }
 
-absl::optional<uint32_t> AudioTrackJni::SpeakerVolume() const {
+std::optional<uint32_t> AudioTrackJni::SpeakerVolume() const {
   RTC_DCHECK(thread_checker_.IsCurrent());
   const uint32_t volume =
       Java_WebRtcAudioTrack_getStreamVolume(env_, j_audio_track_);
diff --git a/sdk/android/src/jni/audio_device/audio_track_jni.h b/sdk/android/src/jni/audio_device/audio_track_jni.h
index 41fbb0a..fee50ef 100644
--- a/sdk/android/src/jni/audio_device/audio_track_jni.h
+++ b/sdk/android/src/jni/audio_device/audio_track_jni.h
@@ -14,8 +14,8 @@
 #include <jni.h>
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_device_defines.h"
 #include "api/sequence_checker.h"
 #include "modules/audio_device/audio_device_buffer.h"
@@ -63,9 +63,9 @@
 
   bool SpeakerVolumeIsAvailable() override;
   int SetSpeakerVolume(uint32_t volume) override;
-  absl::optional<uint32_t> SpeakerVolume() const override;
-  absl::optional<uint32_t> MaxSpeakerVolume() const override;
-  absl::optional<uint32_t> MinSpeakerVolume() const override;
+  std::optional<uint32_t> SpeakerVolume() const override;
+  std::optional<uint32_t> MaxSpeakerVolume() const override;
+  std::optional<uint32_t> MinSpeakerVolume() const override;
   int GetPlayoutUnderrunCount() override;
 
   void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override;
diff --git a/sdk/android/src/jni/audio_device/opensles_player.cc b/sdk/android/src/jni/audio_device/opensles_player.cc
index 6300a3a..588178d 100644
--- a/sdk/android/src/jni/audio_device/opensles_player.cc
+++ b/sdk/android/src/jni/audio_device/opensles_player.cc
@@ -182,16 +182,16 @@
   return -1;
 }
 
-absl::optional<uint32_t> OpenSLESPlayer::SpeakerVolume() const {
-  return absl::nullopt;
+std::optional<uint32_t> OpenSLESPlayer::SpeakerVolume() const {
+  return std::nullopt;
 }
 
-absl::optional<uint32_t> OpenSLESPlayer::MaxSpeakerVolume() const {
-  return absl::nullopt;
+std::optional<uint32_t> OpenSLESPlayer::MaxSpeakerVolume() const {
+  return std::nullopt;
 }
 
-absl::optional<uint32_t> OpenSLESPlayer::MinSpeakerVolume() const {
-  return absl::nullopt;
+std::optional<uint32_t> OpenSLESPlayer::MinSpeakerVolume() const {
+  return std::nullopt;
 }
 
 void OpenSLESPlayer::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) {
diff --git a/sdk/android/src/jni/audio_device/opensles_player.h b/sdk/android/src/jni/audio_device/opensles_player.h
index 3d63bd7..8d6c2ce 100644
--- a/sdk/android/src/jni/audio_device/opensles_player.h
+++ b/sdk/android/src/jni/audio_device/opensles_player.h
@@ -16,8 +16,8 @@
 #include <SLES/OpenSLES_AndroidConfiguration.h>
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/audio/audio_device_defines.h"
 #include "api/scoped_refptr.h"
 #include "api/sequence_checker.h"
@@ -77,9 +77,9 @@
 
   bool SpeakerVolumeIsAvailable() override;
   int SetSpeakerVolume(uint32_t volume) override;
-  absl::optional<uint32_t> SpeakerVolume() const override;
-  absl::optional<uint32_t> MaxSpeakerVolume() const override;
-  absl::optional<uint32_t> MinSpeakerVolume() const override;
+  std::optional<uint32_t> SpeakerVolume() const override;
+  std::optional<uint32_t> MaxSpeakerVolume() const override;
+  std::optional<uint32_t> MinSpeakerVolume() const override;
 
   void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override;
 
diff --git a/sdk/android/src/jni/pc/crypto_options.cc b/sdk/android/src/jni/pc/crypto_options.cc
index af5f195..f37ebc1 100644
--- a/sdk/android/src/jni/pc/crypto_options.cc
+++ b/sdk/android/src/jni/pc/crypto_options.cc
@@ -15,11 +15,11 @@
 namespace webrtc {
 namespace jni {
 
-absl::optional<CryptoOptions> JavaToNativeOptionalCryptoOptions(
+std::optional<CryptoOptions> JavaToNativeOptionalCryptoOptions(
     JNIEnv* jni,
     const JavaRef<jobject>& j_crypto_options) {
   if (j_crypto_options.is_null()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   ScopedJavaLocalRef<jobject> j_srtp =
@@ -36,7 +36,7 @@
       Java_Srtp_getEnableEncryptedRtpHeaderExtensions(jni, j_srtp);
   native_crypto_options.sframe.require_frame_encryption =
       Java_SFrame_getRequireFrameEncryption(jni, j_sframe);
-  return absl::optional<CryptoOptions>(native_crypto_options);
+  return std::optional<CryptoOptions>(native_crypto_options);
 }
 
 }  // namespace jni
diff --git a/sdk/android/src/jni/pc/crypto_options.h b/sdk/android/src/jni/pc/crypto_options.h
index a9c8f26..f82f218 100644
--- a/sdk/android/src/jni/pc/crypto_options.h
+++ b/sdk/android/src/jni/pc/crypto_options.h
@@ -13,14 +13,15 @@
 
 #include <jni.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/crypto/crypto_options.h"
 #include "sdk/android/native_api/jni/scoped_java_ref.h"
 
 namespace webrtc {
 namespace jni {
 
-absl::optional<CryptoOptions> JavaToNativeOptionalCryptoOptions(
+std::optional<CryptoOptions> JavaToNativeOptionalCryptoOptions(
     JNIEnv* jni,
     const JavaRef<jobject>& j_crypto_options);
 
diff --git a/sdk/android/src/jni/pc/ice_candidate.cc b/sdk/android/src/jni/pc/ice_candidate.cc
index af92ff8..fdfe1ec 100644
--- a/sdk/android/src/jni/pc/ice_candidate.cc
+++ b/sdk/android/src/jni/pc/ice_candidate.cc
@@ -228,13 +228,13 @@
   return PeerConnectionInterface::kTlsCertPolicySecure;
 }
 
-absl::optional<rtc::AdapterType> JavaToNativeNetworkPreference(
+std::optional<rtc::AdapterType> JavaToNativeNetworkPreference(
     JNIEnv* jni,
     const JavaRef<jobject>& j_network_preference) {
   std::string enum_name = GetJavaEnumName(jni, j_network_preference);
 
   if (enum_name == "UNKNOWN")
-    return absl::nullopt;
+    return std::nullopt;
 
   if (enum_name == "ETHERNET")
     return rtc::ADAPTER_TYPE_ETHERNET;
@@ -252,7 +252,7 @@
     return rtc::ADAPTER_TYPE_LOOPBACK;
 
   RTC_CHECK(false) << "Unexpected NetworkPreference enum_name " << enum_name;
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace jni
diff --git a/sdk/android/src/jni/pc/ice_candidate.h b/sdk/android/src/jni/pc/ice_candidate.h
index 4bdeea6..4126294 100644
--- a/sdk/android/src/jni/pc/ice_candidate.h
+++ b/sdk/android/src/jni/pc/ice_candidate.h
@@ -79,7 +79,7 @@
     JNIEnv* jni,
     const JavaRef<jobject>& j_ice_server_tls_cert_policy);
 
-absl::optional<rtc::AdapterType> JavaToNativeNetworkPreference(
+std::optional<rtc::AdapterType> JavaToNativeNetworkPreference(
     JNIEnv* jni,
     const JavaRef<jobject>& j_network_preference);
 
diff --git a/sdk/android/src/jni/pc/peer_connection_factory.cc b/sdk/android/src/jni/pc/peer_connection_factory.cc
index e98ac6f..2619140 100644
--- a/sdk/android/src/jni/pc/peer_connection_factory.cc
+++ b/sdk/android/src/jni/pc/peer_connection_factory.cc
@@ -76,12 +76,12 @@
   });
 }
 
-absl::optional<PeerConnectionFactoryInterface::Options>
+std::optional<PeerConnectionFactoryInterface::Options>
 JavaToNativePeerConnectionFactoryOptions(
     JNIEnv* jni,
     const jni_zero::JavaRef<jobject>& j_options) {
   if (j_options.is_null())
-    return absl::nullopt;
+    return std::nullopt;
 
   PeerConnectionFactoryInterface::Options native_options;
 
@@ -262,7 +262,7 @@
   signaling_thread->SetName("signaling_thread", NULL);
   RTC_CHECK(signaling_thread->Start()) << "Failed to start thread";
 
-  const absl::optional<PeerConnectionFactoryInterface::Options> options =
+  const std::optional<PeerConnectionFactoryInterface::Options> options =
       JavaToNativePeerConnectionFactoryOptions(jni, joptions);
 
   PeerConnectionFactoryDependencies dependencies;
@@ -447,7 +447,7 @@
     if (key_type != rtc::KT_DEFAULT) {
       rtc::scoped_refptr<rtc::RTCCertificate> certificate =
           rtc::RTCCertificateGenerator::GenerateCertificate(
-              rtc::KeyParams(key_type), absl::nullopt);
+              rtc::KeyParams(key_type), std::nullopt);
       if (!certificate) {
         RTC_LOG(LS_ERROR) << "Failed to generate certificate. KeyType: "
                           << key_type;
diff --git a/sdk/android/src/jni/pc/rtp_transceiver.cc b/sdk/android/src/jni/pc/rtp_transceiver.cc
index 3746b11..c2b4920 100644
--- a/sdk/android/src/jni/pc/rtp_transceiver.cc
+++ b/sdk/android/src/jni/pc/rtp_transceiver.cc
@@ -96,7 +96,7 @@
 ScopedJavaLocalRef<jstring> JNI_RtpTransceiver_GetMid(
     JNIEnv* jni,
     jlong j_rtp_transceiver_pointer) {
-  absl::optional<std::string> mid =
+  std::optional<std::string> mid =
       reinterpret_cast<RtpTransceiverInterface*>(j_rtp_transceiver_pointer)
           ->mid();
   return NativeToJavaString(jni, mid);
@@ -135,7 +135,7 @@
 ScopedJavaLocalRef<jobject> JNI_RtpTransceiver_CurrentDirection(
     JNIEnv* jni,
     jlong j_rtp_transceiver_pointer) {
-  absl::optional<RtpTransceiverDirection> direction =
+  std::optional<RtpTransceiverDirection> direction =
       reinterpret_cast<RtpTransceiverInterface*>(j_rtp_transceiver_pointer)
           ->current_direction();
   return direction ? NativeToJavaRtpTransceiverDirection(jni, *direction)
diff --git a/sdk/android/src/jni/pc/session_description.cc b/sdk/android/src/jni/pc/session_description.cc
index bbac721..64b2dae 100644
--- a/sdk/android/src/jni/pc/session_description.cc
+++ b/sdk/android/src/jni/pc/session_description.cc
@@ -27,7 +27,7 @@
       jni, Java_SessionDescription_getTypeInCanonicalForm(jni, j_sdp));
   std::string std_description =
       JavaToStdString(jni, Java_SessionDescription_getDescription(jni, j_sdp));
-  absl::optional<SdpType> sdp_type_maybe = SdpTypeFromString(std_type);
+  std::optional<SdpType> sdp_type_maybe = SdpTypeFromString(std_type);
   if (!sdp_type_maybe) {
     RTC_LOG(LS_ERROR) << "Unexpected SDP type: " << std_type;
     return nullptr;
diff --git a/sdk/android/src/jni/video_decoder_wrapper.cc b/sdk/android/src/jni/video_decoder_wrapper.cc
index eaeeb2d..dae1c08 100644
--- a/sdk/android/src/jni/video_decoder_wrapper.cc
+++ b/sdk/android/src/jni/video_decoder_wrapper.cc
@@ -36,9 +36,9 @@
 const int64_t kNumRtpTicksPerMillisec = 90000 / rtc::kNumMillisecsPerSec;
 
 template <typename Dst, typename Src>
-inline absl::optional<Dst> cast_optional(const absl::optional<Src>& value) {
-  return value ? absl::optional<Dst>(rtc::dchecked_cast<Dst, Src>(*value))
-               : absl::nullopt;
+inline std::optional<Dst> cast_optional(const std::optional<Src>& value) {
+  return value ? std::optional<Dst>(rtc::dchecked_cast<Dst, Src>(*value))
+               : std::nullopt;
 }
 }  // namespace
 
@@ -110,7 +110,7 @@
   frame_extra_info.timestamp_rtp = input_image.RtpTimestamp();
   frame_extra_info.timestamp_ntp = input_image.ntp_time_ms_;
   frame_extra_info.qp =
-      qp_parsing_enabled_ ? ParseQP(input_image) : absl::nullopt;
+      qp_parsing_enabled_ ? ParseQP(input_image) : std::nullopt;
   {
     MutexLock lock(&frame_extra_infos_lock_);
     frame_extra_infos_.push_back(frame_extra_info);
@@ -188,10 +188,10 @@
       JavaToNativeFrame(env, j_frame, frame_extra_info.timestamp_rtp);
   frame.set_ntp_time_ms(frame_extra_info.timestamp_ntp);
 
-  absl::optional<int32_t> decoding_time_ms =
+  std::optional<int32_t> decoding_time_ms =
       JavaToNativeOptionalInt(env, j_decode_time_ms);
 
-  absl::optional<uint8_t> decoder_qp =
+  std::optional<uint8_t> decoder_qp =
       cast_optional<uint8_t, int32_t>(JavaToNativeOptionalInt(env, j_qp));
   // If the decoder provides QP values itself, no need to parse the bitstream.
   // Enable QP parsing if decoder does not provide QP values itself.
@@ -230,13 +230,13 @@
   return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
 }
 
-absl::optional<uint8_t> VideoDecoderWrapper::ParseQP(
+std::optional<uint8_t> VideoDecoderWrapper::ParseQP(
     const EncodedImage& input_image) {
   if (input_image.qp_ != -1) {
     return input_image.qp_;
   }
 
-  absl::optional<uint8_t> qp;
+  std::optional<uint8_t> qp;
   switch (decoder_settings_.codec_type()) {
     case kVideoCodecVP8: {
       int qp_int;
diff --git a/sdk/android/src/jni/video_decoder_wrapper.h b/sdk/android/src/jni/video_decoder_wrapper.h
index 5e397f1..ff2ae29 100644
--- a/sdk/android/src/jni/video_decoder_wrapper.h
+++ b/sdk/android/src/jni/video_decoder_wrapper.h
@@ -65,7 +65,7 @@
 
     uint32_t timestamp_rtp;
     int64_t timestamp_ntp;
-    absl::optional<uint8_t> qp;
+    std::optional<uint8_t> qp;
 
     FrameExtraInfo();
     FrameExtraInfo(const FrameExtraInfo&);
@@ -81,7 +81,7 @@
                            const char* method_name)
       RTC_RUN_ON(decoder_thread_checker_);
 
-  absl::optional<uint8_t> ParseQP(const EncodedImage& input_image)
+  std::optional<uint8_t> ParseQP(const EncodedImage& input_image)
       RTC_RUN_ON(decoder_thread_checker_);
 
   const ScopedJavaGlobalRef<jobject> decoder_;
diff --git a/sdk/android/src/jni/video_encoder_factory_wrapper.cc b/sdk/android/src/jni/video_encoder_factory_wrapper.cc
index 78aa145..709fa58 100644
--- a/sdk/android/src/jni/video_encoder_factory_wrapper.cc
+++ b/sdk/android/src/jni/video_encoder_factory_wrapper.cc
@@ -37,36 +37,36 @@
                                                j_codec_info);
   }
 
-  absl::optional<SdpVideoFormat> OnAvailableBitrate(
+  std::optional<SdpVideoFormat> OnAvailableBitrate(
       const DataRate& rate) override {
     JNIEnv* jni = AttachCurrentThreadIfNeeded();
     ScopedJavaLocalRef<jobject> codec_info =
         Java_VideoEncoderSelector_onAvailableBitrate(jni, encoder_selector_,
                                                      rate.kbps<int>());
     if (codec_info.is_null()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return VideoCodecInfoToSdpVideoFormat(jni, codec_info);
   }
 
-  absl::optional<SdpVideoFormat> OnResolutionChange(
+  std::optional<SdpVideoFormat> OnResolutionChange(
       const RenderResolution& resolution) override {
     JNIEnv* jni = AttachCurrentThreadIfNeeded();
     ScopedJavaLocalRef<jobject> codec_info =
         Java_VideoEncoderSelector_onResolutionChange(
             jni, encoder_selector_, resolution.Width(), resolution.Height());
     if (codec_info.is_null()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return VideoCodecInfoToSdpVideoFormat(jni, codec_info);
   }
 
-  absl::optional<SdpVideoFormat> OnEncoderBroken() override {
+  std::optional<SdpVideoFormat> OnEncoderBroken() override {
     JNIEnv* jni = AttachCurrentThreadIfNeeded();
     ScopedJavaLocalRef<jobject> codec_info =
         Java_VideoEncoderSelector_onEncoderBroken(jni, encoder_selector_);
     if (codec_info.is_null()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return VideoCodecInfoToSdpVideoFormat(jni, codec_info);
   }
diff --git a/sdk/android/src/jni/video_encoder_wrapper.cc b/sdk/android/src/jni/video_encoder_wrapper.cc
index 92e6c80..08112f7 100644
--- a/sdk/android/src/jni/video_encoder_wrapper.cc
+++ b/sdk/android/src/jni/video_encoder_wrapper.cc
@@ -201,10 +201,10 @@
   if (!isOn)
     return ScalingSettings::kOff;
 
-  absl::optional<int> low = JavaToNativeOptionalInt(
+  std::optional<int> low = JavaToNativeOptionalInt(
       jni,
       Java_VideoEncoderWrapper_getScalingSettingsLow(jni, j_scaling_settings));
-  absl::optional<int> high = JavaToNativeOptionalInt(
+  std::optional<int> high = JavaToNativeOptionalInt(
       jni,
       Java_VideoEncoderWrapper_getScalingSettingsHigh(jni, j_scaling_settings));
 
diff --git a/sdk/android/src/jni/video_encoder_wrapper.h b/sdk/android/src/jni/video_encoder_wrapper.h
index d0b3893..651f162 100644
--- a/sdk/android/src/jni/video_encoder_wrapper.h
+++ b/sdk/android/src/jni/video_encoder_wrapper.h
@@ -15,10 +15,10 @@
 
 #include <deque>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/video_codecs/video_encoder.h"
 #include "common_video/h264/h264_bitstream_parser.h"
 #ifdef RTC_ENABLE_H265
@@ -101,7 +101,7 @@
   EncodedImageCallback* callback_;
   bool initialized_;
   int num_resets_;
-  absl::optional<VideoEncoder::Capabilities> capabilities_;
+  std::optional<VideoEncoder::Capabilities> capabilities_;
   int number_of_cores_;
   VideoCodec codec_settings_;
   EncoderInfo encoder_info_;
diff --git a/sdk/media_constraints.cc b/sdk/media_constraints.cc
index 88261e7..1281353 100644
--- a/sdk/media_constraints.cc
+++ b/sdk/media_constraints.cc
@@ -10,7 +10,8 @@
 
 #include "sdk/media_constraints.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/peer_connection_interface.h"
 
 namespace webrtc {
@@ -74,11 +75,11 @@
 }
 
 // Converts a constraint (mandatory takes precedence over optional) to an
-// absl::optional.
+// std::optional.
 template <typename T>
 void ConstraintToOptional(const MediaConstraints* constraints,
                           const std::string& key,
-                          absl::optional<T>* value_out) {
+                          std::optional<T>* value_out) {
   T value;
   bool present = FindConstraint<T>(constraints, key, &value, nullptr);
   if (present) {
diff --git a/sdk/objc/api/peerconnection/RTCCertificate.mm b/sdk/objc/api/peerconnection/RTCCertificate.mm
index f6817a6..c3e5d7f 100644
--- a/sdk/objc/api/peerconnection/RTCCertificate.mm
+++ b/sdk/objc/api/peerconnection/RTCCertificate.mm
@@ -51,7 +51,7 @@
                                                                        expirationTimestamp);
   } else {
     cc_certificate =
-        rtc::RTCCertificateGenerator::GenerateCertificate(rtc::KeyParams(keyType), absl::nullopt);
+        rtc::RTCCertificateGenerator::GenerateCertificate(rtc::KeyParams(keyType), std::nullopt);
   }
   if (!cc_certificate) {
     RTCLogError(@"Failed to generate certificate.");
diff --git a/sdk/objc/api/peerconnection/RTCConfiguration.mm b/sdk/objc/api/peerconnection/RTCConfiguration.mm
index 7635ac0..d53a948 100644
--- a/sdk/objc/api/peerconnection/RTCConfiguration.mm
+++ b/sdk/objc/api/peerconnection/RTCConfiguration.mm
@@ -248,7 +248,7 @@
     if (keyType != rtc::KT_DEFAULT) {
       rtc::scoped_refptr<rtc::RTCCertificate> certificate =
           rtc::RTCCertificateGenerator::GenerateCertificate(rtc::KeyParams(keyType),
-                                                            absl::optional<uint64_t>());
+                                                            std::optional<uint64_t>());
       if (!certificate) {
         RTCLogError(@"Failed to generate certificate.");
         return nullptr;
@@ -263,7 +263,7 @@
   nativeConfig->surface_ice_candidates_on_ice_transport_type_changed =
       _shouldSurfaceIceCandidatesOnIceTransportTypeChanged ? true : false;
   if (_iceCheckMinInterval != nil) {
-    nativeConfig->ice_check_min_interval = absl::optional<int>(_iceCheckMinInterval.intValue);
+    nativeConfig->ice_check_min_interval = std::optional<int>(_iceCheckMinInterval.intValue);
   }
   nativeConfig->sdp_semantics = [[self class] nativeSdpSemanticsForSdpSemantics:_sdpSemantics];
   if (_turnCustomizer) {
@@ -280,7 +280,7 @@
         _cryptoOptions.srtpEnableEncryptedRtpHeaderExtensions ? true : false;
     nativeCryptoOptions.sframe.require_frame_encryption =
         _cryptoOptions.sframeRequireFrameEncryption ? true : false;
-    nativeConfig->crypto_options = absl::optional<webrtc::CryptoOptions>(nativeCryptoOptions);
+    nativeConfig->crypto_options = std::optional<webrtc::CryptoOptions>(nativeCryptoOptions);
   }
   nativeConfig->turn_logging_id = [_turnLoggingId UTF8String];
   nativeConfig->set_audio_rtcp_report_interval_ms(_rtcpAudioReportIntervalMs);
@@ -289,20 +289,20 @@
   nativeConfig->offer_extmap_allow_mixed = _offerExtmapAllowMixed;
   if (_iceCheckIntervalStrongConnectivity != nil) {
     nativeConfig->ice_check_interval_strong_connectivity =
-        absl::optional<int>(_iceCheckIntervalStrongConnectivity.intValue);
+        std::optional<int>(_iceCheckIntervalStrongConnectivity.intValue);
   }
   if (_iceCheckIntervalWeakConnectivity != nil) {
     nativeConfig->ice_check_interval_weak_connectivity =
-        absl::optional<int>(_iceCheckIntervalWeakConnectivity.intValue);
+        std::optional<int>(_iceCheckIntervalWeakConnectivity.intValue);
   }
   if (_iceUnwritableTimeout != nil) {
-    nativeConfig->ice_unwritable_timeout = absl::optional<int>(_iceUnwritableTimeout.intValue);
+    nativeConfig->ice_unwritable_timeout = std::optional<int>(_iceUnwritableTimeout.intValue);
   }
   if (_iceUnwritableMinChecks != nil) {
-    nativeConfig->ice_unwritable_min_checks = absl::optional<int>(_iceUnwritableMinChecks.intValue);
+    nativeConfig->ice_unwritable_min_checks = std::optional<int>(_iceUnwritableMinChecks.intValue);
   }
   if (_iceInactiveTimeout != nil) {
-    nativeConfig->ice_inactive_timeout = absl::optional<int>(_iceInactiveTimeout.intValue);
+    nativeConfig->ice_inactive_timeout = std::optional<int>(_iceInactiveTimeout.intValue);
   }
   return nativeConfig.release();
 }
diff --git a/sdk/objc/api/peerconnection/RTCPeerConnection.mm b/sdk/objc/api/peerconnection/RTCPeerConnection.mm
index 62e640e..5a9f14a 100644
--- a/sdk/objc/api/peerconnection/RTCPeerConnection.mm
+++ b/sdk/objc/api/peerconnection/RTCPeerConnection.mm
@@ -622,13 +622,13 @@
               maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
   webrtc::BitrateSettings params;
   if (minBitrateBps != nil) {
-    params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
+    params.min_bitrate_bps = std::optional<int>(minBitrateBps.intValue);
   }
   if (currentBitrateBps != nil) {
-    params.start_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
+    params.start_bitrate_bps = std::optional<int>(currentBitrateBps.intValue);
   }
   if (maxBitrateBps != nil) {
-    params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
+    params.max_bitrate_bps = std::optional<int>(maxBitrateBps.intValue);
   }
   return _peerConnection->SetBitrate(params).ok();
 }
diff --git a/sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm b/sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm
index 9c38bb7..cfce5e3 100644
--- a/sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm
+++ b/sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm
@@ -88,7 +88,7 @@
 - (webrtc::RtpCodecCapability)nativeRtpCodecCapability {
   webrtc::RtpCodecCapability rtpCodecCapability;
   if (_preferredPayloadType != nil) {
-    rtpCodecCapability.preferred_payload_type = absl::optional<int>(_preferredPayloadType.intValue);
+    rtpCodecCapability.preferred_payload_type = std::optional<int>(_preferredPayloadType.intValue);
   }
   rtpCodecCapability.name = [NSString stdStringForString:_name];
   // NSString pointer comparison is safe here since "kind" is readonly and only
@@ -101,10 +101,10 @@
     RTC_DCHECK_NOTREACHED();
   }
   if (_clockRate != nil) {
-    rtpCodecCapability.clock_rate = absl::optional<int>(_clockRate.intValue);
+    rtpCodecCapability.clock_rate = std::optional<int>(_clockRate.intValue);
   }
   if (_numChannels != nil) {
-    rtpCodecCapability.num_channels = absl::optional<int>(_numChannels.intValue);
+    rtpCodecCapability.num_channels = std::optional<int>(_numChannels.intValue);
   }
   for (NSString *paramKey in _parameters.allKeys) {
     std::string key = [NSString stdStringForString:paramKey];
diff --git a/sdk/objc/api/peerconnection/RTCRtpCodecParameters.mm b/sdk/objc/api/peerconnection/RTCRtpCodecParameters.mm
index e273219..f01d367 100644
--- a/sdk/objc/api/peerconnection/RTCRtpCodecParameters.mm
+++ b/sdk/objc/api/peerconnection/RTCRtpCodecParameters.mm
@@ -97,10 +97,10 @@
     RTC_DCHECK_NOTREACHED();
   }
   if (_clockRate != nil) {
-    parameters.clock_rate = absl::optional<int>(_clockRate.intValue);
+    parameters.clock_rate = std::optional<int>(_clockRate.intValue);
   }
   if (_numChannels != nil) {
-    parameters.num_channels = absl::optional<int>(_numChannels.intValue);
+    parameters.num_channels = std::optional<int>(_numChannels.intValue);
   }
   for (NSString *paramKey in _parameters.allKeys) {
     std::string key = [NSString stdStringForString:paramKey];
diff --git a/sdk/objc/api/peerconnection/RTCRtpEncodingParameters.mm b/sdk/objc/api/peerconnection/RTCRtpEncodingParameters.mm
index 8bb2f43..69f8885 100644
--- a/sdk/objc/api/peerconnection/RTCRtpEncodingParameters.mm
+++ b/sdk/objc/api/peerconnection/RTCRtpEncodingParameters.mm
@@ -75,23 +75,22 @@
   }
   parameters.active = _isActive;
   if (_maxBitrateBps != nil) {
-    parameters.max_bitrate_bps = absl::optional<int>(_maxBitrateBps.intValue);
+    parameters.max_bitrate_bps = std::optional<int>(_maxBitrateBps.intValue);
   }
   if (_minBitrateBps != nil) {
-    parameters.min_bitrate_bps = absl::optional<int>(_minBitrateBps.intValue);
+    parameters.min_bitrate_bps = std::optional<int>(_minBitrateBps.intValue);
   }
   if (_maxFramerate != nil) {
-    parameters.max_framerate = absl::optional<int>(_maxFramerate.intValue);
+    parameters.max_framerate = std::optional<int>(_maxFramerate.intValue);
   }
   if (_numTemporalLayers != nil) {
-    parameters.num_temporal_layers = absl::optional<int>(_numTemporalLayers.intValue);
+    parameters.num_temporal_layers = std::optional<int>(_numTemporalLayers.intValue);
   }
   if (_scaleResolutionDownBy != nil) {
-    parameters.scale_resolution_down_by =
-        absl::optional<double>(_scaleResolutionDownBy.doubleValue);
+    parameters.scale_resolution_down_by = std::optional<double>(_scaleResolutionDownBy.doubleValue);
   }
   if (_ssrc != nil) {
-    parameters.ssrc = absl::optional<uint32_t>(_ssrc.unsignedLongValue);
+    parameters.ssrc = std::optional<uint32_t>(_ssrc.unsignedLongValue);
   }
   parameters.bitrate_priority = _bitratePriority;
   parameters.network_priority =
diff --git a/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm b/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm
index c5cbda1..22e5338 100644
--- a/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm
+++ b/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm
@@ -48,7 +48,7 @@
   webrtc::RtpHeaderExtensionCapability rtpHeaderExtensionCapability;
   rtpHeaderExtensionCapability.uri = [NSString stdStringForString:_uri];
   if (_preferredId != nil) {
-    rtpHeaderExtensionCapability.preferred_id = absl::optional<int>(_preferredId.intValue);
+    rtpHeaderExtensionCapability.preferred_id = std::optional<int>(_preferredId.intValue);
   }
   rtpHeaderExtensionCapability.preferred_encrypt = _preferredEncrypted;
   return rtpHeaderExtensionCapability;
diff --git a/sdk/objc/api/peerconnection/RTCRtpParameters.mm b/sdk/objc/api/peerconnection/RTCRtpParameters.mm
index d725f6a..1c2a94f 100644
--- a/sdk/objc/api/peerconnection/RTCRtpParameters.mm
+++ b/sdk/objc/api/peerconnection/RTCRtpParameters.mm
@@ -102,7 +102,7 @@
 }
 
 + (NSNumber *)degradationPreferenceFromNativeDegradationPreference:
-    (absl::optional<webrtc::DegradationPreference>)nativeDegradationPreference {
+    (std::optional<webrtc::DegradationPreference>)nativeDegradationPreference {
   if (!nativeDegradationPreference.has_value()) {
     return nil;
   }
diff --git a/sdk/objc/api/peerconnection/RTCRtpSource.mm b/sdk/objc/api/peerconnection/RTCRtpSource.mm
index 5f7a678..52b0e86 100644
--- a/sdk/objc/api/peerconnection/RTCRtpSource.mm
+++ b/sdk/objc/api/peerconnection/RTCRtpSource.mm
@@ -41,7 +41,7 @@
 }
 
 - (NSNumber *)audioLevel {
-  absl::optional<uint8_t> level = _nativeRtpSource.value().audio_level();
+  std::optional<uint8_t> level = _nativeRtpSource.value().audio_level();
   if (!level.has_value()) {
     return nil;
   }
diff --git a/sdk/objc/api/peerconnection/RTCVideoCodecInfo+Private.mm b/sdk/objc/api/peerconnection/RTCVideoCodecInfo+Private.mm
index ea01a5f..dd45ef0 100644
--- a/sdk/objc/api/peerconnection/RTCVideoCodecInfo+Private.mm
+++ b/sdk/objc/api/peerconnection/RTCVideoCodecInfo+Private.mm
@@ -44,7 +44,7 @@
 
   absl::InlinedVector<webrtc::ScalabilityMode, webrtc::kScalabilityModeCount> scalability_modes;
   for (NSString* mode_name in self.scalabilityModes) {
-    absl::optional<webrtc::ScalabilityMode> mode =
+    std::optional<webrtc::ScalabilityMode> mode =
         webrtc::ScalabilityModeStringToEnum([NSString stdStringForString:mode_name]);
     if (mode.has_value()) {
       scalability_modes.push_back(*mode);
diff --git a/sdk/objc/components/renderer/opengl/RTCDefaultShader.mm b/sdk/objc/components/renderer/opengl/RTCDefaultShader.mm
index 9d686f6..ca0a844 100644
--- a/sdk/objc/components/renderer/opengl/RTCDefaultShader.mm
+++ b/sdk/objc/components/renderer/opengl/RTCDefaultShader.mm
@@ -16,7 +16,7 @@
 #import "RTCShader.h"
 #import "base/RTCLogging.h"
 
-#include "absl/types/optional.h"
+#include <optional>
 
 static const int kYTextureUnit = 0;
 static const int kUTextureUnit = 1;
@@ -69,7 +69,7 @@
   GLuint _vertexBuffer;
   GLuint _vertexArray;
   // Store current rotation and only upload new vertex data when rotation changes.
-  absl::optional<RTCVideoRotation> _currentRotation;
+  std::optional<RTCVideoRotation> _currentRotation;
 
   GLuint _i420Program;
   GLuint _nv12Program;
@@ -138,7 +138,7 @@
 
   glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
   if (!_currentRotation || rotation != *_currentRotation) {
-    _currentRotation = absl::optional<RTCVideoRotation>(rotation);
+    _currentRotation = std::optional<RTCVideoRotation>(rotation);
     RTCSetVertexData(*_currentRotation);
   }
   return YES;
diff --git a/sdk/objc/components/video_codec/RTCH264ProfileLevelId.mm b/sdk/objc/components/video_codec/RTCH264ProfileLevelId.mm
index 028f005..400bc78 100644
--- a/sdk/objc/components/video_codec/RTCH264ProfileLevelId.mm
+++ b/sdk/objc/components/video_codec/RTCH264ProfileLevelId.mm
@@ -39,10 +39,10 @@
 #if defined(WEBRTC_IOS)
 
 NSString *MaxSupportedLevelForProfile(webrtc::H264Profile profile) {
-  const absl::optional<webrtc::H264ProfileLevelId> profileLevelId =
+  const std::optional<webrtc::H264ProfileLevelId> profileLevelId =
       [UIDevice maxSupportedH264Profile];
   if (profileLevelId && profileLevelId->profile >= profile) {
-    const absl::optional<std::string> profileString =
+    const std::optional<std::string> profileString =
         H264ProfileLevelIdToString(webrtc::H264ProfileLevelId(profile, profileLevelId->level));
     if (profileString) {
       return [NSString stringForStdString:*profileString];
@@ -94,7 +94,7 @@
   if (self) {
     self.hexString = hexString;
 
-    absl::optional<webrtc::H264ProfileLevelId> profile_level_id =
+    std::optional<webrtc::H264ProfileLevelId> profile_level_id =
         webrtc::ParseH264ProfileLevelId([hexString cStringUsingEncoding:NSUTF8StringEncoding]);
     if (profile_level_id.has_value()) {
       self.profile = static_cast<RTCH264Profile>(profile_level_id->profile);
@@ -110,7 +110,7 @@
     self.profile = profile;
     self.level = level;
 
-    absl::optional<std::string> hex_string =
+    std::optional<std::string> hex_string =
         webrtc::H264ProfileLevelIdToString(webrtc::H264ProfileLevelId(
             static_cast<webrtc::H264Profile>(profile), static_cast<webrtc::H264Level>(level)));
     self.hexString =
diff --git a/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm b/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm
index 27ccd6d..ec76f0a 100644
--- a/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm
+++ b/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm
@@ -325,7 +325,7 @@
   uint32_t _encoderFrameRate;
   uint32_t _maxAllowedFrameRate;
   RTCH264PacketizationMode _packetizationMode;
-  absl::optional<webrtc::H264ProfileLevelId> _profile_level_id;
+  std::optional<webrtc::H264ProfileLevelId> _profile_level_id;
   RTCVideoEncoderCallback _callback;
   int32_t _width;
   int32_t _height;
diff --git a/sdk/objc/components/video_codec/UIDevice+H264Profile.h b/sdk/objc/components/video_codec/UIDevice+H264Profile.h
index a51debb..722f6f4 100644
--- a/sdk/objc/components/video_codec/UIDevice+H264Profile.h
+++ b/sdk/objc/components/video_codec/UIDevice+H264Profile.h
@@ -14,6 +14,6 @@
 
 @interface UIDevice (H264Profile)
 
-+ (absl::optional<webrtc::H264ProfileLevelId>)maxSupportedH264Profile;
++ (std::optional<webrtc::H264ProfileLevelId>)maxSupportedH264Profile;
 
 @end
diff --git a/sdk/objc/components/video_codec/UIDevice+H264Profile.mm b/sdk/objc/components/video_codec/UIDevice+H264Profile.mm
index cfb2b97..88edc52 100644
--- a/sdk/objc/components/video_codec/UIDevice+H264Profile.mm
+++ b/sdk/objc/components/video_codec/UIDevice+H264Profile.mm
@@ -261,7 +261,7 @@
      {H264Profile::kProfileHigh, H264Level::kLevel4_1}},
 };
 
-absl::optional<H264ProfileLevelId> FindMaxSupportedProfileForDevice(NSString* machineName) {
+std::optional<H264ProfileLevelId> FindMaxSupportedProfileForDevice(NSString* machineName) {
   const auto* result =
       std::find_if(std::begin(kH264MaxSupportedProfiles),
                    std::end(kH264MaxSupportedProfiles),
@@ -279,14 +279,14 @@
     H264ProfileLevelId fallbackProfile{H264Profile::kProfileMain, H264Level::kLevel4_1};
     return fallbackProfile;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace
 
 @implementation UIDevice (H264Profile)
 
-+ (absl::optional<webrtc::H264ProfileLevelId>)maxSupportedH264Profile {
++ (std::optional<webrtc::H264ProfileLevelId>)maxSupportedH264Profile {
   return FindMaxSupportedProfileForDevice([UIDevice machineName]);
 }
 
diff --git a/sdk/objc/native/src/objc_video_encoder_factory.mm b/sdk/objc/native/src/objc_video_encoder_factory.mm
index 1085cb8..e5fb3da 100644
--- a/sdk/objc/native/src/objc_video_encoder_factory.mm
+++ b/sdk/objc/native/src/objc_video_encoder_factory.mm
@@ -120,22 +120,22 @@
         [[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithNativeSdpVideoFormat:format];
     [selector_ registerCurrentEncoderInfo:info];
   }
-  absl::optional<SdpVideoFormat> OnEncoderBroken() override {
+  std::optional<SdpVideoFormat> OnEncoderBroken() override {
     RTC_OBJC_TYPE(RTCVideoCodecInfo) *info = [selector_ encoderForBrokenEncoder];
     if (info) {
       return [info nativeSdpVideoFormat];
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
-  absl::optional<SdpVideoFormat> OnAvailableBitrate(const DataRate &rate) override {
+  std::optional<SdpVideoFormat> OnAvailableBitrate(const DataRate &rate) override {
     RTC_OBJC_TYPE(RTCVideoCodecInfo) *info = [selector_ encoderForBitrate:rate.kbps<NSInteger>()];
     if (info) {
       return [info nativeSdpVideoFormat];
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  absl::optional<SdpVideoFormat> OnResolutionChange(const RenderResolution &resolution) override {
+  std::optional<SdpVideoFormat> OnResolutionChange(const RenderResolution &resolution) override {
     if ([selector_ respondsToSelector:@selector(encoderForResolutionChangeBySize:)]) {
       RTC_OBJC_TYPE(RTCVideoCodecInfo) *info = [selector_
           encoderForResolutionChangeBySize:CGSizeMake(resolution.Width(), resolution.Height())];
@@ -143,7 +143,7 @@
         return [info nativeSdpVideoFormat];
       }
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
  private:
diff --git a/sdk/objc/native/src/objc_video_track_source.h b/sdk/objc/native/src/objc_video_track_source.h
index 19a3d6d..242dc2a 100644
--- a/sdk/objc/native/src/objc_video_track_source.h
+++ b/sdk/objc/native/src/objc_video_track_source.h
@@ -35,7 +35,7 @@
   // Indicates that the encoder should denoise video before encoding it.
   // If it is not set, the default configuration is used which is different
   // depending on video codec.
-  absl::optional<bool> needs_denoising() const override;
+  std::optional<bool> needs_denoising() const override;
 
   SourceState state() const override;
 
diff --git a/sdk/objc/native/src/objc_video_track_source.mm b/sdk/objc/native/src/objc_video_track_source.mm
index 7937e90..9da0d9a 100644
--- a/sdk/objc/native/src/objc_video_track_source.mm
+++ b/sdk/objc/native/src/objc_video_track_source.mm
@@ -48,7 +48,7 @@
   return is_screencast_;
 }
 
-absl::optional<bool> ObjCVideoTrackSource::needs_denoising() const {
+std::optional<bool> ObjCVideoTrackSource::needs_denoising() const {
   return false;
 }
 
diff --git a/stats/BUILD.gn b/stats/BUILD.gn
index 3024f39..ab4be89 100644
--- a/stats/BUILD.gn
+++ b/stats/BUILD.gn
@@ -44,7 +44,6 @@
     "../api:rtc_stats_api",
     "../rtc_base:checks",
     "../rtc_base/system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -65,7 +64,6 @@
       "../rtc_base:rtc_json",
       "../test:test_main",
       "../test:test_support",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
 
     if (is_android) {
diff --git a/stats/attribute.cc b/stats/attribute.cc
index cf49cb2..52cdbc2 100644
--- a/stats/attribute.cc
+++ b/stats/attribute.cc
@@ -25,12 +25,12 @@
 struct VisitIsSequence {
   // Any type of vector is a sequence.
   template <typename T>
-  bool operator()(const absl::optional<std::vector<T>>* attribute) {
+  bool operator()(const std::optional<std::vector<T>>* attribute) {
     return true;
   }
   // Any other type is not.
   template <typename T>
-  bool operator()(const absl::optional<T>* attribute) {
+  bool operator()(const std::optional<T>* attribute) {
     return false;
   }
 };
@@ -62,7 +62,7 @@
 
   // Vector attributes.
   template <typename T>
-  std::string operator()(const absl::optional<std::vector<T>>* attribute) {
+  std::string operator()(const std::optional<std::vector<T>>* attribute) {
     rtc::StringBuilder sb;
     sb << "[";
     const char* separator = "";
@@ -84,7 +84,7 @@
   // Map attributes.
   template <typename T>
   std::string operator()(
-      const absl::optional<std::map<std::string, T>>* attribute) {
+      const std::optional<std::map<std::string, T>>* attribute) {
     rtc::StringBuilder sb;
     sb << "{";
     const char* separator = "";
@@ -106,14 +106,14 @@
   }
   // Simple attributes.
   template <typename T>
-  std::string operator()(const absl::optional<T>* attribute) {
+  std::string operator()(const std::optional<T>* attribute) {
     return ValueToString(attribute->value());
   }
 };
 
 struct VisitIsEqual {
   template <typename T>
-  bool operator()(const absl::optional<T>* attribute) {
+  bool operator()(const std::optional<T>* attribute) {
     if (!other.holds_alternative<T>()) {
       return false;
     }
@@ -143,8 +143,7 @@
 }
 
 bool Attribute::is_string() const {
-  return absl::holds_alternative<const absl::optional<std::string>*>(
-      attribute_);
+  return absl::holds_alternative<const std::optional<std::string>*>(attribute_);
 }
 
 std::string Attribute::ToString() const {
diff --git a/stats/rtc_stats_report_unittest.cc b/stats/rtc_stats_report_unittest.cc
index f11ff52..250433f 100644
--- a/stats/rtc_stats_report_unittest.cc
+++ b/stats/rtc_stats_report_unittest.cc
@@ -10,7 +10,8 @@
 
 #include "api/stats/rtc_stats_report.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/stats/attribute.h"
 #include "api/stats/rtc_stats.h"
 #include "rtc_base/checks.h"
@@ -25,7 +26,7 @@
   RTCTestStats1(const std::string& id, Timestamp timestamp)
       : RTCStats(id, timestamp) {}
 
-  absl::optional<int32_t> integer;
+  std::optional<int32_t> integer;
 };
 
 WEBRTC_RTCSTATS_IMPL(RTCTestStats1,
@@ -40,7 +41,7 @@
   RTCTestStats2(const std::string& id, Timestamp timestamp)
       : RTCStats(id, timestamp) {}
 
-  absl::optional<double> number;
+  std::optional<double> number;
 };
 
 WEBRTC_RTCSTATS_IMPL(RTCTestStats2,
@@ -55,7 +56,7 @@
   RTCTestStats3(const std::string& id, Timestamp timestamp)
       : RTCStats(id, timestamp) {}
 
-  absl::optional<std::string> string;
+  std::optional<std::string> string;
 };
 
 WEBRTC_RTCSTATS_IMPL(RTCTestStats3,
diff --git a/stats/rtc_stats_unittest.cc b/stats/rtc_stats_unittest.cc
index 555360f..19f3a3f 100644
--- a/stats/rtc_stats_unittest.cc
+++ b/stats/rtc_stats_unittest.cc
@@ -14,8 +14,8 @@
 #include <cstdint>
 #include <cstring>
 #include <iostream>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/strings/json.h"
 #include "stats/test/rtc_test_stats.h"
@@ -47,7 +47,7 @@
   RTCChildStats(const std::string& id, Timestamp timestamp)
       : RTCStats(id, timestamp) {}
 
-  absl::optional<int32_t> child_int;
+  std::optional<int32_t> child_int;
 };
 
 WEBRTC_RTCSTATS_IMPL(RTCChildStats,
@@ -62,7 +62,7 @@
   RTCGrandChildStats(const std::string& id, Timestamp timestamp)
       : RTCChildStats(id, timestamp) {}
 
-  absl::optional<int32_t> grandchild_int;
+  std::optional<int32_t> grandchild_int;
 };
 
 WEBRTC_RTCSTATS_IMPL(RTCGrandChildStats,
diff --git a/stats/test/rtc_test_stats.h b/stats/test/rtc_test_stats.h
index ff1a06f..52bcd9c 100644
--- a/stats/test/rtc_test_stats.h
+++ b/stats/test/rtc_test_stats.h
@@ -13,10 +13,10 @@
 
 #include <cstdint>
 #include <map>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/stats/rtc_stats.h"
 #include "rtc_base/system/rtc_export.h"
 
@@ -28,22 +28,22 @@
   RTCTestStats(const std::string& id, Timestamp timestamp);
   ~RTCTestStats() override;
 
-  absl::optional<bool> m_bool;
-  absl::optional<int32_t> m_int32;
-  absl::optional<uint32_t> m_uint32;
-  absl::optional<int64_t> m_int64;
-  absl::optional<uint64_t> m_uint64;
-  absl::optional<double> m_double;
-  absl::optional<std::string> m_string;
-  absl::optional<std::vector<bool>> m_sequence_bool;
-  absl::optional<std::vector<int32_t>> m_sequence_int32;
-  absl::optional<std::vector<uint32_t>> m_sequence_uint32;
-  absl::optional<std::vector<int64_t>> m_sequence_int64;
-  absl::optional<std::vector<uint64_t>> m_sequence_uint64;
-  absl::optional<std::vector<double>> m_sequence_double;
-  absl::optional<std::vector<std::string>> m_sequence_string;
-  absl::optional<std::map<std::string, uint64_t>> m_map_string_uint64;
-  absl::optional<std::map<std::string, double>> m_map_string_double;
+  std::optional<bool> m_bool;
+  std::optional<int32_t> m_int32;
+  std::optional<uint32_t> m_uint32;
+  std::optional<int64_t> m_int64;
+  std::optional<uint64_t> m_uint64;
+  std::optional<double> m_double;
+  std::optional<std::string> m_string;
+  std::optional<std::vector<bool>> m_sequence_bool;
+  std::optional<std::vector<int32_t>> m_sequence_int32;
+  std::optional<std::vector<uint32_t>> m_sequence_uint32;
+  std::optional<std::vector<int64_t>> m_sequence_int64;
+  std::optional<std::vector<uint64_t>> m_sequence_uint64;
+  std::optional<std::vector<double>> m_sequence_double;
+  std::optional<std::vector<std::string>> m_sequence_string;
+  std::optional<std::map<std::string, uint64_t>> m_map_string_uint64;
+  std::optional<std::map<std::string, double>> m_map_string_double;
 };
 
 }  // namespace webrtc
diff --git a/system_wrappers/BUILD.gn b/system_wrappers/BUILD.gn
index 43bae7f..5e66d4b 100644
--- a/system_wrappers/BUILD.gn
+++ b/system_wrappers/BUILD.gn
@@ -41,7 +41,6 @@
     "../rtc_base/synchronization:mutex",
     "../rtc_base/system:arch",
     "../rtc_base/system:rtc_export",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 
   if (is_android) {
diff --git a/system_wrappers/include/rtp_to_ntp_estimator.h b/system_wrappers/include/rtp_to_ntp_estimator.h
index a5c7a15..2f36981 100644
--- a/system_wrappers/include/rtp_to_ntp_estimator.h
+++ b/system_wrappers/include/rtp_to_ntp_estimator.h
@@ -14,8 +14,8 @@
 #include <stdint.h>
 
 #include <list>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/sequence_number_unwrapper.h"
 #include "system_wrappers/include/ntp_time.h"
@@ -64,7 +64,7 @@
 
   int consecutive_invalid_samples_ = 0;
   std::list<RtcpMeasurement> measurements_;
-  absl::optional<Parameters> params_;
+  std::optional<Parameters> params_;
   mutable RtpTimestampUnwrapper unwrapper_;
 };
 }  // namespace webrtc
diff --git a/system_wrappers/source/rtp_to_ntp_estimator.cc b/system_wrappers/source/rtp_to_ntp_estimator.cc
index ef5d9a7..3df4b77 100644
--- a/system_wrappers/source/rtp_to_ntp_estimator.cc
+++ b/system_wrappers/source/rtp_to_ntp_estimator.cc
@@ -116,7 +116,7 @@
     RTC_LOG(LS_WARNING) << "Multiple consecutively invalid RTCP SR reports, "
                            "clearing measurements.";
     measurements_.clear();
-    params_ = absl::nullopt;
+    params_ = std::nullopt;
   }
   consecutive_invalid_samples_ = 0;
 
diff --git a/test/BUILD.gn b/test/BUILD.gn
index bec49f0..42217274 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -76,7 +76,6 @@
     "../rtc_base/system:file_wrapper",
     "../system_wrappers",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -94,7 +93,6 @@
     "../api/video:video_frame",
     "../rtc_base:checks",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -144,7 +142,6 @@
     "../rtc_base:checks",
     "../system_wrappers",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -168,7 +165,6 @@
     "../rtc_base/synchronization:mutex",
     "../rtc_base/task_utils:repeating_task",
     "../system_wrappers",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -310,7 +306,6 @@
     "../rtc_base/synchronization:mutex",
     "../rtc_base/system:arch",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -414,7 +409,6 @@
       "../api/test/metrics:print_result_proxy_metrics_exporter",
       "../api/test/metrics:stdout_metrics_exporter",
       "../sdk:helpers_objc",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
     configs += [ ":test_support_objc_config" ]
   }
@@ -497,7 +491,6 @@
     "../api/video:video_frame",
     "../rtc_base:checks",
     "../system_wrappers",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -563,7 +556,6 @@
     "../rtc_base:rtc_event",
     "../rtc_base:stringutils",
     "../rtc_base/system:file_wrapper",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -619,7 +611,6 @@
         "//third_party/abseil-cpp/absl/memory",
         "//third_party/abseil-cpp/absl/strings",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
         "//third_party/perfetto/include/perfetto/tracing",
       ]
 
@@ -769,7 +760,6 @@
         "time_controller:time_controller_unittests",
         "//third_party/abseil-cpp/absl/flags:flag",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
         "//third_party/libyuv",
       ]
       sources = [
@@ -864,7 +854,6 @@
     "../rtc_base:stringutils",
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   if (is_ios) {
     deps += [ ":fileutils_ios_objc" ]
@@ -895,7 +884,6 @@
     "../rtc_base:macromagic",
     "../rtc_base:stringutils",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   if (is_ios) {
     deps += [ ":fileutils_ios_objc" ]
@@ -948,7 +936,6 @@
     "../rtc_base:checks",
     "../rtc_base:crypto_random",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1016,7 +1003,6 @@
     "../rtc_base/synchronization:mutex",
     "../system_wrappers",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -1202,7 +1188,6 @@
       "../common_audio",
       "../modules/audio_device:test_audio_device_module",
       "../rtc_base:buffer",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -1295,7 +1280,6 @@
       "../system_wrappers:field_trial",
       "../video/config:encoder_config",
       "//third_party/abseil-cpp/absl/flags:flag",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
     if (!is_android && !build_with_chromium) {
       deps += [ "../modules/video_capture:video_capture_internal_impl" ]
@@ -1395,7 +1379,6 @@
     "../test:fileutils",
     "../video/config:streams_config",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/libyuv",
   ]
 }
diff --git a/test/audio_decoder_proxy_factory.h b/test/audio_decoder_proxy_factory.h
index 95606d6..192b417 100644
--- a/test/audio_decoder_proxy_factory.h
+++ b/test/audio_decoder_proxy_factory.h
@@ -41,7 +41,7 @@
 
   std::unique_ptr<AudioDecoder> MakeAudioDecoder(
       const SdpAudioFormat& /* format */,
-      absl::optional<AudioCodecPairId> /* codec_pair_id */) override {
+      std::optional<AudioCodecPairId> /* codec_pair_id */) override {
     return std::make_unique<DecoderProxy>(decoder_);
   }
 
diff --git a/test/call_test.cc b/test/call_test.cc
index 543bf93..bee23d6 100644
--- a/test/call_test.cc
+++ b/test/call_test.cc
@@ -374,15 +374,15 @@
     const VideoSendStream::Config& video_send_config,
     Transport* rtcp_send_transport) {
   CreateMatchingVideoReceiveConfigs(video_send_config, rtcp_send_transport,
-                                    &fake_decoder_factory_, absl::nullopt,
-                                    false, 0);
+                                    &fake_decoder_factory_, std::nullopt, false,
+                                    0);
 }
 
 void CallTest::CreateMatchingVideoReceiveConfigs(
     const VideoSendStream::Config& video_send_config,
     Transport* rtcp_send_transport,
     VideoDecoderFactory* decoder_factory,
-    absl::optional<size_t> decode_sub_stream,
+    std::optional<size_t> decode_sub_stream,
     bool receiver_reference_time_report,
     int rtp_history_ms) {
   AddMatchingVideoReceiveConfigs(
@@ -396,7 +396,7 @@
     const VideoSendStream::Config& video_send_config,
     Transport* rtcp_send_transport,
     VideoDecoderFactory* decoder_factory,
-    absl::optional<size_t> decode_sub_stream,
+    std::optional<size_t> decode_sub_stream,
     bool receiver_reference_time_report,
     int rtp_history_ms) {
   RTC_DCHECK(!video_send_config.rtp.ssrcs.empty());
@@ -502,8 +502,8 @@
   auto frame_generator_capturer =
       std::make_unique<test::FrameGeneratorCapturer>(
           clock,
-          test::CreateSquareFrameGenerator(width, height, absl::nullopt,
-                                           absl::nullopt),
+          test::CreateSquareFrameGenerator(width, height, std::nullopt,
+                                           std::nullopt),
           framerate * speed, env_.task_queue_factory());
   frame_generator_capturer_ = frame_generator_capturer.get();
   frame_generator_capturer->Init();
@@ -518,8 +518,8 @@
   auto frame_generator_capturer =
       std::make_unique<test::FrameGeneratorCapturer>(
           &env_.clock(),
-          test::CreateSquareFrameGenerator(width, height, absl::nullopt,
-                                           absl::nullopt),
+          test::CreateSquareFrameGenerator(width, height, std::nullopt,
+                                           std::nullopt),
           framerate, env_.task_queue_factory());
   frame_generator_capturer_ = frame_generator_capturer.get();
   frame_generator_capturer->Init();
@@ -744,20 +744,20 @@
     flexfec_recv_stream->OnRtpPacket(packet);
 }
 
-absl::optional<RtpExtension> CallTest::GetRtpExtensionByUri(
+std::optional<RtpExtension> CallTest::GetRtpExtensionByUri(
     const std::string& uri) const {
   for (const auto& extension : rtp_extensions_) {
     if (extension.uri == uri) {
       return extension;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void CallTest::AddRtpExtensionByUri(
     const std::string& uri,
     std::vector<RtpExtension>* extensions) const {
-  const absl::optional<RtpExtension> extension = GetRtpExtensionByUri(uri);
+  const std::optional<RtpExtension> extension = GetRtpExtensionByUri(uri);
   if (extension) {
     extensions->push_back(*extension);
   }
diff --git a/test/call_test.h b/test/call_test.h
index 2446a0f..8c97848 100644
--- a/test/call_test.h
+++ b/test/call_test.h
@@ -12,10 +12,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/audio_device.h"
 #include "api/environment/environment.h"
@@ -115,7 +115,7 @@
       const VideoSendStream::Config& video_send_config,
       Transport* rtcp_send_transport,
       VideoDecoderFactory* decoder_factory,
-      absl::optional<size_t> decode_sub_stream,
+      std::optional<size_t> decode_sub_stream,
       bool receiver_reference_time_report,
       int rtp_history_ms);
   void AddMatchingVideoReceiveConfigs(
@@ -123,7 +123,7 @@
       const VideoSendStream::Config& video_send_config,
       Transport* rtcp_send_transport,
       VideoDecoderFactory* decoder_factory,
-      absl::optional<size_t> decode_sub_stream,
+      std::optional<size_t> decode_sub_stream,
       bool receiver_reference_time_report,
       int rtp_history_ms);
 
@@ -241,7 +241,7 @@
   test::FakeVideoRenderer fake_renderer_;
 
  private:
-  absl::optional<RtpExtension> GetRtpExtensionByUri(
+  std::optional<RtpExtension> GetRtpExtensionByUri(
       const std::string& uri) const;
 
   void AddRtpExtensionByUri(const std::string& uri,
diff --git a/test/configurable_frame_size_encoder.h b/test/configurable_frame_size_encoder.h
index 747fc09..1fa032a 100644
--- a/test/configurable_frame_size_encoder.h
+++ b/test/configurable_frame_size_encoder.h
@@ -16,9 +16,9 @@
 
 #include <functional>
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/video/video_bitrate_allocation.h"
 #include "api/video/video_frame.h"
 #include "api/video_codecs/video_codec.h"
@@ -60,7 +60,7 @@
 
  private:
   EncodedImageCallback* callback_;
-  absl::optional<std::function<void(void)>> post_encode_callback_;
+  std::optional<std::function<void(void)>> post_encode_callback_;
 
   size_t current_frame_size_;
   VideoCodecType codec_type_;
diff --git a/test/create_frame_generator_capturer.h b/test/create_frame_generator_capturer.h
index 0d8ec71..de12d73 100644
--- a/test/create_frame_generator_capturer.h
+++ b/test/create_frame_generator_capturer.h
@@ -11,10 +11,10 @@
 #define TEST_CREATE_FRAME_GENERATOR_CAPTURER_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/task_queue/task_queue_factory.h"
 #include "api/test/frame_generator_interface.h"
 #include "api/units/time_delta.h"
@@ -26,13 +26,13 @@
 
 namespace frame_gen_cap_impl {
 template <typename T>
-class AutoOpt : public absl::optional<T> {
+class AutoOpt : public std::optional<T> {
  public:
-  using absl::optional<T>::optional;
+  using std::optional<T>::optional;
   T* operator->() {
-    if (!absl::optional<T>::has_value())
+    if (!std::optional<T>::has_value())
       this->emplace(T());
-    return absl::optional<T>::operator->();
+    return std::optional<T>::operator->();
   }
 };
 }  // namespace frame_gen_cap_impl
@@ -67,8 +67,8 @@
     TimeDelta change_interval = TimeDelta::Seconds(10);
     struct Crop {
       TimeDelta scroll_duration = TimeDelta::Seconds(0);
-      absl::optional<int> width;
-      absl::optional<int> height;
+      std::optional<int> width;
+      std::optional<int> height;
     } crop;
     int width = 1850;
     int height = 1110;
diff --git a/test/direct_transport.cc b/test/direct_transport.cc
index 3aa8508..6b2c5f8 100644
--- a/test/direct_transport.cc
+++ b/test/direct_transport.cc
@@ -123,9 +123,9 @@
 }
 
 void DirectTransport::ProcessPackets() {
-  absl::optional<int64_t> initial_delay_ms =
+  std::optional<int64_t> initial_delay_ms =
       fake_network_->TimeUntilNextProcess();
-  if (initial_delay_ms == absl::nullopt)
+  if (initial_delay_ms == std::nullopt)
     return;
 
   next_process_task_ = RepeatingTaskHandle::DelayedStart(
diff --git a/test/fake_encoded_frame.h b/test/fake_encoded_frame.h
index 36d4781..cfac3d9 100644
--- a/test/fake_encoded_frame.h
+++ b/test/fake_encoded_frame.h
@@ -65,15 +65,15 @@
   std::unique_ptr<FakeEncodedFrame> Build();
 
  private:
-  absl::optional<uint32_t> rtp_timestamp_;
-  absl::optional<int64_t> frame_id_;
-  absl::optional<VideoPlayoutDelay> playout_delay_;
-  absl::optional<int> spatial_layer_;
-  absl::optional<Timestamp> received_time_;
-  absl::optional<int> payload_type_;
-  absl::optional<Timestamp> ntp_time_;
-  absl::optional<VideoRotation> rotation_;
-  absl::optional<RtpPacketInfos> packet_infos_;
+  std::optional<uint32_t> rtp_timestamp_;
+  std::optional<int64_t> frame_id_;
+  std::optional<VideoPlayoutDelay> playout_delay_;
+  std::optional<int> spatial_layer_;
+  std::optional<Timestamp> received_time_;
+  std::optional<int> payload_type_;
+  std::optional<Timestamp> ntp_time_;
+  std::optional<VideoRotation> rotation_;
+  std::optional<RtpPacketInfos> packet_infos_;
   std::vector<int64_t> references_;
   bool last_spatial_layer_ = false;
   size_t size_ = 10;
diff --git a/test/fake_encoder.cc b/test/fake_encoder.cc
index 4ff0926..a2f49a0 100644
--- a/test/fake_encoder.cc
+++ b/test/fake_encoder.cc
@@ -105,7 +105,7 @@
   RateControlParameters rates;
   bool keyframe;
   uint32_t counter;
-  absl::optional<int> qp;
+  std::optional<int> qp;
   {
     MutexLock lock(&mutex_);
     max_framerate = config_.maxFramerate;
diff --git a/test/fake_encoder.h b/test/fake_encoder.h
index 203e67c..d595a8c 100644
--- a/test/fake_encoder.h
+++ b/test/fake_encoder.h
@@ -15,10 +15,10 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/fec_controller_override.h"
 #include "api/sequence_checker.h"
@@ -112,8 +112,8 @@
   uint32_t counter_ RTC_GUARDED_BY(mutex_);
   mutable Mutex mutex_;
   bool used_layers_[kMaxSimulcastStreams];
-  absl::optional<int> qp_ RTC_GUARDED_BY(mutex_);
-  absl::optional<std::string> implementation_name_ RTC_GUARDED_BY(mutex_);
+  std::optional<int> qp_ RTC_GUARDED_BY(mutex_);
+  std::optional<std::string> implementation_name_ RTC_GUARDED_BY(mutex_);
 
   // Current byte debt to be payed over a number of frames.
   // The debt is acquired by keyframes overshooting the bitrate target.
diff --git a/test/fake_vp8_decoder.cc b/test/fake_vp8_decoder.cc
index 8f29b74..3a47939 100644
--- a/test/fake_vp8_decoder.cc
+++ b/test/fake_vp8_decoder.cc
@@ -12,7 +12,8 @@
 
 #include <stddef.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/scoped_refptr.h"
 #include "api/video/i420_buffer.h"
 #include "api/video/video_frame.h"
@@ -60,8 +61,8 @@
   frame.set_rtp_timestamp(input.RtpTimestamp());
   frame.set_ntp_time_ms(input.ntp_time_ms_);
 
-  callback_->Decoded(frame, /*decode_time_ms=*/absl::nullopt,
-                     /*qp=*/absl::nullopt);
+  callback_->Decoded(frame, /*decode_time_ms=*/std::nullopt,
+                     /*qp=*/std::nullopt);
 
   return WEBRTC_VIDEO_CODEC_OK;
 }
diff --git a/test/fake_vp8_encoder.cc b/test/fake_vp8_encoder.cc
index 50a3009..a3e77ea 100644
--- a/test/fake_vp8_encoder.cc
+++ b/test/fake_vp8_encoder.cc
@@ -11,8 +11,8 @@
 #include "test/fake_vp8_encoder.h"
 
 #include <algorithm>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/video_codecs/video_encoder.h"
 #include "api/video_codecs/vp8_temporal_layers.h"
 #include "api/video_codecs/vp8_temporal_layers_factory.h"
diff --git a/test/frame_generator.cc b/test/frame_generator.cc
index d2fa953..7ef563a 100644
--- a/test/frame_generator.cc
+++ b/test/frame_generator.cc
@@ -100,7 +100,7 @@
     buffer = NV12Buffer::Copy(*buffer->ToI420());
   }
 
-  return VideoFrameData(buffer, absl::nullopt);
+  return VideoFrameData(buffer, std::nullopt);
 }
 
 SquareGenerator::Square::Square(int width, int height, int seed)
@@ -298,7 +298,7 @@
   if (++current_display_count_ >= frame_display_count_)
     current_display_count_ = 0;
 
-  return VideoFrameData(buffer_, absl::nullopt);
+  return VideoFrameData(buffer_, std::nullopt);
 }
 
 FrameGeneratorInterface::Resolution SlideGenerator::GetResolution() const {
@@ -363,8 +363,8 @@
       target_height_(static_cast<int>(target_height)),
       current_frame_num_(num_frames_ - 1),
       prev_frame_not_scrolled_(false),
-      current_source_frame_(nullptr, absl::nullopt),
-      current_frame_(nullptr, absl::nullopt),
+      current_source_frame_(nullptr, std::nullopt),
+      current_frame_(nullptr, std::nullopt),
       file_generator_(files, source_width, source_height, 1) {
   RTC_DCHECK(clock_ != nullptr);
   RTC_DCHECK_GT(num_frames_, 0);
diff --git a/test/frame_generator.h b/test/frame_generator.h
index 76f195d..471ce52 100644
--- a/test/frame_generator.h
+++ b/test/frame_generator.h
@@ -40,7 +40,7 @@
   VideoFrameData NextFrame() override;
   Resolution GetResolution() const override;
 
-  absl::optional<int> fps() const override { return absl::nullopt; }
+  std::optional<int> fps() const override { return std::nullopt; }
 
  private:
   rtc::scoped_refptr<I420Buffer> CreateI420Buffer(int width, int height);
@@ -84,7 +84,7 @@
   }
   Resolution GetResolution() const override;
 
-  absl::optional<int> fps() const override { return absl::nullopt; }
+  std::optional<int> fps() const override { return std::nullopt; }
 
  private:
   // Returns true if the new frame was loaded.
@@ -119,7 +119,7 @@
   }
   Resolution GetResolution() const override;
 
-  absl::optional<int> fps() const override { return absl::nullopt; }
+  std::optional<int> fps() const override { return std::nullopt; }
 
  private:
   // Returns true if the new frame was loaded.
@@ -151,7 +151,7 @@
   }
   Resolution GetResolution() const override;
 
-  absl::optional<int> fps() const override { return absl::nullopt; }
+  std::optional<int> fps() const override { return std::nullopt; }
 
  private:
   // Generates some randomly sized and colored squares scattered
@@ -185,7 +185,7 @@
   }
   Resolution GetResolution() const override;
 
-  absl::optional<int> fps() const override { return absl::nullopt; }
+  std::optional<int> fps() const override { return std::nullopt; }
 
  private:
   void UpdateSourceFrame(size_t frame_num);
diff --git a/test/frame_generator_capturer.cc b/test/frame_generator_capturer.cc
index 4641f4e..c96b056 100644
--- a/test/frame_generator_capturer.cc
+++ b/test/frame_generator_capturer.cc
@@ -14,9 +14,9 @@
 #include <cmath>
 #include <cstddef>
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/task_queue/task_queue_factory.h"
 #include "api/test/frame_generator_interface.h"
@@ -67,7 +67,7 @@
 }
 
 void FrameGeneratorCapturer::SetFakeColorSpace(
-    absl::optional<ColorSpace> color_space) {
+    std::optional<ColorSpace> color_space) {
   MutexLock lock(&lock_);
   fake_color_space_ = color_space;
 }
@@ -112,7 +112,7 @@
   }
 }
 
-absl::optional<FrameGeneratorCapturer::Resolution>
+std::optional<FrameGeneratorCapturer::Resolution>
 FrameGeneratorCapturer::GetResolution() const {
   FrameGeneratorInterface::Resolution resolution =
       frame_generator_->GetResolution();
@@ -175,7 +175,7 @@
 void FrameGeneratorCapturer::OnOutputFormatRequest(
     int width,
     int height,
-    const absl::optional<int>& max_fps) {
+    const std::optional<int>& max_fps) {
   TestVideoCapturer::OnOutputFormatRequest(width, height, max_fps);
 }
 
diff --git a/test/frame_generator_capturer.h b/test/frame_generator_capturer.h
index c1d0130..078bcec 100644
--- a/test/frame_generator_capturer.h
+++ b/test/frame_generator_capturer.h
@@ -13,8 +13,8 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/task_queue/task_queue_factory.h"
 #include "api/test/frame_generator_interface.h"
@@ -64,11 +64,11 @@
     int width;
     int height;
   };
-  absl::optional<Resolution> GetResolution() const;
+  std::optional<Resolution> GetResolution() const;
 
   void OnOutputFormatRequest(int width,
                              int height,
-                             const absl::optional<int>& max_fps);
+                             const std::optional<int>& max_fps);
 
   void SetSinkWantsObserver(SinkWantsObserver* observer);
 
@@ -78,7 +78,7 @@
 
   void ForceFrame();
   void SetFakeRotation(VideoRotation rotation);
-  void SetFakeColorSpace(absl::optional<ColorSpace> color_space);
+  void SetFakeColorSpace(std::optional<ColorSpace> color_space);
 
   bool Init();
 
@@ -98,7 +98,7 @@
   int source_fps_ RTC_GUARDED_BY(&lock_);
   int target_capture_fps_ RTC_GUARDED_BY(&lock_);
   VideoRotation fake_rotation_ = kVideoRotation_0;
-  absl::optional<ColorSpace> fake_color_space_ RTC_GUARDED_BY(&lock_);
+  std::optional<ColorSpace> fake_color_space_ RTC_GUARDED_BY(&lock_);
 
   std::unique_ptr<TaskQueueBase, TaskQueueDeleter> task_queue_;
 };
diff --git a/test/function_audio_decoder_factory.h b/test/function_audio_decoder_factory.h
index 2848ce8..c314249 100644
--- a/test/function_audio_decoder_factory.h
+++ b/test/function_audio_decoder_factory.h
@@ -32,14 +32,14 @@
       std::function<std::unique_ptr<AudioDecoder>()> create)
       : create_([create](const Environment&,
                          const SdpAudioFormat&,
-                         absl::optional<AudioCodecPairId> codec_pair_id) {
+                         std::optional<AudioCodecPairId> codec_pair_id) {
           return create();
         }) {}
   explicit FunctionAudioDecoderFactory(
       std::function<std::unique_ptr<AudioDecoder>(
           const Environment&,
           const SdpAudioFormat&,
-          absl::optional<AudioCodecPairId> codec_pair_id)> create)
+          std::optional<AudioCodecPairId> codec_pair_id)> create)
       : create_(std::move(create)) {}
 
   // Unused by tests.
@@ -55,7 +55,7 @@
   std::unique_ptr<AudioDecoder> Create(
       const Environment& env,
       const SdpAudioFormat& format,
-      absl::optional<AudioCodecPairId> codec_pair_id) override {
+      std::optional<AudioCodecPairId> codec_pair_id) override {
     return create_(env, format, codec_pair_id);
   }
 
@@ -63,7 +63,7 @@
   const std::function<std::unique_ptr<AudioDecoder>(
       const Environment&,
       const SdpAudioFormat&,
-      absl::optional<AudioCodecPairId> codec_pair_id)>
+      std::optional<AudioCodecPairId> codec_pair_id)>
       create_;
 };
 
diff --git a/test/fuzzers/BUILD.gn b/test/fuzzers/BUILD.gn
index 68c4d11..6d28c7b 100644
--- a/test/fuzzers/BUILD.gn
+++ b/test/fuzzers/BUILD.gn
@@ -238,7 +238,6 @@
   deps = [
     "../../common_video:common_video",
     "../../modules/rtp_rtcp:rtp_rtcp_format",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   seed_corpus = "corpora/rtp-corpus"
 }
@@ -307,7 +306,6 @@
     "../../api/audio_codecs:audio_codecs_api",
     "../../modules/rtp_rtcp:rtp_rtcp_format",
     "../../rtc_base:checks",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -590,7 +588,6 @@
     "../../api/audio:audio_processing",
     "../../modules/audio_processing:audio_buffer",
     "../../modules/audio_processing/aec3",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/test/fuzzers/aec3_fuzzer.cc b/test/fuzzers/aec3_fuzzer.cc
index 2e6d12e..71a316d 100644
--- a/test/fuzzers/aec3_fuzzer.cc
+++ b/test/fuzzers/aec3_fuzzer.cc
@@ -8,7 +8,8 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/audio/audio_processing.h"
 #include "modules/audio_processing/aec3/echo_canceller3.h"
 #include "modules/audio_processing/audio_buffer.h"
@@ -53,7 +54,7 @@
       1 + fuzz_data.ReadOrDefaultValue<uint8_t>(0) % (kMaxNumChannels - 1);
 
   EchoCanceller3 aec3(EchoCanceller3Config(),
-                      /*multichannel_config=*/absl::nullopt, sample_rate_hz,
+                      /*multichannel_config=*/std::nullopt, sample_rate_hz,
                       num_render_channels, num_capture_channels);
 
   AudioBuffer capture_audio(sample_rate_hz, num_capture_channels,
diff --git a/test/fuzzers/audio_decoder_fuzzer.cc b/test/fuzzers/audio_decoder_fuzzer.cc
index 1db332e..ccfd604 100644
--- a/test/fuzzers/audio_decoder_fuzzer.cc
+++ b/test/fuzzers/audio_decoder_fuzzer.cc
@@ -11,8 +11,8 @@
 #include "test/fuzzers/audio_decoder_fuzzer.h"
 
 #include <limits>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/audio_codecs/audio_decoder.h"
 #include "modules/rtp_rtcp/source/byte_io.h"
 #include "rtc_base/checks.h"
diff --git a/test/fuzzers/dcsctp_packet_fuzzer.cc b/test/fuzzers/dcsctp_packet_fuzzer.cc
index 2fc3fe1..339f7a5 100644
--- a/test/fuzzers/dcsctp_packet_fuzzer.cc
+++ b/test/fuzzers/dcsctp_packet_fuzzer.cc
@@ -14,7 +14,7 @@
 using dcsctp::SctpPacket;
 
 void FuzzOneInput(const uint8_t* data, size_t size) {
-  absl::optional<SctpPacket> c =
+  std::optional<SctpPacket> c =
       SctpPacket::Parse(rtc::ArrayView<const uint8_t>(data, size),
                         /*disable_checksum_verification=*/true);
 
diff --git a/test/fuzzers/neteq_rtp_fuzzer.cc b/test/fuzzers/neteq_rtp_fuzzer.cc
index 3caa5fe..e6933e3 100644
--- a/test/fuzzers/neteq_rtp_fuzzer.cc
+++ b/test/fuzzers/neteq_rtp_fuzzer.cc
@@ -69,15 +69,15 @@
     MaybeFuzzPayload();
   }
 
-  absl::optional<int64_t> NextPacketTime() const override {
+  std::optional<int64_t> NextPacketTime() const override {
     return packet_->time_ms;
   }
 
-  absl::optional<int64_t> NextOutputEventTime() const override {
+  std::optional<int64_t> NextOutputEventTime() const override {
     return input_->NextOutputEventTime();
   }
 
-  absl::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override {
+  std::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override {
     return input_->NextSetMinimumDelayInfo();
   }
 
@@ -98,7 +98,7 @@
 
   bool ended() const override { return ended_; }
 
-  absl::optional<RTPHeader> NextHeader() const override {
+  std::optional<RTPHeader> NextHeader() const override {
     RTC_DCHECK(packet_);
     return packet_->header;
   }
diff --git a/test/fuzzers/neteq_signal_fuzzer.cc b/test/fuzzers/neteq_signal_fuzzer.cc
index 3b1f70c..189f1dd 100644
--- a/test/fuzzers/neteq_signal_fuzzer.cc
+++ b/test/fuzzers/neteq_signal_fuzzer.cc
@@ -89,15 +89,15 @@
     output_event_period_ms_ = fuzz_data_.SelectOneOf(output_event_periods);
   }
 
-  absl::optional<int64_t> NextPacketTime() const override {
+  std::optional<int64_t> NextPacketTime() const override {
     return packet_->time_ms;
   }
 
-  absl::optional<int64_t> NextOutputEventTime() const override {
+  std::optional<int64_t> NextOutputEventTime() const override {
     return next_output_event_ms_;
   }
 
-  absl::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override {
+  std::optional<SetMinimumDelayInfo> NextSetMinimumDelayInfo() const override {
     return input_->NextSetMinimumDelayInfo();
   }
 
@@ -133,7 +133,7 @@
 
   bool ended() const override { return ended_; }
 
-  absl::optional<RTPHeader> NextHeader() const override {
+  std::optional<RTPHeader> NextHeader() const override {
     RTC_DCHECK(packet_);
     return packet_->header;
   }
diff --git a/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc b/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc
index f1c4904..5be9837c 100644
--- a/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc
+++ b/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc
@@ -68,9 +68,9 @@
   return result;
 }
 
-absl::optional<RTPVideoHeader::GenericDescriptorInfo>
+std::optional<RTPVideoHeader::GenericDescriptorInfo>
 GenerateGenericFrameDependencies(DataReader* reader) {
-  absl::optional<RTPVideoHeader::GenericDescriptorInfo> result;
+  std::optional<RTPVideoHeader::GenericDescriptorInfo> result;
   uint8_t flags = reader->GetNum<uint8_t>();
   if (flags & 0b1000'0000) {
     // i.e. with 50% chance there are no generic dependencies.
@@ -156,7 +156,7 @@
         kVideoRotation_0,
         VideoContentType::UNSPECIFIED,
         video_header,
-        /*color_space=*/absl::nullopt,
+        /*color_space=*/std::nullopt,
         RtpPacketInfos(),
         EncodedImageBuffer::Create(/*size=*/0));
     // clang-format on
diff --git a/test/fuzzers/rtp_packet_fuzzer.cc b/test/fuzzers/rtp_packet_fuzzer.cc
index 5d7c31d..eaa423e 100644
--- a/test/fuzzers/rtp_packet_fuzzer.cc
+++ b/test/fuzzers/rtp_packet_fuzzer.cc
@@ -9,9 +9,9 @@
  */
 
 #include <bitset>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "common_video/corruption_detection_message.h"
 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
 #include "modules/rtp_rtcp/source/corruption_detection_extension.h"
@@ -103,7 +103,7 @@
         break;
       case kRtpExtensionTransportSequenceNumber02: {
         uint16_t seqnum;
-        absl::optional<FeedbackRequest> feedback_request;
+        std::optional<FeedbackRequest> feedback_request;
         packet.GetExtension<TransportSequenceNumberV2>(&seqnum,
                                                        &feedback_request);
         break;
@@ -148,7 +148,7 @@
         break;
       }
       case kRtpExtensionInbandComfortNoise: {
-        absl::optional<uint8_t> noise_level;
+        std::optional<uint8_t> noise_level;
         packet.GetExtension<InbandComfortNoiseExtension>(&noise_level);
         break;
       }
diff --git a/test/ios/test_support.h b/test/ios/test_support.h
index 5ac7313..1f8f962 100644
--- a/test/ios/test_support.h
+++ b/test/ios/test_support.h
@@ -11,11 +11,10 @@
 #ifndef TEST_IOS_TEST_SUPPORT_H_
 #define TEST_IOS_TEST_SUPPORT_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
-
 namespace rtc {
 namespace test {
 // Launches an iOS app that serves as a host for a test suite.
@@ -28,7 +27,7 @@
                    bool save_chartjson_result,
                    bool export_perf_results_new_api,
                    std::string webrtc_test_metrics_output_path,
-                   absl::optional<std::vector<std::string>> metrics_to_plot);
+                   std::optional<std::vector<std::string>> metrics_to_plot);
 
 // Returns true if unittests should be run by the XCTest runnner.
 bool ShouldRunIOSUnittestsWithXCTest();
diff --git a/test/ios/test_support.mm b/test/ios/test_support.mm
index d3c9ee0..80208d5 100644
--- a/test/ios/test_support.mm
+++ b/test/ios/test_support.mm
@@ -46,8 +46,8 @@
 static bool g_write_perf_output;
 static bool g_export_perf_results_new_api;
 static std::string g_webrtc_test_metrics_output_path;
-static absl::optional<bool> g_is_xctest;
-static absl::optional<std::vector<std::string>> g_metrics_to_plot;
+static std::optional<bool> g_is_xctest;
+static std::optional<std::vector<std::string>> g_metrics_to_plot;
 
 @interface UIApplication (Testing)
 - (void)_terminateWithStatus:(int)status;
@@ -180,7 +180,7 @@
                    bool write_perf_output,
                    bool export_perf_results_new_api,
                    std::string webrtc_test_metrics_output_path,
-                   absl::optional<std::vector<std::string>> metrics_to_plot) {
+                   std::optional<std::vector<std::string>> metrics_to_plot) {
   g_test_suite = test_suite;
   g_argc = argc;
   g_argv = argv;
@@ -204,12 +204,12 @@
   char **argv = g_argv;
   while (*argv != nullptr) {
     if (strstr(*argv, kEnableRunIOSUnittestsWithXCTest) != nullptr) {
-      g_is_xctest = absl::optional<bool>(true);
+      g_is_xctest = std::optional<bool>(true);
       return true;
     }
     argv++;
   }
-  g_is_xctest = absl::optional<bool>(false);
+  g_is_xctest = std::optional<bool>(false);
   return false;
 }
 
diff --git a/test/jitter/BUILD.gn b/test/jitter/BUILD.gn
index 393ef28..c14c94c 100644
--- a/test/jitter/BUILD.gn
+++ b/test/jitter/BUILD.gn
@@ -24,7 +24,6 @@
     "../../api/video:video_frame_type",
     "../../rtc_base:logging",
     "../../rtc_base:rtc_numerics",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/test/jitter/delay_variation_calculator.cc b/test/jitter/delay_variation_calculator.cc
index 092bd7c..2d409f8 100644
--- a/test/jitter/delay_variation_calculator.cc
+++ b/test/jitter/delay_variation_calculator.cc
@@ -10,9 +10,9 @@
 
 #include "test/jitter/delay_variation_calculator.h"
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/units/frequency.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -29,9 +29,9 @@
     uint32_t rtp_timestamp,
     Timestamp arrival_time,
     DataSize size,
-    absl::optional<int> spatial_layer,
-    absl::optional<int> temporal_layer,
-    absl::optional<VideoFrameType> frame_type) {
+    std::optional<int> spatial_layer,
+    std::optional<int> temporal_layer,
+    std::optional<VideoFrameType> frame_type) {
   Frame frame{.rtp_timestamp = rtp_timestamp,
               .unwrapped_rtp_timestamp = unwrapper_.Unwrap(rtp_timestamp),
               .arrival_time = arrival_time,
diff --git a/test/jitter/delay_variation_calculator.h b/test/jitter/delay_variation_calculator.h
index 6400f82..6b06afe 100644
--- a/test/jitter/delay_variation_calculator.h
+++ b/test/jitter/delay_variation_calculator.h
@@ -14,9 +14,9 @@
 #include <stdint.h>
 
 #include <map>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/numerics/samples_stats_counter.h"
 #include "api/test/metrics/metrics_logger.h"
 #include "api/units/data_size.h"
@@ -56,9 +56,9 @@
   void Insert(uint32_t rtp_timestamp,
               Timestamp arrival_time,
               DataSize size,
-              absl::optional<int> spatial_layer = absl::nullopt,
-              absl::optional<int> temporal_layer = absl::nullopt,
-              absl::optional<VideoFrameType> frame_type = absl::nullopt);
+              std::optional<int> spatial_layer = std::nullopt,
+              std::optional<int> temporal_layer = std::nullopt,
+              std::optional<VideoFrameType> frame_type = std::nullopt);
 
   const TimeSeries& time_series() const { return time_series_; }
 
@@ -68,9 +68,9 @@
     int64_t unwrapped_rtp_timestamp;
     Timestamp arrival_time;
     DataSize size;
-    absl::optional<int> spatial_layer;
-    absl::optional<int> temporal_layer;
-    absl::optional<VideoFrameType> frame_type;
+    std::optional<int> spatial_layer;
+    std::optional<int> temporal_layer;
+    std::optional<VideoFrameType> frame_type;
   };
   using MetadataT = std::map<std::string, std::string>;
 
@@ -84,7 +84,7 @@
   MetadataT BuildMetadata(const Frame& frame);
 
   RtpTimestampUnwrapper unwrapper_;
-  absl::optional<Frame> prev_frame_ = absl::nullopt;
+  std::optional<Frame> prev_frame_ = std::nullopt;
   TimeSeries time_series_;
 };
 
diff --git a/test/jitter/logging_delay_variation_calculator.cc b/test/jitter/logging_delay_variation_calculator.cc
index aa58b0f..dc08a17 100644
--- a/test/jitter/logging_delay_variation_calculator.cc
+++ b/test/jitter/logging_delay_variation_calculator.cc
@@ -20,9 +20,9 @@
     uint32_t rtp_timestamp,
     Timestamp arrival_time,
     DataSize size,
-    absl::optional<int> spatial_layer,
-    absl::optional<int> temporal_layer,
-    absl::optional<VideoFrameType> frame_type) {
+    std::optional<int> spatial_layer,
+    std::optional<int> temporal_layer,
+    std::optional<VideoFrameType> frame_type) {
   calc_.Insert(rtp_timestamp, arrival_time, size, spatial_layer, temporal_layer,
                frame_type);
 }
diff --git a/test/jitter/logging_delay_variation_calculator.h b/test/jitter/logging_delay_variation_calculator.h
index f15d2ae..a3a67af 100644
--- a/test/jitter/logging_delay_variation_calculator.h
+++ b/test/jitter/logging_delay_variation_calculator.h
@@ -35,9 +35,9 @@
   void Insert(uint32_t rtp_timestamp,
               Timestamp arrival_time,
               DataSize size,
-              absl::optional<int> spatial_layer = absl::nullopt,
-              absl::optional<int> temporal_layer = absl::nullopt,
-              absl::optional<VideoFrameType> frame_type = absl::nullopt);
+              std::optional<int> spatial_layer = std::nullopt,
+              std::optional<int> temporal_layer = std::nullopt,
+              std::optional<VideoFrameType> frame_type = std::nullopt);
 
  private:
   void LogMetrics() const;
diff --git a/test/mock_audio_decoder_factory.h b/test/mock_audio_decoder_factory.h
index a577fdaf..d14a7dc 100644
--- a/test/mock_audio_decoder_factory.h
+++ b/test/mock_audio_decoder_factory.h
@@ -51,7 +51,7 @@
               Create,
               (const Environment&,
                const SdpAudioFormat&,
-               absl::optional<AudioCodecPairId>),
+               std::optional<AudioCodecPairId>),
               (override));
 };
 
diff --git a/test/mock_audio_encoder.h b/test/mock_audio_encoder.h
index 30518e8..19c7d9c 100644
--- a/test/mock_audio_encoder.h
+++ b/test/mock_audio_encoder.h
@@ -29,11 +29,11 @@
   MOCK_METHOD(size_t, Num10MsFramesInNextPacket, (), (const, override));
   MOCK_METHOD(size_t, Max10MsFramesInAPacket, (), (const, override));
   MOCK_METHOD(int, GetTargetBitrate, (), (const, override));
-  MOCK_METHOD((absl::optional<std::pair<TimeDelta, TimeDelta>>),
+  MOCK_METHOD((std::optional<std::pair<TimeDelta, TimeDelta>>),
               GetFrameLengthRange,
               (),
               (const, override));
-  MOCK_METHOD((absl::optional<std::pair<DataRate, DataRate>>),
+  MOCK_METHOD((std::optional<std::pair<DataRate, DataRate>>),
               GetBitrateRange,
               (),
               (const, override));
@@ -46,7 +46,7 @@
   MOCK_METHOD(void,
               OnReceivedUplinkBandwidth,
               (int target_audio_bitrate_bps,
-               absl::optional<int64_t> probing_interval_ms),
+               std::optional<int64_t> probing_interval_ms),
               (override));
   MOCK_METHOD(void,
               OnReceivedUplinkPacketLossFraction,
diff --git a/test/mock_audio_encoder_factory.h b/test/mock_audio_encoder_factory.h
index 9f1b0ce..0d3c96a 100644
--- a/test/mock_audio_encoder_factory.h
+++ b/test/mock_audio_encoder_factory.h
@@ -29,7 +29,7 @@
               GetSupportedEncoders,
               (),
               (override));
-  MOCK_METHOD(absl::optional<AudioCodecInfo>,
+  MOCK_METHOD(std::optional<AudioCodecInfo>,
               QueryAudioEncoder,
               (const SdpAudioFormat& format),
               (override));
diff --git a/test/network/BUILD.gn b/test/network/BUILD.gn
index ab92d88..8de643e 100644
--- a/test/network/BUILD.gn
+++ b/test/network/BUILD.gn
@@ -89,7 +89,6 @@
     "//third_party/abseil-cpp/absl/base:nullability",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -138,7 +137,6 @@
     "../../rtc_base:rtc_event",
     "../time_controller",
     "//third_party/abseil-cpp/absl/memory",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -223,7 +221,6 @@
     "../../rtc_base:race_checker",
     "../../rtc_base:random",
     "../../rtc_base/synchronization:mutex",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/test/network/cross_traffic.cc b/test/network/cross_traffic.cc
index dd34bd0..f5a0359 100644
--- a/test/network/cross_traffic.cc
+++ b/test/network/cross_traffic.cc
@@ -12,10 +12,10 @@
 
 #include <math.h>
 
+#include <optional>
 #include <utility>
 
 #include "absl/memory/memory.h"
-#include "absl/types/optional.h"
 #include "cross_traffic.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_minmax.h"
diff --git a/test/network/cross_traffic_unittest.cc b/test/network/cross_traffic_unittest.cc
index 5382f66..80f4d02 100644
--- a/test/network/cross_traffic_unittest.cc
+++ b/test/network/cross_traffic_unittest.cc
@@ -12,11 +12,11 @@
 
 #include <atomic>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/memory/memory.h"
-#include "absl/types/optional.h"
 #include "api/test/network_emulation_manager.h"
 #include "api/test/simulated_network.h"
 #include "api/units/data_rate.h"
diff --git a/test/network/fake_network_socket_server.cc b/test/network/fake_network_socket_server.cc
index 63828e5..8dcca34 100644
--- a/test/network/fake_network_socket_server.cc
+++ b/test/network/fake_network_socket_server.cc
@@ -75,7 +75,7 @@
   int error_ RTC_GUARDED_BY(&thread_);
   std::map<Option, int> options_map_ RTC_GUARDED_BY(&thread_);
 
-  absl::optional<EmulatedIpPacket> pending_ RTC_GUARDED_BY(thread_);
+  std::optional<EmulatedIpPacket> pending_ RTC_GUARDED_BY(thread_);
   rtc::scoped_refptr<PendingTaskSafetyFlag> alive_;
 };
 
@@ -135,7 +135,7 @@
     error_ = EADDRNOTAVAIL;
     return 2;
   }
-  absl::optional<uint16_t> port =
+  std::optional<uint16_t> port =
       endpoint_->BindReceiver(local_addr_.port(), this);
   if (!port) {
     local_addr_.Clear();
diff --git a/test/network/network_emulation.cc b/test/network/network_emulation.cc
index 28c7637..5a1d1dd 100644
--- a/test/network/network_emulation.cc
+++ b/test/network/network_emulation.cc
@@ -17,12 +17,12 @@
 #include <limits>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/base/nullability.h"
-#include "absl/types/optional.h"
 #include "api/numerics/samples_stats_counter.h"
 #include "api/sequence_checker.h"
 #include "api/task_queue/task_queue_base.h"
@@ -423,8 +423,7 @@
   if (process_task_.Running()) {
     process_task_.Stop();
   };
-  absl::optional<int64_t> next_time_us =
-      network_behavior_->NextDeliveryTimeUs();
+  std::optional<int64_t> next_time_us = network_behavior_->NextDeliveryTimeUs();
   if (!next_time_us)
     return;
   Timestamp current_time = clock_->CurrentTime();
@@ -436,7 +435,7 @@
         RTC_DCHECK_RUN_ON(task_queue_);
         Timestamp current_time = clock_->CurrentTime();
         Process(current_time);
-        absl::optional<int64_t> next_time_us =
+        std::optional<int64_t> next_time_us =
             network_behavior_->NextDeliveryTimeUs();
         if (!next_time_us) {
           process_task_.Stop();
@@ -502,7 +501,7 @@
 
 void NetworkRouterNode::RemoveDefaultReceiver() {
   RTC_DCHECK_RUN_ON(task_queue_);
-  default_receiver_ = absl::nullopt;
+  default_receiver_ = std::nullopt;
 }
 
 void NetworkRouterNode::SetWatcher(
@@ -636,19 +635,19 @@
   });
 }
 
-absl::optional<uint16_t> EmulatedEndpointImpl::BindReceiver(
+std::optional<uint16_t> EmulatedEndpointImpl::BindReceiver(
     uint16_t desired_port,
     EmulatedNetworkReceiverInterface* receiver) {
   return BindReceiverInternal(desired_port, receiver, /*is_one_shot=*/false);
 }
 
-absl::optional<uint16_t> EmulatedEndpointImpl::BindOneShotReceiver(
+std::optional<uint16_t> EmulatedEndpointImpl::BindOneShotReceiver(
     uint16_t desired_port,
     EmulatedNetworkReceiverInterface* receiver) {
   return BindReceiverInternal(desired_port, receiver, /*is_one_shot=*/true);
 }
 
-absl::optional<uint16_t> EmulatedEndpointImpl::BindReceiverInternal(
+std::optional<uint16_t> EmulatedEndpointImpl::BindReceiverInternal(
     uint16_t desired_port,
     EmulatedNetworkReceiverInterface* receiver,
     bool is_one_shot) {
@@ -675,7 +674,7 @@
     RTC_LOG(LS_INFO) << "Can't bind receiver to used port " << desired_port
                      << " in endpoint " << options_.log_name
                      << "; id=" << options_.id;
-    return absl::nullopt;
+    return std::nullopt;
   }
   RTC_LOG(LS_INFO) << "New receiver is binded to endpoint " << options_.log_name
                    << "; id=" << options_.id << " on port " << port;
@@ -715,7 +714,7 @@
   MutexLock lock(&receiver_lock_);
   RTC_LOG(LS_INFO) << "Default receiver is removed from endpoint "
                    << options_.log_name << "; id=" << options_.id;
-  default_receiver_ = absl::nullopt;
+  default_receiver_ = std::nullopt;
 }
 
 rtc::IPAddress EmulatedEndpointImpl::GetPeerLocalAddress() const {
diff --git a/test/network/network_emulation.h b/test/network/network_emulation.h
index 2feaa35..6dec782 100644
--- a/test/network/network_emulation.h
+++ b/test/network/network_emulation.h
@@ -16,12 +16,12 @@
 #include <deque>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/base/nullability.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/numerics/samples_stats_counter.h"
 #include "api/sequence_checker.h"
@@ -203,7 +203,7 @@
 
  private:
   const absl::Nonnull<TaskQueueBase*> task_queue_;
-  absl::optional<EmulatedNetworkReceiverInterface*> default_receiver_
+  std::optional<EmulatedNetworkReceiverInterface*> default_receiver_
       RTC_GUARDED_BY(task_queue_);
   std::map<rtc::IPAddress, EmulatedNetworkReceiverInterface*> routing_
       RTC_GUARDED_BY(task_queue_);
@@ -299,12 +299,12 @@
                   rtc::CopyOnWriteBuffer packet_data,
                   uint16_t application_overhead = 0) override;
 
-  absl::optional<uint16_t> BindReceiver(
+  std::optional<uint16_t> BindReceiver(
       uint16_t desired_port,
       EmulatedNetworkReceiverInterface* receiver) override;
   // Binds a receiver, and automatically removes the binding after first call to
   // OnPacketReceived.
-  absl::optional<uint16_t> BindOneShotReceiver(
+  std::optional<uint16_t> BindOneShotReceiver(
       uint16_t desired_port,
       EmulatedNetworkReceiverInterface* receiver);
   void UnbindReceiver(uint16_t port) override;
@@ -330,7 +330,7 @@
     bool is_one_shot;
   };
 
-  absl::optional<uint16_t> BindReceiverInternal(
+  std::optional<uint16_t> BindReceiverInternal(
       uint16_t desired_port,
       EmulatedNetworkReceiverInterface* receiver,
       bool is_one_shot);
@@ -349,7 +349,7 @@
   NetworkRouterNode router_;
 
   uint16_t next_port_ RTC_GUARDED_BY(receiver_lock_);
-  absl::optional<EmulatedNetworkReceiverInterface*> default_receiver_
+  std::optional<EmulatedNetworkReceiverInterface*> default_receiver_
       RTC_GUARDED_BY(receiver_lock_);
   std::map<uint16_t, ReceiverBinding> port_to_receiver_
       RTC_GUARDED_BY(receiver_lock_);
diff --git a/test/network/network_emulation_manager.cc b/test/network/network_emulation_manager.cc
index 6a583a3..47de184 100644
--- a/test/network/network_emulation_manager.cc
+++ b/test/network/network_emulation_manager.cc
@@ -99,7 +99,7 @@
 
 EmulatedEndpointImpl* NetworkEmulationManagerImpl::CreateEndpoint(
     EmulatedEndpointConfig config) {
-  absl::optional<rtc::IPAddress> ip = config.ip;
+  std::optional<rtc::IPAddress> ip = config.ip;
   if (!ip) {
     switch (config.generated_ip_family) {
       case EmulatedEndpointConfig::IpAddressFamily::kIpv4:
@@ -341,7 +341,7 @@
       });
 }
 
-absl::optional<rtc::IPAddress>
+std::optional<rtc::IPAddress>
 NetworkEmulationManagerImpl::GetNextIPv4Address() {
   uint32_t addresses_count = kMaxIPv4Address - kMinIPv4Address;
   for (uint32_t i = 0; i < addresses_count; i++) {
@@ -355,7 +355,7 @@
       return ip;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 Timestamp NetworkEmulationManagerImpl::Now() const {
diff --git a/test/network/network_emulation_manager.h b/test/network/network_emulation_manager.h
index 1c54241..154bd4b 100644
--- a/test/network/network_emulation_manager.h
+++ b/test/network/network_emulation_manager.h
@@ -99,7 +99,7 @@
   using CrossTrafficSource =
       std::pair<std::unique_ptr<CrossTrafficGenerator>, RepeatingTaskHandle>;
 
-  absl::optional<rtc::IPAddress> GetNextIPv4Address();
+  std::optional<rtc::IPAddress> GetNextIPv4Address();
 
   const TimeMode time_mode_;
   const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;
diff --git a/test/network/network_emulation_unittest.cc b/test/network/network_emulation_unittest.cc
index 805a1bf..b644361 100644
--- a/test/network/network_emulation_unittest.cc
+++ b/test/network/network_emulation_unittest.cc
@@ -88,10 +88,7 @@
               DequeueDeliverablePackets,
               (int64_t),
               (override));
-  MOCK_METHOD(absl::optional<int64_t>,
-              NextDeliveryTimeUs,
-              (),
-              (const override));
+  MOCK_METHOD(std::optional<int64_t>, NextDeliveryTimeUs, (), (const override));
   MOCK_METHOD(void,
               RegisterDeliveryTimeChangedCallback,
               (absl::AnyInvocable<void()>),
diff --git a/test/network/simulated_network.cc b/test/network/simulated_network.cc
index 5fe68b7..0663c0d 100644
--- a/test/network/simulated_network.cc
+++ b/test/network/simulated_network.cc
@@ -13,9 +13,9 @@
 #include <algorithm>
 #include <cmath>
 #include <cstdint>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/test/simulated_network.h"
 #include "api/units/data_rate.h"
 #include "api/units/data_size.h"
@@ -188,12 +188,12 @@
   return true;
 }
 
-absl::optional<int64_t> SimulatedNetwork::NextDeliveryTimeUs() const {
+std::optional<int64_t> SimulatedNetwork::NextDeliveryTimeUs() const {
   RTC_DCHECK_RUNS_SERIALIZED(&process_checker_);
   if (next_process_time_.IsFinite()) {
     return next_process_time_.us();
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void SimulatedNetwork::UpdateCapacityQueue(ConfigState state,
diff --git a/test/network/simulated_network.h b/test/network/simulated_network.h
index ae68824..4322aaf 100644
--- a/test/network/simulated_network.h
+++ b/test/network/simulated_network.h
@@ -14,10 +14,10 @@
 
 #include <cstdint>
 #include <deque>
+#include <optional>
 #include <queue>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/sequence_checker.h"
 #include "api/test/simulated_network.h"
 #include "api/units/timestamp.h"
@@ -70,7 +70,7 @@
   std::vector<PacketDeliveryInfo> DequeueDeliverablePackets(
       int64_t receive_time_us) override;
 
-  absl::optional<int64_t> NextDeliveryTimeUs() const override;
+  std::optional<int64_t> NextDeliveryTimeUs() const override;
   void RegisterDeliveryTimeChangedCallback(
       absl::AnyInvocable<void()> callback) override;
 
diff --git a/test/network/simulated_network_unittest.cc b/test/network/simulated_network_unittest.cc
index 536c1e2..21d70ec 100644
--- a/test/network/simulated_network_unittest.cc
+++ b/test/network/simulated_network_unittest.cc
@@ -37,7 +37,7 @@
 
 TEST(SimulatedNetworkTest, NextDeliveryTimeIsUnknownOnEmptyNetwork) {
   SimulatedNetwork network = SimulatedNetwork({});
-  EXPECT_EQ(network.NextDeliveryTimeUs(), absl::nullopt);
+  EXPECT_EQ(network.NextDeliveryTimeUs(), std::nullopt);
 }
 
 TEST(SimulatedNetworkTest, EnqueueFirstPacketOnNetworkWithInfiniteCapacity) {
@@ -329,7 +329,7 @@
   EXPECT_EQ(delivered_packets.size(), 1ul);
 
   // ... leaves the network empty.
-  EXPECT_EQ(network.NextDeliveryTimeUs(), absl::nullopt);
+  EXPECT_EQ(network.NextDeliveryTimeUs(), std::nullopt);
 }
 
 TEST(SimulatedNetworkTest, DequeueDeliverablePacketsOnLateCall) {
diff --git a/test/network/traffic_route.cc b/test/network/traffic_route.cc
index 94db5ae..5e39eb1 100644
--- a/test/network/traffic_route.cc
+++ b/test/network/traffic_route.cc
@@ -12,9 +12,9 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_minmax.h"
 
@@ -46,7 +46,7 @@
     EmulatedEndpointImpl* endpoint)
     : clock_(clock), receiver_(receiver), endpoint_(endpoint) {
   null_receiver_ = std::make_unique<NullReceiver>();
-  absl::optional<uint16_t> port =
+  std::optional<uint16_t> port =
       endpoint_->BindReceiver(0, null_receiver_.get());
   RTC_DCHECK(port);
   null_receiver_port_ = port.value();
@@ -65,7 +65,7 @@
   auto action_receiver = std::make_unique<ActionReceiver>(action);
   // BindOneShotReceiver arranges to free the port in the endpoint after the
   // action is done.
-  absl::optional<uint16_t> port =
+  std::optional<uint16_t> port =
       endpoint_->BindOneShotReceiver(0, action_receiver.get());
   RTC_DCHECK(port);
   actions_.push_back(std::move(action_receiver));
diff --git a/test/pc/e2e/BUILD.gn b/test/pc/e2e/BUILD.gn
index f9d1f47..01ae598 100644
--- a/test/pc/e2e/BUILD.gn
+++ b/test/pc/e2e/BUILD.gn
@@ -80,7 +80,6 @@
         "../../../rtc_base/synchronization:mutex",
         "//third_party/abseil-cpp/absl/memory",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
 
@@ -126,7 +125,6 @@
         "../../../api:sequence_checker",
         "../../../api/test/video:test_video_track_source",
         "../../../api/video:video_frame",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
 
@@ -201,7 +199,6 @@
         "../../../rtc_base/task_utils:repeating_task",
         "../../../system_wrappers",
         "//third_party/abseil-cpp/absl/memory",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
 
@@ -371,7 +368,6 @@
         "../../../api/test/pclf:peer_configurer",
         "../../../api/units:time_delta",
         "//third_party/abseil-cpp/absl/strings:string_view",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
 
@@ -440,7 +436,6 @@
       "../../../api:track_id_stream_info_map",
       "../../../rtc_base:macromagic",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -553,7 +548,6 @@
       "../../../rtc_base/synchronization:mutex",
       "../../../system_wrappers:field_trial",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -578,7 +572,6 @@
       "../../../rtc_base:stringutils",
       "//third_party/abseil-cpp/absl/memory",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
diff --git a/test/pc/e2e/analyzer/video/BUILD.gn b/test/pc/e2e/analyzer/video/BUILD.gn
index 33e358a..e055703 100644
--- a/test/pc/e2e/analyzer/video/BUILD.gn
+++ b/test/pc/e2e/analyzer/video/BUILD.gn
@@ -76,10 +76,7 @@
   testonly = true
   sources = [ "encoded_image_data_injector.h" ]
 
-  deps = [
-    "../../../../../api/video:encoded_image",
-    "//third_party/abseil-cpp/absl/types:optional",
-  ]
+  deps = [ "../../../../../api/video:encoded_image" ]
 }
 
 rtc_library("single_process_encoded_image_data_injector") {
@@ -140,7 +137,6 @@
     "../../../../../rtc_base:logging",
     "../../../../../rtc_base/synchronization:mutex",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -177,7 +173,6 @@
     "../../../../../rtc_base:macromagic",
     "../../../../../rtc_base/synchronization:mutex",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -249,17 +244,13 @@
     "../../../../../system_wrappers",
     "dvqa:pausable_state",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
 rtc_library("multi_reader_queue") {
   testonly = true
   sources = [ "multi_reader_queue.h" ]
-  deps = [
-    "../../../../../rtc_base:checks",
-    "//third_party/abseil-cpp/absl/types:optional",
-  ]
+  deps = [ "../../../../../rtc_base:checks" ]
 }
 
 rtc_library("video_quality_metrics_reporter") {
@@ -330,7 +321,6 @@
     "../../../../../api/units:timestamp",
     "../../../../../rtc_base:checks",
     "../../../../../rtc_base:stringutils",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -362,7 +352,6 @@
     "../../../../../system_wrappers",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings:string_view",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -434,7 +423,6 @@
       "../../../../../system_wrappers",
       "../../../../time_controller",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -445,7 +433,6 @@
       ":analyzing_video_sinks_helper",
       "../../../..:test_support",
       "../../../../../api/test/pclf:media_configuration",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -469,7 +456,6 @@
     deps = [
       ":default_video_quality_analyzer_internal",
       "../../../..:test_support",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -479,7 +465,6 @@
     deps = [
       ":multi_reader_queue",
       "../../../..:test_support",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
@@ -548,7 +533,6 @@
       "../../../../../api:scoped_refptr",
       "../../../../../api/video:video_frame",
       "../../../../../rtc_base:random",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 
diff --git a/test/pc/e2e/analyzer/video/analyzing_video_sink.cc b/test/pc/e2e/analyzer/video/analyzing_video_sink.cc
index 2392483..20e3966 100644
--- a/test/pc/e2e/analyzer/video/analyzing_video_sink.cc
+++ b/test/pc/e2e/analyzer/video/analyzing_video_sink.cc
@@ -10,12 +10,12 @@
 #include "test/pc/e2e/analyzer/video/analyzing_video_sink.h"
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <utility>
 
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/test/metrics/metric.h"
 #include "api/test/metrics/metrics_logger.h"
 #include "api/test/pclf/media_configuration.h"
@@ -58,7 +58,7 @@
     MutexLock lock(&mutex_);
     subscription_ = subscription;
     for (auto it = stream_sinks_.cbegin(); it != stream_sinks_.cend();) {
-      absl::optional<VideoResolution> new_requested_resolution =
+      std::optional<VideoResolution> new_requested_resolution =
           subscription_.GetResolutionForPeer(it->second.sender_peer_name);
       if (!new_requested_resolution.has_value() ||
           (*new_requested_resolution != it->second.resolution)) {
@@ -191,14 +191,14 @@
   }
 
   // Slow pass: we need to create and save sinks
-  absl::optional<std::pair<std::string, VideoConfig>> peer_and_config =
+  std::optional<std::pair<std::string, VideoConfig>> peer_and_config =
       sinks_helper_->GetPeerAndConfig(stream_label);
   RTC_CHECK(peer_and_config.has_value())
       << "No video config for stream " << stream_label;
   const std::string& sender_peer_name = peer_and_config->first;
   const VideoConfig& config = peer_and_config->second;
 
-  absl::optional<VideoResolution> resolution =
+  std::optional<VideoResolution> resolution =
       subscription_.GetResolutionForPeer(sender_peer_name);
   if (!resolution.has_value()) {
     RTC_LOG(LS_ERROR) << peer_name_ << " received stream " << stream_label
diff --git a/test/pc/e2e/analyzer/video/analyzing_video_sink_test.cc b/test/pc/e2e/analyzer/video/analyzing_video_sink_test.cc
index 6cd8955..b2f8ef8 100644
--- a/test/pc/e2e/analyzer/video/analyzing_video_sink_test.cc
+++ b/test/pc/e2e/analyzer/video/analyzing_video_sink_test.cc
@@ -11,11 +11,11 @@
 
 #include <stdio.h>
 
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
 #include "api/test/create_frame_generator.h"
 #include "api/test/frame_generator_interface.h"
@@ -45,7 +45,7 @@
 
 // Remove files and directories in a directory non-recursively.
 void CleanDir(absl::string_view dir, size_t expected_output_files_count) {
-  absl::optional<std::vector<std::string>> dir_content =
+  std::optional<std::vector<std::string>> dir_content =
       test::ReadDirectory(dir);
   if (expected_output_files_count == 0) {
     ASSERT_TRUE(!dir_content.has_value() || dir_content->empty())
@@ -81,8 +81,8 @@
     size_t width,
     size_t height) {
   return test::CreateSquareFrameGenerator(width, height,
-                                          /*type=*/absl::nullopt,
-                                          /*num_squares=*/absl::nullopt);
+                                          /*type=*/std::nullopt,
+                                          /*num_squares=*/std::nullopt);
 }
 
 void AssertFrameIdsAre(const std::string& filename,
diff --git a/test/pc/e2e/analyzer/video/analyzing_video_sinks_helper.cc b/test/pc/e2e/analyzer/video/analyzing_video_sinks_helper.cc
index 70dc4b0..cf4b1bb 100644
--- a/test/pc/e2e/analyzer/video/analyzing_video_sinks_helper.cc
+++ b/test/pc/e2e/analyzer/video/analyzing_video_sinks_helper.cc
@@ -36,12 +36,12 @@
   }
 }
 
-absl::optional<std::pair<std::string, VideoConfig>>
+std::optional<std::pair<std::string, VideoConfig>>
 AnalyzingVideoSinksHelper::GetPeerAndConfig(absl::string_view stream_label) {
   MutexLock lock(&mutex_);
   auto it = video_configs_.find(std::string(stream_label));
   if (it == video_configs_.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return it->second;
 }
diff --git a/test/pc/e2e/analyzer/video/analyzing_video_sinks_helper.h b/test/pc/e2e/analyzer/video/analyzing_video_sinks_helper.h
index 5f38c5a..a4a92af 100644
--- a/test/pc/e2e/analyzer/video/analyzing_video_sinks_helper.h
+++ b/test/pc/e2e/analyzer/video/analyzing_video_sinks_helper.h
@@ -14,12 +14,12 @@
 #include <list>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/test/pclf/media_configuration.h"
 #include "api/test/video/video_frame_writer.h"
 #include "rtc_base/synchronization/mutex.h"
@@ -35,7 +35,7 @@
   // Adds config in the registry. If config with such stream label was
   // registered before, the new value will override the old one.
   void AddConfig(absl::string_view sender_peer_name, VideoConfig config);
-  absl::optional<std::pair<std::string, VideoConfig>> GetPeerAndConfig(
+  std::optional<std::pair<std::string, VideoConfig>> GetPeerAndConfig(
       absl::string_view stream_label);
   // Removes video config for specified stream label. If there are no know video
   // config for such stream label - does nothing.
diff --git a/test/pc/e2e/analyzer/video/analyzing_video_sinks_helper_test.cc b/test/pc/e2e/analyzer/video/analyzing_video_sinks_helper_test.cc
index 1a820a5..792f44f 100644
--- a/test/pc/e2e/analyzer/video/analyzing_video_sinks_helper_test.cc
+++ b/test/pc/e2e/analyzer/video/analyzing_video_sinks_helper_test.cc
@@ -10,10 +10,10 @@
 #include "test/pc/e2e/analyzer/video/analyzing_video_sinks_helper.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/test/pclf/media_configuration.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
@@ -40,7 +40,7 @@
   AnalyzingVideoSinksHelper helper;
   helper.AddConfig("alice", config);
 
-  absl::optional<std::pair<std::string, VideoConfig>> registred_config =
+  std::optional<std::pair<std::string, VideoConfig>> registred_config =
       helper.GetPeerAndConfig("alice_video");
   ASSERT_TRUE(registred_config.has_value());
   EXPECT_THAT(registred_config->first, Eq("alice"));
@@ -56,7 +56,7 @@
   AnalyzingVideoSinksHelper helper;
   helper.AddConfig("alice", config_before);
 
-  absl::optional<std::pair<std::string, VideoConfig>> registred_config =
+  std::optional<std::pair<std::string, VideoConfig>> registred_config =
       helper.GetPeerAndConfig("alice_video");
   ASSERT_TRUE(registred_config.has_value());
   EXPECT_THAT(registred_config->first, Eq("alice"));
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
index 6c52cc5..5b1d558 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
@@ -111,10 +111,10 @@
 }
 
 template <typename T>
-absl::optional<T> MaybeGetValue(const std::map<size_t, T>& map, size_t key) {
+std::optional<T> MaybeGetValue(const std::map<size_t, T>& map, size_t key) {
   auto it = map.find(key);
   if (it == map.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return it->second;
 }
@@ -211,7 +211,7 @@
     }
     StreamState* state = &stream_states_.at(stream_index);
     state->PushBack(frame_id);
-    absl::optional<TimeDelta> time_between_captured_frames = absl::nullopt;
+    std::optional<TimeDelta> time_between_captured_frames = std::nullopt;
     if (state->last_captured_frame_time().has_value()) {
       time_between_captured_frames =
           captured_time - *state->last_captured_frame_time();
@@ -243,8 +243,8 @@
             StatsSample(captured_frames_in_flight_.size(), Now()));
         frames_comparator_.AddComparison(
             InternalStatsKey(stream_index, peer_index, i),
-            /*captured=*/absl::nullopt,
-            /*rendered=*/absl::nullopt, FrameComparisonType::kDroppedFrame,
+            /*captured=*/std::nullopt,
+            /*rendered=*/std::nullopt, FrameComparisonType::kDroppedFrame,
             it->second.GetStatsForPeer(i));
       }
 
@@ -349,7 +349,7 @@
   }
   Timestamp now = Now();
   StreamState& state = stream_states_.at(frame_in_flight.stream());
-  absl::optional<TimeDelta> time_between_encoded_frames = absl::nullopt;
+  std::optional<TimeDelta> time_between_encoded_frames = std::nullopt;
   if (state.last_encoded_frame_time().has_value()) {
     time_between_encoded_frames = now - *state.last_encoded_frame_time();
   }
@@ -527,7 +527,7 @@
 
   // Find corresponding captured frame.
   FrameInFlight* frame_in_flight = &frame_it->second;
-  absl::optional<VideoFrame> captured_frame = frames_storage_.Get(frame.id());
+  std::optional<VideoFrame> captured_frame = frames_storage_.Get(frame.id());
 
   const size_t stream_index = frame_in_flight->stream();
   StreamState* state = &stream_states_.at(stream_index);
@@ -699,7 +699,7 @@
     absl::string_view peer_name) {
   MutexLock lock(&mutex_);
   RTC_CHECK(peers_->HasName(peer_name));
-  absl::optional<size_t> peer_index = peers_->RemoveIfPresent(peer_name);
+  std::optional<size_t> peer_index = peers_->RemoveIfPresent(peer_name);
   RTC_CHECK(peer_index.has_value());
 
   for (auto& [stream_index, stream_state] : stream_states_) {
@@ -964,8 +964,8 @@
     RTC_DCHECK(it != captured_frames_in_flight_.end());
     FrameInFlight& frame = it->second;
 
-    frames_comparator_.AddComparison(stats_key, /*captured=*/absl::nullopt,
-                                     /*rendered=*/absl::nullopt,
+    frames_comparator_.AddComparison(stats_key, /*captured=*/std::nullopt,
+                                     /*rendered=*/std::nullopt,
                                      FrameComparisonType::kFrameInFlight,
                                      frame.GetStatsForPeer(peer_index));
   }
@@ -1053,8 +1053,8 @@
 
       analyzer_stats_.frames_in_flight_left_count.AddSample(
           StatsSample(captured_frames_in_flight_.size(), Now()));
-      frames_comparator_.AddComparison(stats_key, /*captured=*/absl::nullopt,
-                                       /*rendered=*/absl::nullopt,
+      frames_comparator_.AddComparison(stats_key, /*captured=*/std::nullopt,
+                                       /*rendered=*/std::nullopt,
                                        FrameComparisonType::kDroppedFrame,
                                        next_frame.GetStatsForPeer(peer_index));
     } else {
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.cc
index 6d7aa32..fb96ee6e 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.cc
@@ -10,11 +10,11 @@
 
 #include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.h"
 
+#include <optional>
 #include <unordered_map>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/units/data_size.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -26,11 +26,11 @@
 namespace {
 
 template <typename T>
-absl::optional<T> MaybeGetValue(const std::unordered_map<size_t, T>& map,
-                                size_t key) {
+std::optional<T> MaybeGetValue(const std::unordered_map<size_t, T>& map,
+                               size_t key) {
   auto it = map.find(key);
   if (it == map.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return it->second;
 }
@@ -41,7 +41,7 @@
     size_t stream,
     uint16_t frame_id,
     Timestamp captured_time,
-    absl::optional<TimeDelta> time_between_captured_frames,
+    std::optional<TimeDelta> time_between_captured_frames,
     std::set<size_t> expected_receivers)
     : stream_(stream),
       expected_receivers_(std::move(expected_receivers)),
@@ -79,7 +79,7 @@
 
 void FrameInFlight::OnFrameEncoded(
     webrtc::Timestamp time,
-    absl::optional<TimeDelta> time_between_encoded_frames,
+    std::optional<TimeDelta> time_between_encoded_frames,
     VideoFrameType frame_type,
     DataSize encoded_image_size,
     uint32_t target_encode_bitrate,
@@ -136,7 +136,7 @@
                                    int width,
                                    int height,
                                    const StreamCodecInfo& used_decoder,
-                                   const absl::optional<uint8_t> qp) {
+                                   const std::optional<uint8_t> qp) {
   receiver_stats_[peer].decode_end_time = time;
   receiver_stats_[peer].used_decoder = used_decoder;
   receiver_stats_[peer].decoded_frame_width = width;
@@ -194,7 +194,7 @@
   stats.used_encoder = used_encoder_;
   stats.spatial_layers_qp = stream_layers_qp_;
 
-  absl::optional<ReceiverFrameStats> receiver_stats =
+  std::optional<ReceiverFrameStats> receiver_stats =
       MaybeGetValue<ReceiverFrameStats>(receiver_stats_, peer);
   if (receiver_stats.has_value()) {
     stats.received_time = receiver_stats->received_time;
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.h b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.h
index 669330a..287aa6f 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.h
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.h
@@ -12,12 +12,12 @@
 #define TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_FRAME_IN_FLIGHT_H_
 
 #include <map>
+#include <optional>
 #include <set>
 #include <unordered_map>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/numerics/samples_stats_counter.h"
 #include "api/units/data_size.h"
 #include "api/units/time_delta.h"
@@ -36,20 +36,20 @@
   Timestamp rendered_time = Timestamp::MinusInfinity();
 
   // Will be set if there is frame rendered before this one.
-  absl::optional<Timestamp> prev_frame_rendered_time = absl::nullopt;
-  absl::optional<TimeDelta> time_between_rendered_frames = absl::nullopt;
+  std::optional<Timestamp> prev_frame_rendered_time = std::nullopt;
+  std::optional<TimeDelta> time_between_rendered_frames = std::nullopt;
 
   // Type and encoded size of received frame.
   VideoFrameType frame_type = VideoFrameType::kEmptyFrame;
   DataSize encoded_image_size = DataSize::Bytes(0);
 
-  absl::optional<int> decoded_frame_width = absl::nullopt;
-  absl::optional<int> decoded_frame_height = absl::nullopt;
+  std::optional<int> decoded_frame_width = std::nullopt;
+  std::optional<int> decoded_frame_height = std::nullopt;
 
-  absl::optional<uint8_t> decoded_frame_qp = absl::nullopt;
+  std::optional<uint8_t> decoded_frame_qp = std::nullopt;
 
   // Can be not set if frame was dropped in the network.
-  absl::optional<StreamCodecInfo> used_decoder = absl::nullopt;
+  std::optional<StreamCodecInfo> used_decoder = std::nullopt;
 
   bool dropped = false;
   bool decoder_failed = false;
@@ -71,7 +71,7 @@
   FrameInFlight(size_t stream,
                 uint16_t frame_id,
                 Timestamp captured_time,
-                absl::optional<TimeDelta> time_between_captured_frames,
+                std::optional<TimeDelta> time_between_captured_frames,
                 std::set<size_t> expected_receivers);
 
   size_t stream() const { return stream_; }
@@ -93,7 +93,7 @@
   void SetPreEncodeTime(Timestamp time) { pre_encode_time_ = time; }
 
   void OnFrameEncoded(Timestamp time,
-                      absl::optional<TimeDelta> time_between_encoded_frames,
+                      std::optional<TimeDelta> time_between_encoded_frames,
                       VideoFrameType frame_type,
                       DataSize encoded_image_size,
                       uint32_t target_encode_bitrate,
@@ -116,7 +116,7 @@
                       int width,
                       int height,
                       const StreamCodecInfo& used_decoder,
-                      const absl::optional<uint8_t> qp);
+                      const std::optional<uint8_t> qp);
 
   void OnDecoderError(size_t peer, const StreamCodecInfo& used_decoder);
 
@@ -170,8 +170,8 @@
   Timestamp pre_encode_time_ = Timestamp::MinusInfinity();
   Timestamp encoded_time_ = Timestamp::MinusInfinity();
 
-  absl::optional<TimeDelta> time_between_captured_frames_ = absl::nullopt;
-  absl::optional<TimeDelta> time_between_encoded_frames_ = absl::nullopt;
+  std::optional<TimeDelta> time_between_captured_frames_ = std::nullopt;
+  std::optional<TimeDelta> time_between_encoded_frames_ = std::nullopt;
 
   // Type and encoded size of sent frame.
   VideoFrameType frame_type_ = VideoFrameType::kEmptyFrame;
@@ -181,7 +181,7 @@
   // spatial or simulcast index is set in `EncodedImage`, 0 is used.
   std::map<int, SamplesStatsCounter> stream_layers_qp_;
   // Can be not set if frame was dropped by encoder.
-  absl::optional<StreamCodecInfo> used_encoder_ = absl::nullopt;
+  std::optional<StreamCodecInfo> used_encoder_ = std::nullopt;
   // Map from the receiver peer's index to frame stats for that peer.
   std::unordered_map<size_t, ReceiverFrameStats> receiver_stats_;
 };
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.cc
index 9db4057..96ba330 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.cc
@@ -12,11 +12,11 @@
 
 #include <algorithm>
 #include <map>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/scoped_refptr.h"
 #include "api/video/i420_buffer.h"
@@ -317,8 +317,8 @@
 
 void DefaultVideoQualityAnalyzerFramesComparator::AddComparison(
     InternalStatsKey stats_key,
-    absl::optional<VideoFrame> captured,
-    absl::optional<VideoFrame> rendered,
+    std::optional<VideoFrame> captured,
+    std::optional<VideoFrame> rendered,
     FrameComparisonType type,
     FrameStats frame_stats) {
   MutexLock lock(&mutex_);
@@ -331,8 +331,8 @@
 void DefaultVideoQualityAnalyzerFramesComparator::AddComparison(
     InternalStatsKey stats_key,
     int skipped_between_rendered,
-    absl::optional<VideoFrame> captured,
-    absl::optional<VideoFrame> rendered,
+    std::optional<VideoFrame> captured,
+    std::optional<VideoFrame> rendered,
     FrameComparisonType type,
     FrameStats frame_stats) {
   MutexLock lock(&mutex_);
@@ -349,8 +349,8 @@
 
 void DefaultVideoQualityAnalyzerFramesComparator::AddComparisonInternal(
     InternalStatsKey stats_key,
-    absl::optional<VideoFrame> captured,
-    absl::optional<VideoFrame> rendered,
+    std::optional<VideoFrame> captured,
+    std::optional<VideoFrame> rendered,
     FrameComparisonType type,
     FrameStats frame_stats) {
   cpu_measurer_.StartExcludingCpuThreadTime();
@@ -360,9 +360,9 @@
   // frames itself to make future computations lighter.
   if (comparisons_.size() >= kMaxActiveComparisons) {
     comparisons_.emplace_back(ValidateFrameComparison(
-        FrameComparison(std::move(stats_key), /*captured=*/absl::nullopt,
-                        /*rendered=*/absl::nullopt, type,
-                        std::move(frame_stats), OverloadReason::kCpu)));
+        FrameComparison(std::move(stats_key), /*captured=*/std::nullopt,
+                        /*rendered=*/std::nullopt, type, std::move(frame_stats),
+                        OverloadReason::kCpu)));
   } else {
     OverloadReason overload_reason = OverloadReason::kNone;
     if (!captured && type == FrameComparisonType::kRegular) {
@@ -379,7 +379,7 @@
 void DefaultVideoQualityAnalyzerFramesComparator::ProcessComparisons() {
   while (true) {
     // Try to pick next comparison to perform from the queue.
-    absl::optional<FrameComparison> comparison = absl::nullopt;
+    std::optional<FrameComparison> comparison = std::nullopt;
     bool more_new_comparisons_expected;
     {
       MutexLock lock(&mutex_);
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.h b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.h
index 006c3eb..b41268d 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.h
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.h
@@ -94,23 +94,23 @@
 
   // `captured` - video frame captured by sender to use for PSNR/SSIM
   //     computation. If `type` is `FrameComparisonType::kRegular` and
-  //     `captured` is `absl::nullopt` comparison is assumed to be overloaded
+  //     `captured` is `std::nullopt` comparison is assumed to be overloaded
   //     due to memory constraints.
   // `rendered` - video frame rendered by receiver to use for PSNR/SSIM
   //     computation. Required only if `type` is
   //     `FrameComparisonType::kRegular`, but can still be omitted if
-  //     `captured` is `absl::nullopt`.
+  //     `captured` is `std::nullopt`.
   void AddComparison(InternalStatsKey stats_key,
-                     absl::optional<VideoFrame> captured,
-                     absl::optional<VideoFrame> rendered,
+                     std::optional<VideoFrame> captured,
+                     std::optional<VideoFrame> rendered,
                      FrameComparisonType type,
                      FrameStats frame_stats);
   // `skipped_between_rendered` - amount of frames dropped on this stream before
   //     last received frame and current frame.
   void AddComparison(InternalStatsKey stats_key,
                      int skipped_between_rendered,
-                     absl::optional<VideoFrame> captured,
-                     absl::optional<VideoFrame> rendered,
+                     std::optional<VideoFrame> captured,
+                     std::optional<VideoFrame> rendered,
                      FrameComparisonType type,
                      FrameStats frame_stats);
 
@@ -127,8 +127,8 @@
   enum State { kNew, kActive, kStopped };
 
   void AddComparisonInternal(InternalStatsKey stats_key,
-                             absl::optional<VideoFrame> captured,
-                             absl::optional<VideoFrame> rendered,
+                             std::optional<VideoFrame> captured,
+                             std::optional<VideoFrame> rendered,
                              FrameComparisonType type,
                              FrameStats frame_stats)
       RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator_test.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator_test.cc
index ecd2a54..ca39eb7 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator_test.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator_test.cc
@@ -50,8 +50,8 @@
                        Timestamp timestamp) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(width, height,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
   test::FrameGeneratorInterface::VideoFrameData frame_data =
       frame_generator->NextFrame();
   return VideoFrame::Builder()
@@ -177,8 +177,8 @@
   comparator.EnsureStatsForStream(stream, sender, peers_count,
                                   stream_start_time, stream_start_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kRegular, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -223,12 +223,12 @@
   comparator.EnsureStatsForStream(stream, sender, peers_count,
                                   stream_start_time, stream_start_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kRegular, frame_stats1);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kRegular, frame_stats2);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -311,13 +311,13 @@
                                   stream_start_time, stream_start_time);
   for (size_t i = 0; i < stats.size() - 1; ++i) {
     comparator.AddComparison(stats_key,
-                             /*captured=*/absl::nullopt,
-                             /*rendered=*/absl::nullopt,
+                             /*captured=*/std::nullopt,
+                             /*rendered=*/std::nullopt,
                              FrameComparisonType::kFrameInFlight, stats[i]);
   }
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kRegular,
                            stats[stats.size() - 1]);
   comparator.Stop(/*last_rendered_frame_times=*/{});
@@ -378,8 +378,8 @@
   comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
                                   captured_time, captured_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kFrameInFlight, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -439,8 +439,8 @@
   comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
                                   captured_time, captured_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kFrameInFlight, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -512,8 +512,8 @@
   comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
                                   captured_time, captured_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kFrameInFlight, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -589,8 +589,8 @@
   comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
                                   captured_time, captured_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kFrameInFlight, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -671,8 +671,8 @@
   comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
                                   captured_time, captured_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kFrameInFlight, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -763,8 +763,8 @@
   comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
                                   captured_time, captured_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kFrameInFlight, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -854,8 +854,8 @@
   comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
                                   captured_time, captured_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kFrameInFlight, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -923,8 +923,8 @@
   comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
                                   captured_time, captured_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kDroppedFrame, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -984,8 +984,8 @@
   comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
                                   captured_time, captured_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kDroppedFrame, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -1057,8 +1057,8 @@
   comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
                                   captured_time, captured_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kDroppedFrame, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -1134,8 +1134,8 @@
   comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
                                   captured_time, captured_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kDroppedFrame, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -1212,8 +1212,8 @@
   comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
                                   captured_time, captured_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kDroppedFrame, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -1301,8 +1301,8 @@
   comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
                                   captured_time, captured_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kDroppedFrame, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -1389,8 +1389,8 @@
   comparator.EnsureStatsForStream(stream, sender, /*peers_count=*/2,
                                   captured_time, captured_time);
   comparator.AddComparison(stats_key,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kDroppedFrame, frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
@@ -1628,21 +1628,21 @@
 
   // Add 5 frames which were rendered with 30 fps (~30ms between frames)
   // Frame ids are in [1..5] and last frame is with 120ms offset from first.
-  absl::optional<Timestamp> prev_frame_rendered_time = absl::nullopt;
+  std::optional<Timestamp> prev_frame_rendered_time = std::nullopt;
   for (int i = 0; i < 5; ++i) {
     FrameStats frame_stats = FrameStatsWith10msDeltaBetweenPhasesAnd10x10Frame(
         /*frame_id=*/i + 1, stream_start_time + TimeDelta::Millis(30 * i));
     frame_stats.prev_frame_rendered_time = prev_frame_rendered_time;
     frame_stats.time_between_rendered_frames =
         prev_frame_rendered_time.has_value()
-            ? absl::optional<TimeDelta>(frame_stats.rendered_time -
-                                        *prev_frame_rendered_time)
-            : absl::nullopt;
+            ? std::optional<TimeDelta>(frame_stats.rendered_time -
+                                       *prev_frame_rendered_time)
+            : std::nullopt;
     prev_frame_rendered_time = frame_stats.rendered_time;
 
     comparator.AddComparison(stats_key,
-                             /*captured=*/absl::nullopt,
-                             /*rendered=*/absl::nullopt,
+                             /*captured=*/std::nullopt,
+                             /*rendered=*/std::nullopt,
                              FrameComparisonType::kRegular, frame_stats);
   }
 
@@ -1657,8 +1657,8 @@
 
   comparator.AddComparison(stats_key,
                            /*skipped_between_rendered=*/4,
-                           /*captured=*/absl::nullopt,
-                           /*rendered=*/absl::nullopt,
+                           /*captured=*/std::nullopt,
+                           /*rendered=*/std::nullopt,
                            FrameComparisonType::kRegular, freeze_frame_stats);
   comparator.Stop(/*last_rendered_frame_times=*/{});
 
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.cc
index 16f49ef..49e0f42 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.cc
@@ -37,8 +37,8 @@
 }
 
 FrameComparison::FrameComparison(InternalStatsKey stats_key,
-                                 absl::optional<VideoFrame> captured,
-                                 absl::optional<VideoFrame> rendered,
+                                 std::optional<VideoFrame> captured,
+                                 std::optional<VideoFrame> rendered,
                                  FrameComparisonType type,
                                  FrameStats frame_stats,
                                  OverloadReason overload_reason)
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.h b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.h
index 7a2cd71..c688748 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.h
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.h
@@ -12,11 +12,11 @@
 #define TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_INTERNAL_SHARED_OBJECTS_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/numerics/samples_stats_counter.h"
 #include "api/units/data_size.h"
 #include "api/units/timestamp.h"
@@ -59,10 +59,10 @@
   Timestamp rendered_time = Timestamp::MinusInfinity();
 
   // Next timings are set if and only if previous frame exist.
-  absl::optional<Timestamp> prev_frame_rendered_time = absl::nullopt;
-  absl::optional<TimeDelta> time_between_captured_frames = absl::nullopt;
-  absl::optional<TimeDelta> time_between_encoded_frames = absl::nullopt;
-  absl::optional<TimeDelta> time_between_rendered_frames = absl::nullopt;
+  std::optional<Timestamp> prev_frame_rendered_time = std::nullopt;
+  std::optional<TimeDelta> time_between_captured_frames = std::nullopt;
+  std::optional<TimeDelta> time_between_encoded_frames = std::nullopt;
+  std::optional<TimeDelta> time_between_rendered_frames = std::nullopt;
 
   VideoFrameType encoded_frame_type = VideoFrameType::kEmptyFrame;
   DataSize encoded_image_size = DataSize::Bytes(0);
@@ -76,15 +76,15 @@
   // time index. The QP value here corresponds to one of the encoded spatial
   // layer's QP given in `spatial_layers_qp`, i.e. to the one that corresponds
   // to the rendered frame.
-  absl::optional<uint8_t> decoded_frame_qp = absl::nullopt;
+  std::optional<uint8_t> decoded_frame_qp = std::nullopt;
 
-  absl::optional<int> decoded_frame_width = absl::nullopt;
-  absl::optional<int> decoded_frame_height = absl::nullopt;
+  std::optional<int> decoded_frame_width = std::nullopt;
+  std::optional<int> decoded_frame_height = std::nullopt;
 
   // Can be not set if frame was dropped by encoder.
-  absl::optional<StreamCodecInfo> used_encoder = absl::nullopt;
+  std::optional<StreamCodecInfo> used_encoder = std::nullopt;
   // Can be not set if frame was dropped in the network.
-  absl::optional<StreamCodecInfo> used_decoder = absl::nullopt;
+  std::optional<StreamCodecInfo> used_decoder = std::nullopt;
 
   bool decoder_failed = false;
 };
@@ -121,8 +121,8 @@
 //      true or false showing was frame dropped or not.
 struct FrameComparison {
   FrameComparison(InternalStatsKey stats_key,
-                  absl::optional<VideoFrame> captured,
-                  absl::optional<VideoFrame> rendered,
+                  std::optional<VideoFrame> captured,
+                  std::optional<VideoFrame> rendered,
                   FrameComparisonType type,
                   FrameStats frame_stats,
                   OverloadReason overload_reason);
@@ -130,8 +130,8 @@
   InternalStatsKey stats_key;
   // Frames can be omitted if there too many computations waiting in the
   // queue.
-  absl::optional<VideoFrame> captured;
-  absl::optional<VideoFrame> rendered;
+  std::optional<VideoFrame> captured;
+  std::optional<VideoFrame> rendered;
   FrameComparisonType type;
   FrameStats frame_stats;
   OverloadReason overload_reason;
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_metric_names_test.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_metric_names_test.cc
index 59ce998..906db56 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_metric_names_test.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_metric_names_test.cc
@@ -160,8 +160,8 @@
 TEST(DefaultVideoQualityAnalyzerMetricNamesTest, MetricNamesForP2PAreCorrect) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   DefaultMetricsLogger metrics_logger(Clock::GetRealTimeClock());
@@ -336,8 +336,8 @@
      MetricNamesFor3PeersAreCorrect) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   DefaultMetricsLogger metrics_logger(Clock::GetRealTimeClock());
@@ -662,8 +662,8 @@
      TestCaseFor3PeerIsTheSameAfterAllPeersLeft) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   DefaultMetricsLogger metrics_logger(Clock::GetRealTimeClock());
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.cc
index 79b9286..7915df3 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.cc
@@ -151,11 +151,11 @@
   return it->second;
 }
 
-absl::optional<std::string> VideoStreamsInfo::GetSender(
+std::optional<std::string> VideoStreamsInfo::GetSender(
     absl::string_view stream_label) const {
   auto it = stream_to_sender_.find(std::string(stream_label));
   if (it == stream_to_sender_.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return it->second;
 }
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h
index e5ab235..a2dbd5c 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h
@@ -14,13 +14,13 @@
 #include <cstdint>
 #include <map>
 #include <memory>
+#include <optional>
 #include <ostream>
 #include <set>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/numerics/samples_stats_counter.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -238,9 +238,9 @@
   // empty set will be returned.
   std::set<std::string> GetStreams(absl::string_view sender_name) const;
 
-  // Returns sender name for specified `stream_label`. Returns `absl::nullopt`
+  // Returns sender name for specified `stream_label`. Returns `std::nullopt`
   // if provided `stream_label` isn't known to the video analyzer.
-  absl::optional<std::string> GetSender(absl::string_view stream_label) const;
+  std::optional<std::string> GetSender(absl::string_view stream_label) const;
 
   // Returns set of the receivers for specified `stream_label`. If stream wasn't
   // received by any peer or `stream_label` isn't known to the video analyzer
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.cc
index bcdf16d..4b7b063 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.cc
@@ -10,10 +10,10 @@
 
 #include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.h"
 
+#include <optional>
 #include <set>
 #include <unordered_map>
 
-#include "absl/types/optional.h"
 #include "api/units/timestamp.h"
 #include "rtc_base/checks.h"
 #include "system_wrappers/include/clock.h"
@@ -23,11 +23,11 @@
 namespace {
 
 template <typename T>
-absl::optional<T> MaybeGetValue(const std::unordered_map<size_t, T>& map,
-                                size_t key) {
+std::optional<T> MaybeGetValue(const std::unordered_map<size_t, T>& map,
+                               size_t key) {
   auto it = map.find(key);
   if (it == map.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return it->second;
 }
@@ -53,7 +53,7 @@
 
 uint16_t StreamState::PopFront(size_t peer) {
   RTC_CHECK_NE(peer, kAliveFramesQueueIndex);
-  absl::optional<uint16_t> frame_id = frame_ids_.PopFront(peer);
+  std::optional<uint16_t> frame_id = frame_ids_.PopFront(peer);
   RTC_DCHECK(frame_id.has_value());
 
   // If alive's frame queue is longer than all others, than also pop frame from
@@ -62,7 +62,7 @@
   size_t other_size = GetLongestReceiverQueue();
   // Pops frame from alive queue if alive's queue is the longest one.
   if (alive_size > other_size) {
-    absl::optional<uint16_t> alive_frame_id =
+    std::optional<uint16_t> alive_frame_id =
         frame_ids_.PopFront(kAliveFramesQueueIndex);
     RTC_DCHECK(alive_frame_id.has_value());
     RTC_DCHECK_EQ(frame_id.value(), alive_frame_id.value());
@@ -110,7 +110,7 @@
   }
 }
 
-absl::optional<Timestamp> StreamState::last_rendered_frame_time(
+std::optional<Timestamp> StreamState::last_rendered_frame_time(
     size_t peer) const {
   return MaybeGetValue(last_rendered_frame_time_, peer);
 }
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.h b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.h
index 22fbfd4..bfc28e0 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.h
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.h
@@ -12,10 +12,10 @@
 #define TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_STREAM_STATE_H_
 
 #include <limits>
+#include <optional>
 #include <set>
 #include <unordered_map>
 
-#include "absl/types/optional.h"
 #include "api/units/timestamp.h"
 #include "system_wrappers/include/clock.h"
 #include "test/pc/e2e/analyzer/video/dvqa/pausable_state.h"
@@ -73,19 +73,19 @@
   void SetLastCapturedFrameTime(Timestamp time) {
     last_captured_frame_time_ = time;
   }
-  absl::optional<Timestamp> last_captured_frame_time() const {
+  std::optional<Timestamp> last_captured_frame_time() const {
     return last_captured_frame_time_;
   }
 
   void SetLastEncodedFrameTime(Timestamp time) {
     last_encoded_frame_time_ = time;
   }
-  absl::optional<Timestamp> last_encoded_frame_time() const {
+  std::optional<Timestamp> last_encoded_frame_time() const {
     return last_encoded_frame_time_;
   }
 
   void SetLastRenderedFrameTime(size_t peer, Timestamp time);
-  absl::optional<Timestamp> last_rendered_frame_time(size_t peer) const;
+  std::optional<Timestamp> last_rendered_frame_time(size_t peer) const;
 
  private:
   // Index of the `frame_ids_` queue which is used to track alive frames for
@@ -113,8 +113,8 @@
   // frame_id2 and consider those frames as dropped and then compare received
   // frame with the one from `FrameInFlight` with id frame_id3.
   MultiReaderQueue<uint16_t> frame_ids_;
-  absl::optional<Timestamp> last_captured_frame_time_ = absl::nullopt;
-  absl::optional<Timestamp> last_encoded_frame_time_ = absl::nullopt;
+  std::optional<Timestamp> last_captured_frame_time_ = std::nullopt;
+  std::optional<Timestamp> last_encoded_frame_time_ = std::nullopt;
   std::unordered_map<size_t, Timestamp> last_rendered_frame_time_;
   // Mapping from peer's index to pausable state for this receiver.
   std::unordered_map<size_t, PausableState> pausable_state_;
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc
index 97c0496..93b13f1 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc
@@ -211,8 +211,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, NormalScenario) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
                                        test::GetGlobalMetricsLogger(),
@@ -271,8 +271,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, OneFrameReceivedTwice) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
                                        test::GetGlobalMetricsLogger(),
@@ -324,8 +324,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, NormalScenario2Receivers) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   constexpr char kAlice[] = "alice";
   constexpr char kBob[] = "bob";
@@ -456,8 +456,8 @@
      OneFrameReceivedTwiceBySamePeerWith2Receivers) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   constexpr char kAlice[] = "alice";
   constexpr char kBob[] = "bob";
@@ -514,8 +514,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, HeavyQualityMetricsFromEqualFrames) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions analyzer_options;
   analyzer_options.compute_psnr = true;
@@ -573,8 +573,8 @@
      HeavyQualityMetricsFromShiftedFramesWithAdjustment) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions analyzer_options;
   analyzer_options.compute_psnr = true;
@@ -637,8 +637,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, CpuUsage) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
                                        test::GetGlobalMetricsLogger(),
@@ -693,8 +693,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, RuntimeParticipantsAdding) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   constexpr char kAlice[] = "alice";
   constexpr char kBob[] = "bob";
@@ -849,8 +849,8 @@
      SimulcastFrameWasFullyReceivedByAllPeersBeforeEncodeFinish) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
                                        test::GetGlobalMetricsLogger(),
@@ -911,8 +911,8 @@
      FrameCanBeReceivedBySenderAfterItWasReceivedByReceiver) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   options.enable_receive_own_stream = true;
@@ -1008,8 +1008,8 @@
      FrameCanBeReceivedByReceiverAfterItWasReceivedBySender) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   options.enable_receive_own_stream = true;
@@ -1104,8 +1104,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, CodecTrackedCorrectly) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
                                        test::GetGlobalMetricsLogger(),
@@ -1175,8 +1175,8 @@
      FramesInFlightAreCorrectlySentToTheComparatorAfterStop) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
@@ -1267,8 +1267,8 @@
     FramesInFlightAreCorrectlySentToTheComparatorAfterStopForSenderAndReceiver) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   options.enable_receive_own_stream = true;
@@ -1373,8 +1373,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, GetStreamFrames) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
@@ -1419,8 +1419,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, ReceiverReceivedFramesWhenSenderRemoved) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
@@ -1462,8 +1462,8 @@
      ReceiverReceivedFramesWhenSenderRemovedWithSelfview) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   options.enable_receive_own_stream = true;
@@ -1506,8 +1506,8 @@
      SenderReceivedFramesWhenReceiverRemovedWithSelfview) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   options.enable_receive_own_stream = true;
@@ -1550,8 +1550,8 @@
      SenderAndReceiverReceivedFramesWhenReceiverRemovedWithSelfview) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   options.enable_receive_own_stream = true;
@@ -1607,8 +1607,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, ReceiverRemovedBeforeCapturing2ndFrame) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
@@ -1648,8 +1648,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, ReceiverRemovedBeforePreEncoded) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
@@ -1691,8 +1691,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, ReceiverRemovedBeforeEncoded) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
@@ -1735,8 +1735,8 @@
      ReceiverRemovedBetweenSimulcastLayersEncoded) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
@@ -1782,8 +1782,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, UnregisterOneAndRegisterAnother) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
@@ -1844,8 +1844,8 @@
      UnregisterOneAndRegisterAnotherRegisterBack) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
@@ -1900,8 +1900,8 @@
      FramesInFlightAreAccountedForUnregisterPeers) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
@@ -1934,8 +1934,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, InfraMetricsAreReportedWhenRequested) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   options.report_infra_metrics = true;
@@ -1966,8 +1966,8 @@
 TEST(DefaultVideoQualityAnalyzerTest, InfraMetricsNotCollectedByDefault) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   options.report_infra_metrics = false;
@@ -1999,8 +1999,8 @@
      FrameDroppedByDecoderIsAccountedCorrectly) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   options.report_infra_metrics = false;
@@ -2041,8 +2041,8 @@
        TimeBetweenFreezesIsEqualToStreamDurationWhenThereAreNoFeeezes) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
@@ -2094,8 +2094,8 @@
        PausedAndResumedStreamIsAccountedInStatsCorrectly) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   options.report_infra_metrics = false;
@@ -2172,8 +2172,8 @@
        PausedAndResumedTwoStreamsAreAccountedInStatsCorrectly) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzer analyzer(
       GetClock(), test::GetGlobalMetricsLogger(), AnalyzerOptionsForTest());
@@ -2250,8 +2250,8 @@
        PausedStreamIsAccountedInStatsCorrectly) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest();
   options.report_infra_metrics = false;
@@ -2320,8 +2320,8 @@
        MemoryOverloadedAndThenAllFramesReceived) {
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
 
   DefaultVideoQualityAnalyzer analyzer(
       GetClock(), test::GetGlobalMetricsLogger(), AnalyzerOptionsForTest());
@@ -2382,8 +2382,8 @@
   constexpr char kBobStreamLabel[] = "bob-video";
   std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
       test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
-                                       /*type=*/absl::nullopt,
-                                       /*num_squares=*/absl::nullopt);
+                                       /*type=*/std::nullopt,
+                                       /*num_squares=*/std::nullopt);
   DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
                                        test::GetGlobalMetricsLogger(),
                                        AnalyzerOptionsForTest());
diff --git a/test/pc/e2e/analyzer/video/dvqa/BUILD.gn b/test/pc/e2e/analyzer/video/dvqa/BUILD.gn
index aae1852..fd250f4 100644
--- a/test/pc/e2e/analyzer/video/dvqa/BUILD.gn
+++ b/test/pc/e2e/analyzer/video/dvqa/BUILD.gn
@@ -72,7 +72,6 @@
     "../../../../../../api/units:timestamp",
     "../../../../../../api/video:video_frame",
     "../../../../../../system_wrappers",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/test/pc/e2e/analyzer/video/dvqa/frames_storage.cc b/test/pc/e2e/analyzer/video/dvqa/frames_storage.cc
index 2a70468..369295f 100644
--- a/test/pc/e2e/analyzer/video/dvqa/frames_storage.cc
+++ b/test/pc/e2e/analyzer/video/dvqa/frames_storage.cc
@@ -11,9 +11,9 @@
 #include "test/pc/e2e/analyzer/video/dvqa/frames_storage.h"
 
 #include <cstdint>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/units/timestamp.h"
 #include "api/video/video_frame.h"
 
@@ -26,10 +26,10 @@
   RemoveTooOldFrames();
 }
 
-absl::optional<VideoFrame> FramesStorage::Get(uint16_t frame_id) {
+std::optional<VideoFrame> FramesStorage::Get(uint16_t frame_id) {
   auto it = frame_id_index_.find(frame_id);
   if (it == frame_id_index_.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return heap_[it->second].frame;
diff --git a/test/pc/e2e/analyzer/video/dvqa/frames_storage.h b/test/pc/e2e/analyzer/video/dvqa/frames_storage.h
index d3c6bd4..05012e6 100644
--- a/test/pc/e2e/analyzer/video/dvqa/frames_storage.h
+++ b/test/pc/e2e/analyzer/video/dvqa/frames_storage.h
@@ -12,10 +12,10 @@
 #define TEST_PC_E2E_ANALYZER_VIDEO_DVQA_FRAMES_STORAGE_H_
 
 #include <cstdint>
+#include <optional>
 #include <unordered_map>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
 #include "api/video/video_frame.h"
@@ -41,7 +41,7 @@
   void Add(const VideoFrame& frame, Timestamp captured_time);
 
   // Complexity: O(1)
-  absl::optional<VideoFrame> Get(uint16_t frame_id);
+  std::optional<VideoFrame> Get(uint16_t frame_id);
 
   // Removes the frame identified by `frame_id` from the storage. No error
   // happens in case there isn't a frame identified by `frame_id`.
diff --git a/test/pc/e2e/analyzer/video/dvqa/frames_storage_test.cc b/test/pc/e2e/analyzer/video/dvqa/frames_storage_test.cc
index 88a172e..ae6e95d 100644
--- a/test/pc/e2e/analyzer/video/dvqa/frames_storage_test.cc
+++ b/test/pc/e2e/analyzer/video/dvqa/frames_storage_test.cc
@@ -40,7 +40,7 @@
 }
 
 void AssertHasFrame(FramesStorage& storage, uint16_t frame_id) {
-  absl::optional<VideoFrame> frame = storage.Get(frame_id);
+  std::optional<VideoFrame> frame = storage.Get(frame_id);
   ASSERT_TRUE(frame.has_value()) << "Frame " << frame_id << " wasn't found";
   EXPECT_EQ(frame->id(), frame_id);
 }
diff --git a/test/pc/e2e/analyzer/video/encoded_image_data_injector.h b/test/pc/e2e/analyzer/video/encoded_image_data_injector.h
index 384e901..3074701 100644
--- a/test/pc/e2e/analyzer/video/encoded_image_data_injector.h
+++ b/test/pc/e2e/analyzer/video/encoded_image_data_injector.h
@@ -12,9 +12,9 @@
 #define TEST_PC_E2E_ANALYZER_VIDEO_ENCODED_IMAGE_DATA_INJECTOR_H_
 
 #include <cstdint>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/video/encoded_image.h"
 
 namespace webrtc {
@@ -35,7 +35,7 @@
 };
 
 struct EncodedImageExtractionResult {
-  absl::optional<uint16_t> id;
+  std::optional<uint16_t> id;
   EncodedImage image;
   // Is true if encoded image should be discarded. It is used to filter out
   // unnecessary spatial layers and simulcast streams.
diff --git a/test/pc/e2e/analyzer/video/multi_reader_queue.h b/test/pc/e2e/analyzer/video/multi_reader_queue.h
index 39d26b4..99c53d0 100644
--- a/test/pc/e2e/analyzer/video/multi_reader_queue.h
+++ b/test/pc/e2e/analyzer/video/multi_reader_queue.h
@@ -13,10 +13,10 @@
 
 #include <deque>
 #include <memory>
+#include <optional>
 #include <set>
 #include <unordered_map>
 
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
@@ -90,10 +90,10 @@
   }
 
   // Extract element from specified head. Complexity O(1).
-  absl::optional<T> PopFront(size_t reader) {
+  std::optional<T> PopFront(size_t reader) {
     size_t pos = GetHeadPositionOrDie(reader);
     if (pos >= queue_.size()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     T out = queue_[pos];
@@ -109,10 +109,10 @@
   }
 
   // Returns element at specified head. Complexity O(1).
-  absl::optional<T> Front(size_t reader) const {
+  std::optional<T> Front(size_t reader) const {
     size_t pos = GetHeadPositionOrDie(reader);
     if (pos >= queue_.size()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return queue_[pos];
   }
diff --git a/test/pc/e2e/analyzer/video/multi_reader_queue_test.cc b/test/pc/e2e/analyzer/video/multi_reader_queue_test.cc
index ea6aa0a..a035f44 100644
--- a/test/pc/e2e/analyzer/video/multi_reader_queue_test.cc
+++ b/test/pc/e2e/analyzer/video/multi_reader_queue_test.cc
@@ -10,7 +10,8 @@
 
 #include "test/pc/e2e/analyzer/video/multi_reader_queue.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "test/gtest.h"
 
 namespace webrtc {
@@ -48,7 +49,7 @@
   // Removing elements from queue #0
   for (int i = 0; i < 5; ++i) {
     EXPECT_EQ(queue.size(/*reader=*/0), static_cast<size_t>(5 - i));
-    EXPECT_EQ(queue.PopFront(/*reader=*/0), absl::optional<int>(i));
+    EXPECT_EQ(queue.PopFront(/*reader=*/0), std::optional<int>(i));
     for (int j = 1; j < 10; ++j) {
       EXPECT_EQ(queue.size(/*reader=*/j), 5lu);
     }
@@ -63,7 +64,7 @@
   EXPECT_EQ(queue.size(), 1lu);
   EXPECT_TRUE(queue.Front(/*reader=*/0).has_value());
   EXPECT_EQ(queue.Front(/*reader=*/0).value(), 1);
-  absl::optional<int> value = queue.PopFront(/*reader=*/0);
+  std::optional<int> value = queue.PopFront(/*reader=*/0);
   EXPECT_TRUE(value.has_value());
   EXPECT_EQ(value.value(), 1);
   EXPECT_EQ(queue.size(), 0lu);
@@ -78,8 +79,8 @@
     EXPECT_EQ(queue.size(), i + 1);
   }
   for (size_t i = 0; i < 10; ++i) {
-    EXPECT_EQ(queue.Front(/*reader=*/0), absl::optional<size_t>(i));
-    EXPECT_EQ(queue.PopFront(/*reader=*/0), absl::optional<size_t>(i));
+    EXPECT_EQ(queue.Front(/*reader=*/0), std::optional<size_t>(i));
+    EXPECT_EQ(queue.PopFront(/*reader=*/0), std::optional<size_t>(i));
     EXPECT_EQ(queue.size(), 10 - i - 1);
   }
 }
@@ -92,19 +93,19 @@
     EXPECT_EQ(queue.size(), i + 1);
   }
   for (size_t i = 0; i < 10; ++i) {
-    absl::optional<size_t> value = queue.PopFront(/*reader=*/0);
+    std::optional<size_t> value = queue.PopFront(/*reader=*/0);
     EXPECT_EQ(queue.size(), 10lu);
     ASSERT_TRUE(value.has_value());
     EXPECT_EQ(value.value(), i);
   }
   for (size_t i = 0; i < 10; ++i) {
-    absl::optional<size_t> value = queue.PopFront(/*reader=*/1);
+    std::optional<size_t> value = queue.PopFront(/*reader=*/1);
     EXPECT_EQ(queue.size(), 10lu);
     ASSERT_TRUE(value.has_value());
     EXPECT_EQ(value.value(), i);
   }
   for (size_t i = 0; i < 10; ++i) {
-    absl::optional<size_t> value = queue.PopFront(/*reader=*/2);
+    std::optional<size_t> value = queue.PopFront(/*reader=*/2);
     EXPECT_EQ(queue.size(), 10 - i - 1);
     ASSERT_TRUE(value.has_value());
     EXPECT_EQ(value.value(), i);
@@ -119,9 +120,9 @@
     EXPECT_EQ(queue.size(), i + 1);
   }
   for (size_t i = 0; i < 10; ++i) {
-    absl::optional<size_t> value1 = queue.PopFront(/*reader=*/0);
-    absl::optional<size_t> value2 = queue.PopFront(/*reader=*/1);
-    absl::optional<size_t> value3 = queue.PopFront(/*reader=*/2);
+    std::optional<size_t> value1 = queue.PopFront(/*reader=*/0);
+    std::optional<size_t> value2 = queue.PopFront(/*reader=*/1);
+    std::optional<size_t> value3 = queue.PopFront(/*reader=*/2);
     EXPECT_EQ(queue.size(), 10 - i - 1);
     ASSERT_TRUE(value1.has_value());
     ASSERT_TRUE(value2.has_value());
@@ -146,7 +147,7 @@
 
   EXPECT_EQ(queue.readers_count(), 3lu);
   for (size_t i = 5; i < 10; ++i) {
-    absl::optional<size_t> value = queue.PopFront(/*reader=*/2);
+    std::optional<size_t> value = queue.PopFront(/*reader=*/2);
     EXPECT_EQ(queue.size(/*reader=*/2), 10 - i - 1);
     ASSERT_TRUE(value.has_value());
     EXPECT_EQ(value.value(), i);
@@ -167,7 +168,7 @@
 
   EXPECT_EQ(queue.readers_count(), 3lu);
   for (size_t i = 0; i < 10; ++i) {
-    absl::optional<size_t> value = queue.PopFront(/*reader=*/2);
+    std::optional<size_t> value = queue.PopFront(/*reader=*/2);
     EXPECT_EQ(queue.size(/*reader=*/2), 10 - i - 1);
     ASSERT_TRUE(value.has_value());
     EXPECT_EQ(value.value(), i);
diff --git a/test/pc/e2e/analyzer/video/names_collection.cc b/test/pc/e2e/analyzer/video/names_collection.cc
index 3ccab620..33dbc93 100644
--- a/test/pc/e2e/analyzer/video/names_collection.cc
+++ b/test/pc/e2e/analyzer/video/names_collection.cc
@@ -10,10 +10,10 @@
 
 #include "test/pc/e2e/analyzer/video/names_collection.h"
 
+#include <optional>
 #include <set>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 
 namespace webrtc {
 
@@ -65,15 +65,14 @@
   return out;
 }
 
-absl::optional<size_t> NamesCollection::RemoveIfPresent(
-    absl::string_view name) {
+std::optional<size_t> NamesCollection::RemoveIfPresent(absl::string_view name) {
   auto it = index_.find(name);
   if (it == index_.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   size_t index = it->second;
   if (removed_[index]) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   removed_[index] = true;
   size_--;
diff --git a/test/pc/e2e/analyzer/video/names_collection.h b/test/pc/e2e/analyzer/video/names_collection.h
index f9a13a2..a306ca7 100644
--- a/test/pc/e2e/analyzer/video/names_collection.h
+++ b/test/pc/e2e/analyzer/video/names_collection.h
@@ -12,12 +12,12 @@
 #define TEST_PC_E2E_ANALYZER_VIDEO_NAMES_COLLECTION_H_
 
 #include <map>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 
 namespace webrtc {
@@ -70,9 +70,9 @@
   // will continue to return previously known index for `index(name)` and return
   // `name` for `name(index(name))`.
   //
-  // Returns the index of the removed value or absl::nullopt if no such `name`
+  // Returns the index of the removed value or std::nullopt if no such `name`
   // registered in the collection.
-  absl::optional<size_t> RemoveIfPresent(absl::string_view name);
+  std::optional<size_t> RemoveIfPresent(absl::string_view name);
 
   // Returns a set of indexes for all currently present names in the
   // collection.
diff --git a/test/pc/e2e/analyzer/video/names_collection_test.cc b/test/pc/e2e/analyzer/video/names_collection_test.cc
index 6c52f96..e67c23f 100644
--- a/test/pc/e2e/analyzer/video/names_collection_test.cc
+++ b/test/pc/e2e/analyzer/video/names_collection_test.cc
@@ -10,10 +10,10 @@
 
 #include "test/pc/e2e/analyzer/video/names_collection.h"
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
 
@@ -76,7 +76,7 @@
   EXPECT_THAT(collection.size(), Eq(static_cast<size_t>(2)));
 
   EXPECT_THAT(collection.RemoveIfPresent("bob"),
-              Eq(absl::optional<size_t>(bob_index)));
+              Eq(std::optional<size_t>(bob_index)));
 
   EXPECT_THAT(collection.size(), Eq(static_cast<size_t>(1)));
   EXPECT_FALSE(collection.HasName("bob"));
@@ -94,7 +94,7 @@
   EXPECT_THAT(collection.size(), Eq(static_cast<size_t>(2)));
 
   EXPECT_THAT(collection.RemoveIfPresent("alice"),
-              Eq(absl::optional<size_t>(alice_index)));
+              Eq(std::optional<size_t>(alice_index)));
 
   EXPECT_THAT(collection.size(), Eq(static_cast<size_t>(1)));
   EXPECT_THAT(collection.index("bob"), Eq(bob_index));
@@ -108,17 +108,17 @@
 
   EXPECT_THAT(collection.size(), Eq(static_cast<size_t>(1)));
   EXPECT_THAT(collection.RemoveIfPresent("bob"),
-              Eq(absl::optional<size_t>(bob_index)));
+              Eq(std::optional<size_t>(bob_index)));
 
   EXPECT_THAT(collection.size(), Eq(static_cast<size_t>(0)));
-  EXPECT_THAT(collection.RemoveIfPresent("bob"), Eq(absl::nullopt));
+  EXPECT_THAT(collection.RemoveIfPresent("bob"), Eq(std::nullopt));
 }
 
 TEST(NamesCollectionTest, RemoveOfNotExistingHasNoEffect) {
   NamesCollection collection(std::vector<std::string>{"bob"});
 
   EXPECT_THAT(collection.size(), Eq(static_cast<size_t>(1)));
-  EXPECT_THAT(collection.RemoveIfPresent("alice"), Eq(absl::nullopt));
+  EXPECT_THAT(collection.RemoveIfPresent("alice"), Eq(std::nullopt));
   EXPECT_THAT(collection.size(), Eq(static_cast<size_t>(1)));
 }
 
@@ -129,7 +129,7 @@
   EXPECT_THAT(collection.size(), Eq(static_cast<size_t>(1)));
 
   EXPECT_THAT(collection.RemoveIfPresent("alice"),
-              Eq(absl::optional<size_t>(alice_index)));
+              Eq(std::optional<size_t>(alice_index)));
   EXPECT_THAT(collection.size(), Eq(static_cast<size_t>(0)));
 
   EXPECT_THAT(collection.AddIfAbsent("alice"), Eq(alice_index));
@@ -144,7 +144,7 @@
   EXPECT_THAT(collection.GetKnownSize(), Eq(static_cast<size_t>(1)));
 
   EXPECT_THAT(collection.RemoveIfPresent("alice"),
-              Eq(absl::optional<size_t>(alice_index)));
+              Eq(std::optional<size_t>(alice_index)));
   EXPECT_THAT(collection.GetKnownSize(), Eq(static_cast<size_t>(1)));
 }
 
diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc
index ccddd39..ac99b15 100644
--- a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc
+++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc
@@ -13,10 +13,10 @@
 #include <cstdint>
 #include <cstring>
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/video/i420_buffer.h"
 #include "api/video/video_frame.h"
 #include "modules/video_coding/include/video_error_codes.h"
@@ -156,8 +156,8 @@
 // method on `delegate_callback_`, as was called on `this` callback.
 int32_t QualityAnalyzingVideoDecoder::DecoderCallback::Decoded(
     VideoFrame& decodedImage) {
-  decoder_->OnFrameDecoded(&decodedImage, /*decode_time_ms=*/absl::nullopt,
-                           /*qp=*/absl::nullopt);
+  decoder_->OnFrameDecoded(&decodedImage, /*decode_time_ms=*/std::nullopt,
+                           /*qp=*/std::nullopt);
 
   MutexLock lock(&callback_mutex_);
   RTC_DCHECK(delegate_callback_);
@@ -167,7 +167,7 @@
 int32_t QualityAnalyzingVideoDecoder::DecoderCallback::Decoded(
     VideoFrame& decodedImage,
     int64_t decode_time_ms) {
-  decoder_->OnFrameDecoded(&decodedImage, decode_time_ms, /*qp=*/absl::nullopt);
+  decoder_->OnFrameDecoded(&decodedImage, decode_time_ms, /*qp=*/std::nullopt);
 
   MutexLock lock(&callback_mutex_);
   RTC_DCHECK(delegate_callback_);
@@ -176,8 +176,8 @@
 
 void QualityAnalyzingVideoDecoder::DecoderCallback::Decoded(
     VideoFrame& decodedImage,
-    absl::optional<int32_t> decode_time_ms,
-    absl::optional<uint8_t> qp) {
+    std::optional<int32_t> decode_time_ms,
+    std::optional<uint8_t> qp) {
   decoder_->OnFrameDecoded(&decodedImage, decode_time_ms, qp);
 
   MutexLock lock(&callback_mutex_);
@@ -197,7 +197,7 @@
           .build();
   MutexLock lock(&callback_mutex_);
   RTC_DCHECK(delegate_callback_);
-  delegate_callback_->Decoded(dummy_frame, absl::nullopt, absl::nullopt);
+  delegate_callback_->Decoded(dummy_frame, std::nullopt, std::nullopt);
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
@@ -212,9 +212,9 @@
 
 void QualityAnalyzingVideoDecoder::OnFrameDecoded(
     VideoFrame* frame,
-    absl::optional<int32_t> decode_time_ms,
-    absl::optional<uint8_t> qp) {
-  absl::optional<uint16_t> frame_id;
+    std::optional<int32_t> decode_time_ms,
+    std::optional<uint8_t> qp) {
+  std::optional<uint16_t> frame_id;
   std::string codec_name;
   {
     MutexLock lock(&mutex_);
diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h
index daa919d..d70b75f5 100644
--- a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h
+++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h
@@ -13,11 +13,11 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/test/video_quality_analyzer_interface.h"
 #include "api/video/encoded_image.h"
@@ -79,8 +79,8 @@
     int32_t Decoded(VideoFrame& decodedImage) override;
     int32_t Decoded(VideoFrame& decodedImage, int64_t decode_time_ms) override;
     void Decoded(VideoFrame& decodedImage,
-                 absl::optional<int32_t> decode_time_ms,
-                 absl::optional<uint8_t> qp) override;
+                 std::optional<int32_t> decode_time_ms,
+                 std::optional<uint8_t> qp) override;
 
     int32_t IrrelevantSimulcastStreamDecoded(uint16_t frame_id,
                                              uint32_t timestamp_ms);
@@ -97,8 +97,8 @@
   };
 
   void OnFrameDecoded(VideoFrame* frame,
-                      absl::optional<int32_t> decode_time_ms,
-                      absl::optional<uint8_t> qp);
+                      std::optional<int32_t> decode_time_ms,
+                      std::optional<uint8_t> qp);
 
   const std::string peer_name_;
   const std::string implementation_name_;
@@ -114,7 +114,7 @@
 
   // Name of the video codec type used. Ex: VP8, VP9, H264 etc.
   std::string codec_name_ RTC_GUARDED_BY(mutex_);
-  std::map<uint32_t, absl::optional<uint16_t>> timestamp_to_frame_id_
+  std::map<uint32_t, std::optional<uint16_t>> timestamp_to_frame_id_
       RTC_GUARDED_BY(mutex_);
   // Stores currently being decoded images by timestamp. Because
   // EncodedImageDataExtractor can create new copy on EncodedImage we need to
diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc
index 7ecfa70..b8790e9 100644
--- a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc
+++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc
@@ -85,7 +85,7 @@
   MutexLock lock(&mutex_);
   codec_settings_ = *codec_settings;
   mode_ = SimulcastMode::kNormal;
-  absl::optional<InterLayerPredMode> inter_layer_pred_mode;
+  std::optional<InterLayerPredMode> inter_layer_pred_mode;
   if (codec_settings->GetScalabilityMode().has_value()) {
     inter_layer_pred_mode = ScalabilityModeToInterLayerPredMode(
         *codec_settings->GetScalabilityMode());
@@ -399,7 +399,7 @@
 VideoEncoderFactory::CodecSupport
 QualityAnalyzingVideoEncoderFactory::QueryCodecSupport(
     const SdpVideoFormat& format,
-    absl::optional<std::string> scalability_mode) const {
+    std::optional<std::string> scalability_mode) const {
   return delegate_->QueryCodecSupport(format, scalability_mode);
 }
 
diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h
index 1fb6302..02159d7 100644
--- a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h
+++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h
@@ -52,7 +52,7 @@
                                      public EncodedImageCallback {
  public:
   using EmulatedSFUConfigMap =
-      std::map<std::string, absl::optional<EmulatedSFUConfig>>;
+      std::map<std::string, std::optional<EmulatedSFUConfig>>;
 
   QualityAnalyzingVideoEncoder(absl::string_view peer_name,
                                std::unique_ptr<VideoEncoder> delegate,
@@ -138,7 +138,7 @@
   const double bitrate_multiplier_;
   // Contains mapping from stream label to optional spatial index.
   // If we have stream label "Foo" and mapping contains
-  // 1. `absl::nullopt` means all streams are required
+  // 1. `std::nullopt` means all streams are required
   // 2. Concrete value means that particular simulcast/SVC stream have to be
   //    analyzed.
   EmulatedSFUConfigMap stream_to_sfu_config_;
@@ -176,7 +176,7 @@
   std::vector<SdpVideoFormat> GetSupportedFormats() const override;
   VideoEncoderFactory::CodecSupport QueryCodecSupport(
       const SdpVideoFormat& format,
-      absl::optional<std::string> scalability_mode) const override;
+      std::optional<std::string> scalability_mode) const override;
   std::unique_ptr<VideoEncoder> Create(const Environment& env,
                                        const SdpVideoFormat& format) override;
 
diff --git a/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.cc b/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.cc
index ccd2f03..3bc40a5 100644
--- a/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.cc
+++ b/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.cc
@@ -100,7 +100,7 @@
   }
 
   size_t prev_frames_size = 0;
-  absl::optional<uint16_t> id = absl::nullopt;
+  std::optional<uint16_t> id = std::nullopt;
   bool discard = true;
   std::vector<ExtractionInfo> extraction_infos;
   for (size_t frame_size : frame_sizes) {
diff --git a/test/pc/e2e/analyzer/video/video_dumping_test.cc b/test/pc/e2e/analyzer/video/video_dumping_test.cc
index 5dd4021..21f1b2c 100644
--- a/test/pc/e2e/analyzer/video/video_dumping_test.cc
+++ b/test/pc/e2e/analyzer/video/video_dumping_test.cc
@@ -12,10 +12,10 @@
 #include <stdio.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
 #include "api/video/i420_buffer.h"
 #include "api/video/video_frame.h"
diff --git a/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.h b/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.h
index d3d9763..cc31c48 100644
--- a/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.h
+++ b/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.h
@@ -64,7 +64,7 @@
   test::MetricsLogger* const metrics_logger_;
 
   std::string test_case_name_;
-  absl::optional<Timestamp> start_time_;
+  std::optional<Timestamp> start_time_;
 
   Mutex video_bwe_stats_lock_;
   // Map between a peer connection label (provided by the framework) and
diff --git a/test/pc/e2e/analyzer_helper.cc b/test/pc/e2e/analyzer_helper.cc
index 76cd9a7..0987f8c 100644
--- a/test/pc/e2e/analyzer_helper.cc
+++ b/test/pc/e2e/analyzer_helper.cc
@@ -24,7 +24,7 @@
     absl::string_view track_id,
     absl::string_view receiver_peer,
     absl::string_view stream_label,
-    absl::optional<std::string> sync_group) {
+    std::optional<std::string> sync_group) {
   RTC_DCHECK_RUN_ON(&signaling_sequence_checker_);
   track_to_stream_map_.insert(
       {std::string(track_id),
diff --git a/test/pc/e2e/analyzer_helper.h b/test/pc/e2e/analyzer_helper.h
index d0b47c4..008cb3b 100644
--- a/test/pc/e2e/analyzer_helper.h
+++ b/test/pc/e2e/analyzer_helper.h
@@ -12,10 +12,10 @@
 #define TEST_PC_E2E_ANALYZER_HELPER_H_
 
 #include <map>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/sequence_checker.h"
 #include "api/test/track_id_stream_info_map.h"
 #include "rtc_base/thread_annotations.h"
@@ -40,7 +40,7 @@
   void AddTrackToStreamMapping(absl::string_view track_id,
                                absl::string_view receiver_peer,
                                absl::string_view stream_label,
-                               absl::optional<std::string> sync_group);
+                               std::optional<std::string> sync_group);
   void AddTrackToStreamMapping(std::string track_id, std::string stream_label);
   void AddTrackToStreamMapping(std::string track_id,
                                std::string stream_label,
diff --git a/test/pc/e2e/cross_media_metrics_reporter.h b/test/pc/e2e/cross_media_metrics_reporter.h
index 2d51ebb..c031b06 100644
--- a/test/pc/e2e/cross_media_metrics_reporter.h
+++ b/test/pc/e2e/cross_media_metrics_reporter.h
@@ -12,10 +12,10 @@
 #define TEST_PC_E2E_CROSS_MEDIA_METRICS_REPORTER_H_
 
 #include <map>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/numerics/samples_stats_counter.h"
 #include "api/test/metrics/metrics_logger.h"
 #include "api/test/peerconnection_quality_test_fixture.h"
diff --git a/test/pc/e2e/media/test_video_capturer_video_track_source.h b/test/pc/e2e/media/test_video_capturer_video_track_source.h
index abcdc6c..cbfffd0 100644
--- a/test/pc/e2e/media/test_video_capturer_video_track_source.h
+++ b/test/pc/e2e/media/test_video_capturer_video_track_source.h
@@ -12,9 +12,9 @@
 #define TEST_PC_E2E_MEDIA_TEST_VIDEO_CAPTURER_VIDEO_TRACK_SOURCE_H_
 
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/sequence_checker.h"
 #include "api/test/video/test_video_track_source.h"
 #include "api/video/video_frame.h"
@@ -29,7 +29,7 @@
   TestVideoCapturerVideoTrackSource(
       std::unique_ptr<test::TestVideoCapturer> video_capturer,
       bool is_screencast,
-      absl::optional<std::string> stream_label = absl::nullopt)
+      std::optional<std::string> stream_label = std::nullopt)
       : TestVideoTrackSource(/*remote=*/false, std::move(stream_label)),
         video_capturer_(std::move(video_capturer)),
         is_screencast_(is_screencast) {
@@ -76,7 +76,7 @@
 
   void OnOutputFormatRequest(int width,
                              int height,
-                             const absl::optional<int>& max_fps) override {
+                             const std::optional<int>& max_fps) override {
     video_capturer_->OnOutputFormatRequest(width, height, max_fps);
   }
 
diff --git a/test/pc/e2e/peer_connection_quality_test.cc b/test/pc/e2e/peer_connection_quality_test.cc
index 6c58115..fac96e2 100644
--- a/test/pc/e2e/peer_connection_quality_test.cc
+++ b/test/pc/e2e/peer_connection_quality_test.cc
@@ -180,7 +180,7 @@
 void PeerConnectionE2EQualityTest::ExecuteAt(
     TimeDelta target_time_since_start,
     std::function<void(TimeDelta)> func) {
-  executor_->ScheduleActivity(target_time_since_start, absl::nullopt, func);
+  executor_->ScheduleActivity(target_time_since_start, std::nullopt, func);
 }
 
 void PeerConnectionE2EQualityTest::ExecuteEvery(
@@ -256,9 +256,9 @@
   // Audio streams are intercepted in AudioDeviceModule, so if it is required to
   // catch output of Alice's stream, Alice's output_dump_file_name should be
   // passed to Bob's TestPeer setup as audio output file name.
-  absl::optional<RemotePeerAudioConfig> alice_remote_audio_config =
+  std::optional<RemotePeerAudioConfig> alice_remote_audio_config =
       RemotePeerAudioConfig::Create(bob_configurer->params()->audio_config);
-  absl::optional<RemotePeerAudioConfig> bob_remote_audio_config =
+  std::optional<RemotePeerAudioConfig> bob_remote_audio_config =
       RemotePeerAudioConfig::Create(alice_configurer->params()->audio_config);
   // Copy Alice and Bob video configs, subscriptions and names to correctly pass
   // them into lambdas.
diff --git a/test/pc/e2e/peer_connection_quality_test_test.cc b/test/pc/e2e/peer_connection_quality_test_test.cc
index a63bc29..87e0c3f 100644
--- a/test/pc/e2e/peer_connection_quality_test_test.cc
+++ b/test/pc/e2e/peer_connection_quality_test_test.cc
@@ -40,7 +40,7 @@
 
 // Remove files and directories in a directory non-recursively.
 void CleanDir(absl::string_view dir, size_t expected_output_files_count) {
-  absl::optional<std::vector<std::string>> dir_content =
+  std::optional<std::vector<std::string>> dir_content =
       test::ReadDirectory(dir);
   if (expected_output_files_count == 0) {
     ASSERT_FALSE(dir_content.has_value()) << "Empty directory is expected";
diff --git a/test/pc/e2e/peer_params_preprocessor.cc b/test/pc/e2e/peer_params_preprocessor.cc
index 3647c01..7c820a0 100644
--- a/test/pc/e2e/peer_params_preprocessor.cc
+++ b/test/pc/e2e/peer_params_preprocessor.cc
@@ -52,7 +52,7 @@
       rtc::ArrayView<const absl::string_view> default_names = {})
       : prefix_(prefix), default_names_(default_names) {}
 
-  void MaybeSetName(absl::optional<std::string>& name) {
+  void MaybeSetName(std::optional<std::string>& name) {
     if (name.has_value()) {
       known_names_.insert(name.value());
     } else {
@@ -168,11 +168,11 @@
           if (!encoding_param.scalability_mode)
             continue;
 
-          absl::optional<ScalabilityMode> scalability_mode =
+          std::optional<ScalabilityMode> scalability_mode =
               ScalabilityModeFromString(*encoding_param.scalability_mode);
           RTC_CHECK(scalability_mode) << "Unknown scalability_mode requested";
 
-          absl::optional<ScalableVideoController::StreamLayersConfig>
+          std::optional<ScalableVideoController::StreamLayersConfig>
               stream_layers_config =
                   ScalabilityStructureConfig(*scalability_mode);
           is_svc |= stream_layers_config->num_spatial_layers > 1;
diff --git a/test/pc/e2e/sdp/sdp_changer.h b/test/pc/e2e/sdp/sdp_changer.h
index 6f68d03..018150c 100644
--- a/test/pc/e2e/sdp/sdp_changer.h
+++ b/test/pc/e2e/sdp/sdp_changer.h
@@ -12,11 +12,11 @@
 #define TEST_PC_E2E_SDP_SDP_CHANGER_H_
 
 #include <map>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/jsep.h"
 #include "api/rtp_parameters.h"
diff --git a/test/pc/e2e/stats_based_network_quality_metrics_reporter_test.cc b/test/pc/e2e/stats_based_network_quality_metrics_reporter_test.cc
index a4ed112..1a169dc 100644
--- a/test/pc/e2e/stats_based_network_quality_metrics_reporter_test.cc
+++ b/test/pc/e2e/stats_based_network_quality_metrics_reporter_test.cc
@@ -12,11 +12,11 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/test/create_network_emulation_manager.h"
 #include "api/test/create_peer_connection_quality_test_frame_generator.h"
@@ -65,14 +65,14 @@
   fixture.AddPeer(std::move(peer));
 }
 
-absl::optional<Metric> FindMeetricByName(absl::string_view name,
-                                         rtc::ArrayView<const Metric> metrics) {
+std::optional<Metric> FindMeetricByName(absl::string_view name,
+                                        rtc::ArrayView<const Metric> metrics) {
   for (const Metric& metric : metrics) {
     if (metric.name == name) {
       return metric;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 TEST(StatsBasedNetworkQualityMetricsReporterTest, DebugStatsAreCollected) {
@@ -128,20 +128,20 @@
   fixture.Run(RunParams(TimeDelta::Seconds(4)));
 
   std::vector<Metric> metrics = metrics_logger.GetCollectedMetrics();
-  absl::optional<Metric> uplink_packet_transport_time =
+  std::optional<Metric> uplink_packet_transport_time =
       FindMeetricByName("uplink_packet_transport_time", metrics);
   ASSERT_TRUE(uplink_packet_transport_time.has_value());
   ASSERT_FALSE(uplink_packet_transport_time->time_series.samples.empty());
-  absl::optional<Metric> uplink_size_to_packet_transport_time =
+  std::optional<Metric> uplink_size_to_packet_transport_time =
       FindMeetricByName("uplink_size_to_packet_transport_time", metrics);
   ASSERT_TRUE(uplink_size_to_packet_transport_time.has_value());
   ASSERT_FALSE(
       uplink_size_to_packet_transport_time->time_series.samples.empty());
-  absl::optional<Metric> downlink_packet_transport_time =
+  std::optional<Metric> downlink_packet_transport_time =
       FindMeetricByName("downlink_packet_transport_time", metrics);
   ASSERT_TRUE(downlink_packet_transport_time.has_value());
   ASSERT_FALSE(downlink_packet_transport_time->time_series.samples.empty());
-  absl::optional<Metric> downlink_size_to_packet_transport_time =
+  std::optional<Metric> downlink_size_to_packet_transport_time =
       FindMeetricByName("downlink_size_to_packet_transport_time", metrics);
   ASSERT_TRUE(downlink_size_to_packet_transport_time.has_value());
   ASSERT_FALSE(
diff --git a/test/pc/e2e/test_activities_executor.cc b/test/pc/e2e/test_activities_executor.cc
index 7bcf7dd..cad4f63 100644
--- a/test/pc/e2e/test_activities_executor.cc
+++ b/test/pc/e2e/test_activities_executor.cc
@@ -48,7 +48,7 @@
 
 void TestActivitiesExecutor::ScheduleActivity(
     TimeDelta initial_delay_since_start,
-    absl::optional<TimeDelta> interval,
+    std::optional<TimeDelta> interval,
     std::function<void(TimeDelta)> func) {
   RTC_CHECK(initial_delay_since_start.IsFinite() &&
             initial_delay_since_start >= TimeDelta::Zero());
@@ -112,7 +112,7 @@
 
 TestActivitiesExecutor::ScheduledActivity::ScheduledActivity(
     TimeDelta initial_delay_since_start,
-    absl::optional<TimeDelta> interval,
+    std::optional<TimeDelta> interval,
     std::function<void(TimeDelta)> func)
     : initial_delay_since_start(initial_delay_since_start),
       interval(interval),
diff --git a/test/pc/e2e/test_activities_executor.h b/test/pc/e2e/test_activities_executor.h
index 2469ac7..1d9d7ca 100644
--- a/test/pc/e2e/test_activities_executor.h
+++ b/test/pc/e2e/test_activities_executor.h
@@ -11,10 +11,10 @@
 #ifndef TEST_PC_E2E_TEST_ACTIVITIES_EXECUTOR_H_
 #define TEST_PC_E2E_TEST_ACTIVITIES_EXECUTOR_H_
 
+#include <optional>
 #include <queue>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
@@ -43,17 +43,17 @@
   // If test is started, then it will be executed immediately according to its
   // schedule.
   void ScheduleActivity(TimeDelta initial_delay_since_start,
-                        absl::optional<TimeDelta> interval,
+                        std::optional<TimeDelta> interval,
                         std::function<void(TimeDelta)> func);
 
  private:
   struct ScheduledActivity {
     ScheduledActivity(TimeDelta initial_delay_since_start,
-                      absl::optional<TimeDelta> interval,
+                      std::optional<TimeDelta> interval,
                       std::function<void(TimeDelta)> func);
 
     TimeDelta initial_delay_since_start;
-    absl::optional<TimeDelta> interval;
+    std::optional<TimeDelta> interval;
     std::function<void(TimeDelta)> func;
   };
 
diff --git a/test/pc/e2e/test_peer.h b/test/pc/e2e/test_peer.h
index 1ce2acb..0956e05 100644
--- a/test/pc/e2e/test_peer.h
+++ b/test/pc/e2e/test_peer.h
@@ -12,11 +12,11 @@
 #define TEST_PC_E2E_TEST_PEER_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/function_view.h"
 #include "api/scoped_refptr.h"
 #include "api/sequence_checker.h"
@@ -111,7 +111,7 @@
 
   rtc::scoped_refptr<DataChannelInterface> CreateDataChannel(
       const std::string& label,
-      const absl::optional<DataChannelInit>& config = absl::nullopt) {
+      const std::optional<DataChannelInit>& config = std::nullopt) {
     RTC_CHECK(wrapper_) << "TestPeer is already closed";
     return wrapper_->CreateDataChannel(label, config);
   }
diff --git a/test/pc/e2e/test_peer_factory.cc b/test/pc/e2e/test_peer_factory.cc
index a184c5d..f0ffe9f 100644
--- a/test/pc/e2e/test_peer_factory.cc
+++ b/test/pc/e2e/test_peer_factory.cc
@@ -60,7 +60,7 @@
 
 // Returns mapping from stream label to optional spatial index.
 // If we have stream label "Foo" and mapping contains
-// 1. `absl::nullopt` means all simulcast/SVC streams are required
+// 1. `std::nullopt` means all simulcast/SVC streams are required
 // 2. Concrete value means that particular simulcast/SVC stream have to be
 //    analyzed.
 EmulatedSFUConfigMap CalculateRequiredSpatialIndexPerStream(
@@ -80,7 +80,7 @@
 }
 
 std::unique_ptr<TestAudioDeviceModule::Renderer> CreateAudioRenderer(
-    const absl::optional<RemotePeerAudioConfig>& config) {
+    const std::optional<RemotePeerAudioConfig>& config) {
   if (!config) {
     // Return default renderer because we always require some renderer.
     return TestAudioDeviceModule::CreateDiscardRenderer(
@@ -95,7 +95,7 @@
 }
 
 std::unique_ptr<TestAudioDeviceModule::Capturer> CreateAudioCapturer(
-    const absl::optional<AudioConfig>& audio_config) {
+    const std::optional<AudioConfig>& audio_config) {
   if (!audio_config) {
     // If we have no audio config we still need to provide some audio device.
     // In such case use generated capturer. Despite of we provided audio here,
@@ -113,9 +113,9 @@
 }
 
 rtc::scoped_refptr<AudioDeviceModule> CreateAudioDeviceModule(
-    absl::optional<AudioConfig> audio_config,
-    absl::optional<RemotePeerAudioConfig> remote_audio_config,
-    absl::optional<EchoEmulationConfig> echo_emulation_config,
+    std::optional<AudioConfig> audio_config,
+    std::optional<RemotePeerAudioConfig> remote_audio_config,
+    std::optional<EchoEmulationConfig> echo_emulation_config,
     TaskQueueFactory* task_queue_factory) {
   std::unique_ptr<TestAudioDeviceModule::Renderer> renderer =
       CreateAudioRenderer(remote_audio_config);
@@ -259,10 +259,10 @@
 
 }  // namespace
 
-absl::optional<RemotePeerAudioConfig> RemotePeerAudioConfig::Create(
-    absl::optional<AudioConfig> config) {
+std::optional<RemotePeerAudioConfig> RemotePeerAudioConfig::Create(
+    std::optional<AudioConfig> config) {
   if (!config) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return RemotePeerAudioConfig(config.value());
 }
@@ -270,8 +270,8 @@
 std::unique_ptr<TestPeer> TestPeerFactory::CreateTestPeer(
     std::unique_ptr<PeerConfigurer> configurer,
     std::unique_ptr<MockPeerConnectionObserver> observer,
-    absl::optional<RemotePeerAudioConfig> remote_audio_config,
-    absl::optional<EchoEmulationConfig> echo_emulation_config) {
+    std::optional<RemotePeerAudioConfig> remote_audio_config,
+    std::optional<EchoEmulationConfig> echo_emulation_config) {
   std::unique_ptr<InjectableComponents> components =
       configurer->ReleaseComponents();
   std::unique_ptr<Params> params = configurer->ReleaseParams();
diff --git a/test/pc/e2e/test_peer_factory.h b/test/pc/e2e/test_peer_factory.h
index cc61b04..34462c1 100644
--- a/test/pc/e2e/test_peer_factory.h
+++ b/test/pc/e2e/test_peer_factory.h
@@ -35,11 +35,11 @@
       : sampling_frequency_in_hz(config.sampling_frequency_in_hz),
         output_file_name(config.output_dump_file_name) {}
 
-  static absl::optional<RemotePeerAudioConfig> Create(
-      absl::optional<AudioConfig> config);
+  static std::optional<RemotePeerAudioConfig> Create(
+      std::optional<AudioConfig> config);
 
   int sampling_frequency_in_hz;
-  absl::optional<std::string> output_file_name;
+  std::optional<std::string> output_file_name;
 };
 
 class TestPeerFactory {
@@ -68,8 +68,8 @@
   std::unique_ptr<TestPeer> CreateTestPeer(
       std::unique_ptr<PeerConfigurer> configurer,
       std::unique_ptr<MockPeerConnectionObserver> observer,
-      absl::optional<RemotePeerAudioConfig> remote_audio_config,
-      absl::optional<EchoEmulationConfig> echo_emulation_config);
+      std::optional<RemotePeerAudioConfig> remote_audio_config,
+      std::optional<EchoEmulationConfig> echo_emulation_config);
 
  private:
   rtc::Thread* signaling_thread_;
diff --git a/test/pc/sctp/fake_sctp_transport.h b/test/pc/sctp/fake_sctp_transport.h
index 8aacd3b..b5d0866 100644
--- a/test/pc/sctp/fake_sctp_transport.h
+++ b/test/pc/sctp/fake_sctp_transport.h
@@ -45,11 +45,11 @@
   void set_debug_name_for_testing(const char* debug_name) override {}
 
   int max_message_size() const override { return max_message_size_; }
-  absl::optional<int> max_outbound_streams() const override {
-    return absl::nullopt;
+  std::optional<int> max_outbound_streams() const override {
+    return std::nullopt;
   }
-  absl::optional<int> max_inbound_streams() const override {
-    return absl::nullopt;
+  std::optional<int> max_inbound_streams() const override {
+    return std::nullopt;
   }
   size_t buffered_amount(int sid) const override { return 0; }
   size_t buffered_amount_low_threshold(int sid) const override { return 0; }
@@ -64,8 +64,8 @@
   }
 
  private:
-  absl::optional<int> local_port_;
-  absl::optional<int> remote_port_;
+  std::optional<int> local_port_;
+  std::optional<int> remote_port_;
   int max_message_size_;
 };
 
diff --git a/test/peer_scenario/peer_scenario_client.h b/test/peer_scenario/peer_scenario_client.h
index cb025e9..729703a 100644
--- a/test/peer_scenario/peer_scenario_client.h
+++ b/test/peer_scenario/peer_scenario_client.h
@@ -79,7 +79,7 @@
       struct PulsedNoise {
         double amplitude = 0.1;
       };
-      absl::optional<PulsedNoise> pulsed_noise = PulsedNoise();
+      std::optional<PulsedNoise> pulsed_noise = PulsedNoise();
     } audio;
     struct Video {
       bool use_fake_codecs = false;
diff --git a/test/peer_scenario/tests/unsignaled_stream_test.cc b/test/peer_scenario/tests/unsignaled_stream_test.cc
index d7565c9..befd116 100644
--- a/test/peer_scenario/tests/unsignaled_stream_test.cc
+++ b/test/peer_scenario/tests/unsignaled_stream_test.cc
@@ -143,7 +143,7 @@
 
   uint32_t first_ssrc = 0;
   uint32_t second_ssrc = 0;
-  absl::optional<int> mid_header_extension_id = absl::nullopt;
+  std::optional<int> mid_header_extension_id = std::nullopt;
 
   signaling.NegotiateSdp(
       /* munge_sdp = */
diff --git a/test/rtp_file_writer.cc b/test/rtp_file_writer.cc
index 22f664a..f992756 100644
--- a/test/rtp_file_writer.cc
+++ b/test/rtp_file_writer.cc
@@ -13,9 +13,9 @@
 #include <stdint.h>
 #include <stdio.h>
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
@@ -92,7 +92,7 @@
   }
 
   FILE* file_;
-  absl::optional<uint32_t> first_packet_time_;
+  std::optional<uint32_t> first_packet_time_;
 };
 
 RtpFileWriter* RtpFileWriter::Create(FileFormat format,
diff --git a/test/scenario/BUILD.gn b/test/scenario/BUILD.gn
index 672cd91..8f9234a 100644
--- a/test/scenario/BUILD.gn
+++ b/test/scenario/BUILD.gn
@@ -157,7 +157,6 @@
       "//third_party/abseil-cpp/absl/memory",
       "//third_party/abseil-cpp/absl/strings",
       "//third_party/abseil-cpp/absl/strings:string_view",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
     if (is_android) {
       deps += [ "../../modules/video_coding:android_codec_factory_helper" ]
diff --git a/test/scenario/audio_stream.cc b/test/scenario/audio_stream.cc
index 232f738..64b6406 100644
--- a/test/scenario/audio_stream.cc
+++ b/test/scenario/audio_stream.cc
@@ -29,7 +29,7 @@
   kAbsSendTimeExtensionId
 };
 
-absl::optional<std::string> CreateAdaptationString(
+std::optional<std::string> CreateAdaptationString(
     AudioStreamConfig::NetworkAdaptation config) {
 #if WEBRTC_ENABLE_PROTOBUF
 
@@ -61,7 +61,7 @@
   RTC_LOG(LS_ERROR) << "audio_network_adaptation is enabled"
                        " but WEBRTC_ENABLE_PROTOBUF is false.\n"
                        "Ignoring settings.";
-  return absl::nullopt;
+  return std::nullopt;
 #endif  // WEBRTC_ENABLE_PROTOBUF
 }
 }  // namespace
diff --git a/test/scenario/scenario_config.h b/test/scenario/scenario_config.h
index 50845cd..b47a220 100644
--- a/test/scenario/scenario_config.h
+++ b/test/scenario/scenario_config.h
@@ -12,9 +12,9 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/fec_controller.h"
 #include "api/rtp_parameters.h"
 #include "api/test/frame_generator_interface.h"
@@ -90,8 +90,8 @@
       struct Images {
         struct Crop {
           TimeDelta scroll_duration = TimeDelta::Seconds(0);
-          absl::optional<int> width;
-          absl::optional<int> height;
+          std::optional<int> width;
+          std::optional<int> height;
         } crop;
         int width = 1850;
         int height = 1110;
@@ -132,11 +132,11 @@
 
     using Codec = VideoCodecType;
     Codec codec = Codec::kVideoCodecGeneric;
-    absl::optional<DataRate> max_data_rate;
-    absl::optional<DataRate> min_data_rate;
-    absl::optional<int> max_framerate;
+    std::optional<DataRate> max_data_rate;
+    std::optional<DataRate> min_data_rate;
+    std::optional<int> max_framerate;
     // Counted in frame count.
-    absl::optional<int> key_frame_interval = 3000;
+    std::optional<int> key_frame_interval = 3000;
     bool frame_dropping = true;
     struct SingleLayer {
       bool denoising = true;
@@ -199,8 +199,8 @@
     bool enable_dtx = false;
     DataRate fixed_rate = DataRate::KilobitsPerSec(32);
     // Overrides fixed rate.
-    absl::optional<DataRate> min_rate;
-    absl::optional<DataRate> max_rate;
+    std::optional<DataRate> min_rate;
+    std::optional<DataRate> max_rate;
     TimeDelta initial_frame_length = TimeDelta::Millis(20);
   } encoder;
   struct Stream {
@@ -221,7 +221,7 @@
   TimeDelta delay = TimeDelta::Zero();
   TimeDelta delay_std_dev = TimeDelta::Zero();
   double loss_rate = 0;
-  absl::optional<int> packet_queue_length_limit;
+  std::optional<int> packet_queue_length_limit;
   DataSize packet_overhead = DataSize::Zero();
 };
 }  // namespace test
diff --git a/test/scenario/stats_collection.h b/test/scenario/stats_collection.h
index 1f5d8da..fcf8f71 100644
--- a/test/scenario/stats_collection.h
+++ b/test/scenario/stats_collection.h
@@ -12,8 +12,8 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "call/call.h"
 #include "rtc_base/thread.h"
 #include "test/logging/log_writer.h"
@@ -59,7 +59,7 @@
   const VideoQualityAnalyzerConfig config_;
   std::map<int, VideoLayerAnalyzer> layer_analyzers_;
   const std::unique_ptr<RtcEventLogOutput> writer_;
-  absl::optional<VideoQualityStats> cached_;
+  std::optional<VideoQualityStats> cached_;
 };
 
 class CallStatsCollector {
diff --git a/test/scenario/video_stream.cc b/test/scenario/video_stream.cc
index eb403f9..db4918b 100644
--- a/test/scenario/video_stream.cc
+++ b/test/scenario/video_stream.cc
@@ -263,7 +263,7 @@
     case Capture::kGenerator:
       return CreateSquareFrameGenerator(
           source.generator.width, source.generator.height,
-          source.generator.pixel_format, /*num_squares*/ absl::nullopt);
+          source.generator.pixel_format, /*num_squares*/ std::nullopt);
     case Capture::kVideoFile:
       RTC_CHECK(source.video_file.width && source.video_file.height);
       return CreateFromYuvFileFrameGenerator(
diff --git a/test/test_main_lib.cc b/test/test_main_lib.cc
index 486913b..08f9b4e 100644
--- a/test/test_main_lib.cc
+++ b/test/test_main_lib.cc
@@ -15,6 +15,7 @@
 #include <fstream>
 #include <ios>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -22,7 +23,6 @@
 #include "absl/memory/memory.h"
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/test/metrics/chrome_perf_dashboard_metrics_exporter.h"
 #include "api/test/metrics/global_metrics_logger_and_exporter.h"
 #include "api/test/metrics/metrics_exporter.h"
@@ -167,11 +167,11 @@
       StartTracingCapture(trace_event_path);
     }
 
-    absl::optional<std::vector<std::string>> metrics_to_plot =
+    std::optional<std::vector<std::string>> metrics_to_plot =
         absl::GetFlag(FLAGS_plot);
 
     if (metrics_to_plot->empty()) {
-      metrics_to_plot = absl::nullopt;
+      metrics_to_plot = std::nullopt;
     } else {
       if (metrics_to_plot->size() == 1 &&
           (*metrics_to_plot)[0] == kPlotAllMetrics) {
diff --git a/test/test_video_capturer.cc b/test/test_video_capturer.cc
index 385af12..de4e175 100644
--- a/test/test_video_capturer.cc
+++ b/test/test_video_capturer.cc
@@ -25,10 +25,10 @@
 void TestVideoCapturer::OnOutputFormatRequest(
     int width,
     int height,
-    const absl::optional<int>& max_fps) {
-  absl::optional<std::pair<int, int>> target_aspect_ratio =
+    const std::optional<int>& max_fps) {
+  std::optional<std::pair<int, int>> target_aspect_ratio =
       std::make_pair(width, height);
-  absl::optional<int> max_pixel_count = width * height;
+  std::optional<int> max_pixel_count = width * height;
   video_adapter_.OnOutputFormatRequest(target_aspect_ratio, max_pixel_count,
                                        max_fps);
 }
diff --git a/test/test_video_capturer.h b/test/test_video_capturer.h
index 49660d8..4ac17db 100644
--- a/test/test_video_capturer.h
+++ b/test/test_video_capturer.h
@@ -47,7 +47,7 @@
   }
   void OnOutputFormatRequest(int width,
                              int height,
-                             const absl::optional<int>& max_fps);
+                             const std::optional<int>& max_fps);
 
   // Starts or resumes video capturing. Can be called multiple times during
   // lifetime of this object.
diff --git a/test/testsupport/copy_to_file_audio_capturer.h b/test/testsupport/copy_to_file_audio_capturer.h
index a410bee..9170cc1 100644
--- a/test/testsupport/copy_to_file_audio_capturer.h
+++ b/test/testsupport/copy_to_file_audio_capturer.h
@@ -12,9 +12,9 @@
 #define TEST_TESTSUPPORT_COPY_TO_FILE_AUDIO_CAPTURER_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "common_audio/wav_file.h"
 #include "modules/audio_device/include/test_audio_device.h"
diff --git a/test/testsupport/file_utils.cc b/test/testsupport/file_utils.cc
index f796361..9451c20 100644
--- a/test/testsupport/file_utils.cc
+++ b/test/testsupport/file_utils.cc
@@ -138,9 +138,9 @@
   return filename;
 }
 
-absl::optional<std::vector<std::string>> ReadDirectory(absl::string_view path) {
+std::optional<std::vector<std::string>> ReadDirectory(absl::string_view path) {
   if (path.length() == 0)
-    return absl::optional<std::vector<std::string>>();
+    return std::optional<std::vector<std::string>>();
 
   std::string path_str(path);
 
@@ -153,7 +153,7 @@
   WIN32_FIND_DATAW data;
   HANDLE handle = ::FindFirstFileW(rtc::ToUtf16(path_str + '*').c_str(), &data);
   if (handle == INVALID_HANDLE_VALUE)
-    return absl::optional<std::vector<std::string>>();
+    return std::optional<std::vector<std::string>>();
 
   // Populate output.
   std::vector<std::string> found_entries;
@@ -174,7 +174,7 @@
   // Init.
   DIR* dir = ::opendir(path_str.c_str());
   if (dir == nullptr)
-    return absl::optional<std::vector<std::string>>();
+    return std::optional<std::vector<std::string>>();
 
   // Populate output.
   std::vector<std::string> found_entries;
@@ -188,7 +188,7 @@
   closedir(dir);
 #endif
 
-  return absl::optional<std::vector<std::string>>(std::move(found_entries));
+  return std::optional<std::vector<std::string>>(std::move(found_entries));
 }
 
 bool CreateDir(absl::string_view directory_name) {
diff --git a/test/testsupport/file_utils.h b/test/testsupport/file_utils.h
index 120c6cb..22d3d11 100644
--- a/test/testsupport/file_utils.h
+++ b/test/testsupport/file_utils.h
@@ -13,12 +13,12 @@
 #ifndef TEST_TESTSUPPORT_FILE_UTILS_H_
 #define TEST_TESTSUPPORT_FILE_UTILS_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/base/attributes.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 
 namespace webrtc {
 namespace test {
@@ -80,7 +80,7 @@
 // of strings with one element for each found file or directory. Each element is
 // a path created by prepending `dir` to the file/directory name. "." and ".."
 // are never added in the returned vector.
-absl::optional<std::vector<std::string>> ReadDirectory(absl::string_view path);
+std::optional<std::vector<std::string>> ReadDirectory(absl::string_view path);
 
 // Creates a directory if it not already exists.
 // Returns true if successful. Will print an error message to stderr and return
diff --git a/test/testsupport/file_utils_override.cc b/test/testsupport/file_utils_override.cc
index 0140e6c..fe8cdd6 100644
--- a/test/testsupport/file_utils_override.cc
+++ b/test/testsupport/file_utils_override.cc
@@ -40,8 +40,9 @@
 #include "test/testsupport/mac_file_utils.h"
 #endif
 
+#include <optional>
+
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "rtc_base/arraysize.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/string_utils.h"
@@ -80,7 +81,7 @@
 
 // Finds the WebRTC src dir.
 // The returned path always ends with a path separator.
-absl::optional<std::string> ProjectRootPath() {
+std::optional<std::string> ProjectRootPath() {
 #if defined(WEBRTC_ANDROID)
   return std::string(kAndroidChromiumTestsRoot);
 #elif defined WEBRTC_IOS
@@ -102,7 +103,7 @@
   ssize_t count = ::readlink("/proc/self/exe", buf, arraysize(buf));
   if (count <= 0) {
     RTC_DCHECK_NOTREACHED() << "Unable to resolve /proc/self/exe.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   // On POSIX, tests execute in out/Whatever, so src is two levels up.
   std::string exe_dir = DirName(absl::string_view(buf, count));
@@ -112,7 +113,7 @@
   wchar_t buf[MAX_PATH];
   buf[0] = 0;
   if (GetModuleFileNameW(NULL, buf, MAX_PATH) == 0)
-    return absl::nullopt;
+    return std::nullopt;
 
   std::string exe_path = rtc::ToUtf8(std::wstring(buf));
   std::string exe_dir = DirName(exe_path);
@@ -128,7 +129,7 @@
 #elif defined(WEBRTC_FUCHSIA)
   return std::string(kFuchsiaTempWritableDir);
 #else
-  absl::optional<std::string> path_opt = ProjectRootPath();
+  std::optional<std::string> path_opt = ProjectRootPath();
   RTC_DCHECK(path_opt);
   std::string path = *path_opt + "out";
   if (!CreateDir(path)) {
@@ -156,7 +157,7 @@
 #if defined(WEBRTC_IOS)
   return IOSResourcePath(name, extension);
 #else
-  absl::optional<std::string> path_opt = ProjectRootPath();
+  std::optional<std::string> path_opt = ProjectRootPath();
   RTC_DCHECK(path_opt);
   rtc::StringBuilder os(*path_opt);
   os << kResourcesDirName << kPathDelimiter << name << "." << extension;
diff --git a/test/testsupport/file_utils_unittest.cc b/test/testsupport/file_utils_unittest.cc
index 005e12c..fff6563 100644
--- a/test/testsupport/file_utils_unittest.cc
+++ b/test/testsupport/file_utils_unittest.cc
@@ -14,10 +14,10 @@
 
 #include <algorithm>
 #include <fstream>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/crypto_random.h"
 #include "test/gmock.h"
@@ -45,7 +45,7 @@
 void CleanDir(absl::string_view dir, size_t* num_deleted_entries) {
   RTC_DCHECK(num_deleted_entries);
   *num_deleted_entries = 0;
-  absl::optional<std::vector<std::string>> dir_content = ReadDirectory(dir);
+  std::optional<std::vector<std::string>> dir_content = ReadDirectory(dir);
   EXPECT_TRUE(dir_content);
   for (const auto& entry : *dir_content) {
     if (DirExists(entry)) {
@@ -271,7 +271,7 @@
   EXPECT_TRUE(DirExists(temp_subdir));
 
   // Checks.
-  absl::optional<std::vector<std::string>> dir_content =
+  std::optional<std::vector<std::string>> dir_content =
       ReadDirectory(temp_directory);
   EXPECT_TRUE(dir_content);
   EXPECT_EQ(2u, dir_content->size());
diff --git a/test/testsupport/fixed_fps_video_frame_writer_adapter.cc b/test/testsupport/fixed_fps_video_frame_writer_adapter.cc
index 531dade..4b90d21 100644
--- a/test/testsupport/fixed_fps_video_frame_writer_adapter.cc
+++ b/test/testsupport/fixed_fps_video_frame_writer_adapter.cc
@@ -11,9 +11,9 @@
 #include "test/testsupport/fixed_fps_video_frame_writer_adapter.h"
 
 #include <cmath>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/units/time_delta.h"
 #include "api/video/video_sink_interface.h"
 #include "rtc_base/checks.h"
diff --git a/test/testsupport/fixed_fps_video_frame_writer_adapter.h b/test/testsupport/fixed_fps_video_frame_writer_adapter.h
index d4d95e9..6d966bf 100644
--- a/test/testsupport/fixed_fps_video_frame_writer_adapter.h
+++ b/test/testsupport/fixed_fps_video_frame_writer_adapter.h
@@ -12,8 +12,8 @@
 #define TEST_TESTSUPPORT_FIXED_FPS_VIDEO_FRAME_WRITER_ADAPTER_H_
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/test/video/video_frame_writer.h"
 #include "api/video/video_sink_interface.h"
 #include "system_wrappers/include/clock.h"
@@ -78,7 +78,7 @@
 
   // Expected time slot for the last frame.
   Timestamp last_frame_time_ = Timestamp::MinusInfinity();
-  absl::optional<VideoFrame> last_frame_ = absl::nullopt;
+  std::optional<VideoFrame> last_frame_ = std::nullopt;
 };
 
 }  // namespace test
diff --git a/test/testsupport/frame_reader.h b/test/testsupport/frame_reader.h
index 7856476..29f4773 100644
--- a/test/testsupport/frame_reader.h
+++ b/test/testsupport/frame_reader.h
@@ -13,9 +13,9 @@
 
 #include <stdio.h>
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
 #include "api/video/resolution.h"
 
@@ -104,7 +104,7 @@
     int Skip(Ratio framerate_scale);
 
    private:
-    absl::optional<int> ticks_;
+    std::optional<int> ticks_;
   };
 
   const std::string filepath_;
diff --git a/test/testsupport/ivf_video_frame_generator.cc b/test/testsupport/ivf_video_frame_generator.cc
index 42b9c19..3410205 100644
--- a/test/testsupport/ivf_video_frame_generator.cc
+++ b/test/testsupport/ivf_video_frame_generator.cc
@@ -83,7 +83,7 @@
   video_decoder_.reset();
   {
     MutexLock frame_lock(&frame_decode_lock_);
-    next_frame_ = absl::nullopt;
+    next_frame_ = std::nullopt;
     // Set event in case another thread is waiting on it.
     next_frame_decoded_.Set();
   }
@@ -96,7 +96,7 @@
   if (!file_reader_->HasMoreFrames()) {
     file_reader_->Reset();
   }
-  absl::optional<EncodedImage> image = file_reader_->NextFrame();
+  std::optional<EncodedImage> image = file_reader_->NextFrame();
   RTC_CHECK(image);
   // Last parameter is undocumented and there is no usage of it found.
   RTC_CHECK_EQ(WEBRTC_VIDEO_CODEC_OK,
@@ -127,7 +127,7 @@
   if (!file_reader_->HasMoreFrames()) {
     file_reader_->Reset();
   }
-  absl::optional<EncodedImage> image = file_reader_->NextFrame();
+  std::optional<EncodedImage> image = file_reader_->NextFrame();
   RTC_CHECK(image);
   // Last parameter is undocumented and there is no usage of it found.
   // Frame has to be decoded in case it is a key frame.
@@ -159,8 +159,8 @@
 }
 void IvfVideoFrameGenerator::DecodedCallback::Decoded(
     VideoFrame& decoded_image,
-    absl::optional<int32_t> decode_time_ms,
-    absl::optional<uint8_t> qp) {
+    std::optional<int32_t> decode_time_ms,
+    std::optional<uint8_t> qp) {
   reader_->OnFrameDecoded(decoded_image);
 }
 
diff --git a/test/testsupport/ivf_video_frame_generator.h b/test/testsupport/ivf_video_frame_generator.h
index 41cf2d9..b91037e 100644
--- a/test/testsupport/ivf_video_frame_generator.h
+++ b/test/testsupport/ivf_video_frame_generator.h
@@ -12,10 +12,10 @@
 #define TEST_TESTSUPPORT_IVF_VIDEO_FRAME_GENERATOR_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/sequence_checker.h"
 #include "api/test/frame_generator_interface.h"
@@ -40,7 +40,7 @@
   void ChangeResolution(size_t width, size_t height) override;
   Resolution GetResolution() const override;
 
-  absl::optional<int> fps() const override { return absl::nullopt; }
+  std::optional<int> fps() const override { return std::nullopt; }
 
  private:
   class DecodedCallback : public DecodedImageCallback {
@@ -51,8 +51,8 @@
     int32_t Decoded(VideoFrame& decoded_image) override;
     int32_t Decoded(VideoFrame& decoded_image, int64_t decode_time_ms) override;
     void Decoded(VideoFrame& decoded_image,
-                 absl::optional<int32_t> decode_time_ms,
-                 absl::optional<uint8_t> qp) override;
+                 std::optional<int32_t> decode_time_ms,
+                 std::optional<uint8_t> qp) override;
 
    private:
     IvfVideoFrameGenerator* const reader_;
@@ -82,7 +82,7 @@
   Mutex frame_decode_lock_;
 
   rtc::Event next_frame_decoded_;
-  absl::optional<VideoFrame> next_frame_ RTC_GUARDED_BY(frame_decode_lock_);
+  std::optional<VideoFrame> next_frame_ RTC_GUARDED_BY(frame_decode_lock_);
 };
 
 }  // namespace test
diff --git a/test/testsupport/ivf_video_frame_generator_unittest.cc b/test/testsupport/ivf_video_frame_generator_unittest.cc
index f550890..0c83a93 100644
--- a/test/testsupport/ivf_video_frame_generator_unittest.cc
+++ b/test/testsupport/ivf_video_frame_generator_unittest.cc
@@ -11,9 +11,9 @@
 #include "test/testsupport/ivf_video_frame_generator.h"
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
 #include "api/test/create_frame_generator.h"
@@ -118,7 +118,7 @@
     std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
         test::CreateSquareFrameGenerator(
             kWidth, kHeight, test::FrameGeneratorInterface::OutputType::kI420,
-            absl::nullopt);
+            std::nullopt);
 
     VideoCodec codec_settings;
     webrtc::test::CodecSettings(video_codec_type, &codec_settings);
@@ -170,7 +170,7 @@
 TEST_F(IvfVideoFrameGeneratorTest, DoesNotKnowFps) {
   CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, CreateVp8Encoder(env_));
   IvfVideoFrameGenerator generator(env_, file_name_);
-  EXPECT_EQ(generator.fps(), absl::nullopt);
+  EXPECT_EQ(generator.fps(), std::nullopt);
 }
 
 TEST_F(IvfVideoFrameGeneratorTest, Vp8) {
diff --git a/test/testsupport/y4m_frame_generator.h b/test/testsupport/y4m_frame_generator.h
index 16d8485..dfffb4a 100644
--- a/test/testsupport/y4m_frame_generator.h
+++ b/test/testsupport/y4m_frame_generator.h
@@ -13,10 +13,10 @@
 
 #include <cstddef>
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 #include "api/test/frame_generator_interface.h"
 #include "rtc_base/checks.h"
 #include "test/testsupport/frame_reader.h"
@@ -51,7 +51,7 @@
 
   Resolution GetResolution() const override;
 
-  absl::optional<int> fps() const override { return fps_; }
+  std::optional<int> fps() const override { return fps_; }
 
  private:
   YuvFrameReaderImpl::RepeatMode ToYuvFrameReaderRepeatMode(
diff --git a/test/video_codec_tester.cc b/test/video_codec_tester.cc
index a51a532..2782a66 100644
--- a/test/video_codec_tester.cc
+++ b/test/video_codec_tester.cc
@@ -162,7 +162,7 @@
   // scaling. This value increases by the source frame duration each time a
   // frame is read from the source, and decreases by the output frame duration
   // each time an output frame is delivered.
-  absl::optional<TimeDelta> time_delta_;
+  std::optional<TimeDelta> time_delta_;
 };
 
 // Pacer calculates delay necessary to keep frame encode or decode call spaced
@@ -203,8 +203,8 @@
   }
 
   PacingSettings settings_;
-  absl::optional<Timestamp> prev_timestamp_;
-  absl::optional<Timestamp> prev_scheduled_;
+  std::optional<Timestamp> prev_timestamp_;
+  std::optional<Timestamp> prev_scheduled_;
   TimeDelta delay_;
 };
 
@@ -361,7 +361,7 @@
   }
 
  private:
-  absl::optional<VideoCodecStats::Frame> prev_frame_;
+  std::optional<VideoCodecStats::Frame> prev_frame_;
   double level_bits_;
 };
 
@@ -457,7 +457,7 @@
 
   void FinishDecode(const VideoFrame& decoded_frame,
                     int spatial_idx,
-                    absl::optional<VideoFrame> ref_frame = absl::nullopt) {
+                    std::optional<VideoFrame> ref_frame = std::nullopt) {
     int64_t decode_finished_us = rtc::TimeMicros();
     task_queue_.PostTask([this, timestamp_rtp = decoded_frame.rtp_timestamp(),
                           spatial_idx, width = decoded_frame.width(),
@@ -759,7 +759,7 @@
   }
 
   DataRate GetTargetBitrate(const EncodingSettings& encoding_settings,
-                            absl::optional<LayerId> layer_id) const {
+                            std::optional<LayerId> layer_id) const {
     int base_spatial_idx;
     if (layer_id.has_value()) {
       bool is_svc =
@@ -790,7 +790,7 @@
   }
 
   Frequency GetTargetFramerate(const EncodingSettings& encoding_settings,
-                               absl::optional<LayerId> layer_id) const {
+                               std::optional<LayerId> layer_id) const {
     if (layer_id.has_value()) {
       auto layer_settings = encoding_settings.layers_settings.find(
           {.spatial_idx = layer_id->spatial_idx,
@@ -857,7 +857,7 @@
   }
 
   void Decode(const EncodedImage& encoded_frame,
-              absl::optional<VideoFrame> ref_frame = absl::nullopt) {
+              std::optional<VideoFrame> ref_frame = std::nullopt) {
     int spatial_idx = encoded_frame.SpatialIndex().value_or(
         encoded_frame.SimulcastIndex().value_or(0));
     {
@@ -900,7 +900,7 @@
  private:
   int Decoded(VideoFrame& decoded_frame) override {
     int spatial_idx;
-    absl::optional<VideoFrame> ref_frame;
+    std::optional<VideoFrame> ref_frame;
     {
       MutexLock lock(&mutex_);
       spatial_idx = *spatial_idx_;
@@ -930,8 +930,8 @@
   LimitedTaskQueue task_queue_;
   std::unique_ptr<TesterIvfWriter> ivf_writer_;
   std::unique_ptr<TesterY4mWriter> y4m_writer_;
-  absl::optional<VideoCodecType> codec_type_;
-  absl::optional<int> spatial_idx_ RTC_GUARDED_BY(mutex_);
+  std::optional<VideoCodecType> codec_type_;
+  std::optional<int> spatial_idx_ RTC_GUARDED_BY(mutex_);
   std::map<uint32_t, VideoFrame> ref_frames_ RTC_GUARDED_BY(mutex_);
   Mutex mutex_;
 };
@@ -1260,7 +1260,7 @@
   std::unique_ptr<VideoEncoder> encoder_;
   VideoCodecAnalyzer* const analyzer_;
   Pacer pacer_;
-  absl::optional<EncodingSettings> last_encoding_settings_;
+  std::optional<EncodingSettings> last_encoding_settings_;
   std::unique_ptr<VideoBitrateAllocator> bitrate_allocator_;
   LimitedTaskQueue task_queue_;
   std::unique_ptr<TesterY4mWriter> y4m_writer_;
@@ -1268,7 +1268,7 @@
   std::map<uint32_t, int> sidx_ RTC_GUARDED_BY(mutex_);
   std::map<uint32_t, EncodeCallback> callbacks_ RTC_GUARDED_BY(mutex_);
   VideoCodecType codec_type_;
-  absl::optional<Superframe> last_superframe_;
+  std::optional<Superframe> last_superframe_;
   Mutex mutex_;
 };
 
diff --git a/test/video_codec_tester.h b/test/video_codec_tester.h
index 3789f56..fcec47e 100644
--- a/test/video_codec_tester.h
+++ b/test/video_codec_tester.h
@@ -14,10 +14,10 @@
 #include <limits>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/numerics/samples_stats_counter.h"
 #include "api/test/metrics/metric.h"
@@ -68,7 +68,7 @@
     struct Filter {
       uint32_t min_timestamp_rtp = std::numeric_limits<uint32_t>::min();
       uint32_t max_timestamp_rtp = std::numeric_limits<uint32_t>::max();
-      absl::optional<LayerId> layer_id;
+      std::optional<LayerId> layer_id;
     };
 
     struct Frame {
@@ -80,20 +80,20 @@
       int height = 0;
       DataSize frame_size = DataSize::Zero();
       bool keyframe = false;
-      absl::optional<int> qp;
+      std::optional<int> qp;
       Timestamp encode_start = Timestamp::Zero();
       TimeDelta encode_time = TimeDelta::Zero();
       Timestamp decode_start = Timestamp::Zero();
       TimeDelta decode_time = TimeDelta::Zero();
-      absl::optional<DataRate> target_bitrate;
-      absl::optional<Frequency> target_framerate;
+      std::optional<DataRate> target_bitrate;
+      std::optional<Frequency> target_framerate;
 
       struct Psnr {
         double y = 0.0;
         double u = 0.0;
         double v = 0.0;
       };
-      absl::optional<Psnr> psnr;
+      std::optional<Psnr> psnr;
     };
 
     struct Stream {
@@ -166,14 +166,14 @@
 
   struct DecoderSettings {
     PacingSettings pacing_settings;
-    absl::optional<std::string> decoder_input_base_path;
-    absl::optional<std::string> decoder_output_base_path;
+    std::optional<std::string> decoder_input_base_path;
+    std::optional<std::string> decoder_output_base_path;
   };
 
   struct EncoderSettings {
     PacingSettings pacing_settings;
-    absl::optional<std::string> encoder_input_base_path;
-    absl::optional<std::string> encoder_output_base_path;
+    std::optional<std::string> encoder_input_base_path;
+    std::optional<std::string> encoder_output_base_path;
   };
 
   virtual ~VideoCodecTester() = default;
@@ -183,10 +183,10 @@
    public:
     virtual ~CodedVideoSource() = default;
 
-    // Returns next frame. Returns `absl::nullopt` if the end-of-stream is
+    // Returns next frame. Returns `std::nullopt` if the end-of-stream is
     // reached. Frames should have RTP timestamps representing desired frame
     // rate.
-    virtual absl::optional<EncodedImage> PullFrame() = 0;
+    virtual std::optional<EncodedImage> PullFrame() = 0;
   };
 
   // A helper function that creates `EncodingSettings` from the given
diff --git a/test/video_codec_tester_unittest.cc b/test/video_codec_tester_unittest.cc
index e219995..df2ac23 100644
--- a/test/video_codec_tester_unittest.cc
+++ b/test/video_codec_tester_unittest.cc
@@ -188,7 +188,7 @@
       std::string codec_type,
       ScalabilityMode scalability_mode,
       std::vector<std::vector<Frame>> encoded_frames,
-      absl::optional<int> num_source_frames = absl::nullopt) {
+      std::optional<int> num_source_frames = std::nullopt) {
     int num_frames = encoded_frames.size();
     std::string yuv_path =
         CreateYuvFile(kWidth, kHeight, num_source_frames.value_or(num_frames));
@@ -276,9 +276,9 @@
   MockCodedVideoSource(int num_frames, Frequency framerate)
       : num_frames_(num_frames), frame_num_(0), framerate_(framerate) {}
 
-  absl::optional<EncodedImage> PullFrame() override {
+  std::optional<EncodedImage> PullFrame() override {
     if (frame_num_ >= num_frames_) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     uint32_t timestamp_rtp = frame_num_ * k90kHz / framerate_;
     ++frame_num_;
diff --git a/test/video_encoder_proxy_factory.h b/test/video_encoder_proxy_factory.h
index 6a5ff6f..5560fb8 100644
--- a/test/video_encoder_proxy_factory.h
+++ b/test/video_encoder_proxy_factory.h
@@ -127,17 +127,17 @@
       encoder_selector_->OnCurrentEncoder(format);
     }
 
-    absl::optional<SdpVideoFormat> OnAvailableBitrate(
+    std::optional<SdpVideoFormat> OnAvailableBitrate(
         const DataRate& rate) override {
       return encoder_selector_->OnAvailableBitrate(rate);
     }
 
-    absl::optional<SdpVideoFormat> OnResolutionChange(
+    std::optional<SdpVideoFormat> OnResolutionChange(
         const RenderResolution& resolution) override {
       return encoder_selector_->OnResolutionChange(resolution);
     }
 
-    absl::optional<SdpVideoFormat> OnEncoderBroken() override {
+    std::optional<SdpVideoFormat> OnEncoderBroken() override {
       return encoder_selector_->OnEncoderBroken();
     }
 
diff --git a/video/BUILD.gn b/video/BUILD.gn
index 507e428..f46c29f 100644
--- a/video/BUILD.gn
+++ b/video/BUILD.gn
@@ -170,7 +170,6 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 
   if (!build_with_mozilla) {
@@ -292,7 +291,6 @@
     "../system_wrappers:field_trial",
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/functional:bind_front",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -302,7 +300,6 @@
     ":frame_decode_timing",
     "../api/units:timestamp",
     "//third_party/abseil-cpp/absl/functional:any_invocable",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -335,7 +332,6 @@
     "../modules/video_coding/timing:timing_module",
     "../rtc_base:logging",
     "../system_wrappers",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -371,7 +367,6 @@
     "../rtc_base:event_tracer",
     "../rtc_base:logging",
     "../rtc_base:macromagic",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -469,7 +464,6 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/cleanup",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -605,7 +599,6 @@
         "//testing/gtest",
         "//third_party/abseil-cpp/absl/flags:flag",
         "//third_party/abseil-cpp/absl/flags:parse",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
 
@@ -666,7 +659,6 @@
         "//testing/gtest",
         "//third_party/abseil-cpp/absl/flags:flag",
         "//third_party/abseil-cpp/absl/flags:parse",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
 
@@ -710,7 +702,6 @@
         "../test:test_support",
         "//third_party/abseil-cpp/absl/flags:flag",
         "//third_party/abseil-cpp/absl/flags:parse",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
 
@@ -739,7 +730,6 @@
         "//testing/gtest",
         "//third_party/abseil-cpp/absl/flags:flag",
         "//third_party/abseil-cpp/absl/flags:parse",
-        "//third_party/abseil-cpp/absl/types:optional",
       ]
     }
   }
@@ -965,7 +955,6 @@
       "//third_party/abseil-cpp/absl/functional:any_invocable",
       "//third_party/abseil-cpp/absl/memory",
       "//third_party/abseil-cpp/absl/strings",
-      "//third_party/abseil-cpp/absl/types:optional",
       "//third_party/abseil-cpp/absl/types:variant",
     ]
     if (!build_with_mozilla) {
diff --git a/video/adaptation/BUILD.gn b/video/adaptation/BUILD.gn
index 1aa280a..829d1f1 100644
--- a/video/adaptation/BUILD.gn
+++ b/video/adaptation/BUILD.gn
@@ -68,7 +68,6 @@
     "../../video/config:encoder_config",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/base:core_headers",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -112,7 +111,6 @@
       "../../test:test_support",
       "../../test/time_controller:time_controller",
       "//third_party/abseil-cpp/absl/functional:any_invocable",
-      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
diff --git a/video/adaptation/balanced_constraint.cc b/video/adaptation/balanced_constraint.cc
index f9ee08a..0e8975c 100644
--- a/video/adaptation/balanced_constraint.cc
+++ b/video/adaptation/balanced_constraint.cc
@@ -20,7 +20,7 @@
 BalancedConstraint::BalancedConstraint(
     DegradationPreferenceProvider* degradation_preference_provider,
     const FieldTrialsView& field_trials)
-    : encoder_target_bitrate_bps_(absl::nullopt),
+    : encoder_target_bitrate_bps_(std::nullopt),
       balanced_settings_(field_trials),
       degradation_preference_provider_(degradation_preference_provider) {
   RTC_DCHECK(degradation_preference_provider_);
@@ -28,7 +28,7 @@
 }
 
 void BalancedConstraint::OnEncoderTargetBitrateUpdated(
-    absl::optional<uint32_t> encoder_target_bitrate_bps) {
+    std::optional<uint32_t> encoder_target_bitrate_bps) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   encoder_target_bitrate_bps_ = std::move(encoder_target_bitrate_bps);
 }
diff --git a/video/adaptation/balanced_constraint.h b/video/adaptation/balanced_constraint.h
index 22c7d29..294fe6f 100644
--- a/video/adaptation/balanced_constraint.h
+++ b/video/adaptation/balanced_constraint.h
@@ -11,9 +11,9 @@
 #ifndef VIDEO_ADAPTATION_BALANCED_CONSTRAINT_H_
 #define VIDEO_ADAPTATION_BALANCED_CONSTRAINT_H_
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/sequence_checker.h"
 #include "call/adaptation/adaptation_constraint.h"
@@ -31,7 +31,7 @@
   ~BalancedConstraint() override = default;
 
   void OnEncoderTargetBitrateUpdated(
-      absl::optional<uint32_t> encoder_target_bitrate_bps);
+      std::optional<uint32_t> encoder_target_bitrate_bps);
 
   // AdaptationConstraint implementation.
   std::string Name() const override { return "BalancedConstraint"; }
@@ -42,7 +42,7 @@
 
  private:
   RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
-  absl::optional<uint32_t> encoder_target_bitrate_bps_
+  std::optional<uint32_t> encoder_target_bitrate_bps_
       RTC_GUARDED_BY(&sequence_checker_);
   const BalancedDegradationSettings balanced_settings_;
   const DegradationPreferenceProvider* degradation_preference_provider_;
diff --git a/video/adaptation/bandwidth_quality_scaler_resource.h b/video/adaptation/bandwidth_quality_scaler_resource.h
index a57c990..c108039 100644
--- a/video/adaptation/bandwidth_quality_scaler_resource.h
+++ b/video/adaptation/bandwidth_quality_scaler_resource.h
@@ -12,11 +12,11 @@
 #define VIDEO_ADAPTATION_BANDWIDTH_QUALITY_SCALER_RESOURCE_H_
 
 #include <memory>
+#include <optional>
 #include <queue>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
 #include "api/video/video_adaptation_reason.h"
 #include "api/video_codecs/video_encoder.h"
diff --git a/video/adaptation/bitrate_constraint.cc b/video/adaptation/bitrate_constraint.cc
index 2f92095..6eb480b 100644
--- a/video/adaptation/bitrate_constraint.cc
+++ b/video/adaptation/bitrate_constraint.cc
@@ -20,19 +20,19 @@
 namespace webrtc {
 
 BitrateConstraint::BitrateConstraint()
-    : encoder_settings_(absl::nullopt),
-      encoder_target_bitrate_bps_(absl::nullopt) {
+    : encoder_settings_(std::nullopt),
+      encoder_target_bitrate_bps_(std::nullopt) {
   sequence_checker_.Detach();
 }
 
 void BitrateConstraint::OnEncoderSettingsUpdated(
-    absl::optional<EncoderSettings> encoder_settings) {
+    std::optional<EncoderSettings> encoder_settings) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   encoder_settings_ = std::move(encoder_settings);
 }
 
 void BitrateConstraint::OnEncoderTargetBitrateUpdated(
-    absl::optional<uint32_t> encoder_target_bitrate_bps) {
+    std::optional<uint32_t> encoder_target_bitrate_bps) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   encoder_target_bitrate_bps_ = std::move(encoder_target_bitrate_bps);
 }
@@ -64,13 +64,13 @@
       return true;
     }
 
-    absl::optional<int> current_frame_size_px =
+    std::optional<int> current_frame_size_px =
         input_state.single_active_stream_pixels();
     if (!current_frame_size_px.has_value()) {
       return true;
     }
 
-    absl::optional<VideoEncoder::ResolutionBitrateLimits> bitrate_limits =
+    std::optional<VideoEncoder::ResolutionBitrateLimits> bitrate_limits =
         encoder_settings_->encoder_info().GetEncoderBitrateLimitsForResolution(
             // Need some sort of expected resulting pixels to be used
             // instead of unrestricted.
diff --git a/video/adaptation/bitrate_constraint.h b/video/adaptation/bitrate_constraint.h
index a608e5d..8906a16 100644
--- a/video/adaptation/bitrate_constraint.h
+++ b/video/adaptation/bitrate_constraint.h
@@ -11,9 +11,9 @@
 #ifndef VIDEO_ADAPTATION_BITRATE_CONSTRAINT_H_
 #define VIDEO_ADAPTATION_BITRATE_CONSTRAINT_H_
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/sequence_checker.h"
 #include "call/adaptation/adaptation_constraint.h"
 #include "call/adaptation/encoder_settings.h"
@@ -29,9 +29,9 @@
   ~BitrateConstraint() override = default;
 
   void OnEncoderSettingsUpdated(
-      absl::optional<EncoderSettings> encoder_settings);
+      std::optional<EncoderSettings> encoder_settings);
   void OnEncoderTargetBitrateUpdated(
-      absl::optional<uint32_t> encoder_target_bitrate_bps);
+      std::optional<uint32_t> encoder_target_bitrate_bps);
 
   // AdaptationConstraint implementation.
   std::string Name() const override { return "BitrateConstraint"; }
@@ -42,9 +42,9 @@
 
  private:
   RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
-  absl::optional<EncoderSettings> encoder_settings_
+  std::optional<EncoderSettings> encoder_settings_
       RTC_GUARDED_BY(&sequence_checker_);
-  absl::optional<uint32_t> encoder_target_bitrate_bps_
+  std::optional<uint32_t> encoder_target_bitrate_bps_
       RTC_GUARDED_BY(&sequence_checker_);
 };
 
diff --git a/video/adaptation/bitrate_constraint_unittest.cc b/video/adaptation/bitrate_constraint_unittest.cc
index 8a416db..29ebb6a 100644
--- a/video/adaptation/bitrate_constraint_unittest.cc
+++ b/video/adaptation/bitrate_constraint_unittest.cc
@@ -36,7 +36,7 @@
 
 struct TestParams {
   bool active;
-  absl::optional<ScalabilityMode> scalability_mode;
+  std::optional<ScalabilityMode> scalability_mode;
 };
 
 void FillCodecConfig(VideoCodec* video_codec,
diff --git a/video/adaptation/encode_usage_resource.cc b/video/adaptation/encode_usage_resource.cc
index 4a97881..24d0e5f 100644
--- a/video/adaptation/encode_usage_resource.cc
+++ b/video/adaptation/encode_usage_resource.cc
@@ -29,7 +29,7 @@
     : VideoStreamEncoderResource("EncoderUsageResource"),
       overuse_detector_(std::move(overuse_detector)),
       is_started_(false),
-      target_frame_rate_(absl::nullopt) {
+      target_frame_rate_(std::nullopt) {
   RTC_DCHECK(overuse_detector_);
 }
 
@@ -56,7 +56,7 @@
 }
 
 void EncodeUsageResource::SetTargetFrameRate(
-    absl::optional<double> target_frame_rate) {
+    std::optional<double> target_frame_rate) {
   RTC_DCHECK_RUN_ON(encoder_queue());
   if (target_frame_rate == target_frame_rate_)
     return;
@@ -77,7 +77,7 @@
     uint32_t timestamp,
     int64_t time_sent_in_us,
     int64_t capture_time_us,
-    absl::optional<int> encode_duration_us) {
+    std::optional<int> encode_duration_us) {
   RTC_DCHECK_RUN_ON(encoder_queue());
   // TODO(hbos): Rename FrameSent() to something more appropriate (e.g.
   // "OnEncodeCompleted"?).
diff --git a/video/adaptation/encode_usage_resource.h b/video/adaptation/encode_usage_resource.h
index c391132..d12e19d 100644
--- a/video/adaptation/encode_usage_resource.h
+++ b/video/adaptation/encode_usage_resource.h
@@ -12,9 +12,9 @@
 #define VIDEO_ADAPTATION_ENCODE_USAGE_RESOURCE_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
 #include "api/video/video_adaptation_reason.h"
 #include "video/adaptation/overuse_frame_detector.h"
@@ -42,13 +42,13 @@
   void StartCheckForOveruse(CpuOveruseOptions options);
   void StopCheckForOveruse();
 
-  void SetTargetFrameRate(absl::optional<double> target_frame_rate);
+  void SetTargetFrameRate(std::optional<double> target_frame_rate);
   void OnEncodeStarted(const VideoFrame& cropped_frame,
                        int64_t time_when_first_seen_us);
   void OnEncodeCompleted(uint32_t timestamp,
                          int64_t time_sent_in_us,
                          int64_t capture_time_us,
-                         absl::optional<int> encode_duration_us);
+                         std::optional<int> encode_duration_us);
 
   // OveruseFrameDetectorObserverInterface implementation.
   void AdaptUp() override;
@@ -60,7 +60,7 @@
   const std::unique_ptr<OveruseFrameDetector> overuse_detector_
       RTC_GUARDED_BY(encoder_queue());
   bool is_started_ RTC_GUARDED_BY(encoder_queue());
-  absl::optional<double> target_frame_rate_ RTC_GUARDED_BY(encoder_queue());
+  std::optional<double> target_frame_rate_ RTC_GUARDED_BY(encoder_queue());
 };
 
 }  // namespace webrtc
diff --git a/video/adaptation/overuse_frame_detector.cc b/video/adaptation/overuse_frame_detector.cc
index 2397b55..1739f95 100644
--- a/video/adaptation/overuse_frame_detector.cc
+++ b/video/adaptation/overuse_frame_detector.cc
@@ -110,12 +110,12 @@
         frame.timestamp_us(), frame.rtp_timestamp(), time_when_first_seen_us));
   }
 
-  absl::optional<int> FrameSent(
+  std::optional<int> FrameSent(
       uint32_t timestamp,
       int64_t time_sent_in_us,
       int64_t /* capture_time_us */,
-      absl::optional<int> /* encode_duration_us */) override {
-    absl::optional<int> encode_duration_us;
+      std::optional<int> /* encode_duration_us */) override {
+    std::optional<int> encode_duration_us;
     // Delay before reporting actual encoding time, used to have the ability to
     // detect total encoding time when encoding more than one layer. Encoding is
     // here assumed to finish within a second (or that we get enough long-time
@@ -242,11 +242,10 @@
                      int64_t time_when_first_seen_us,
                      int64_t last_capture_time_us) override {}
 
-  absl::optional<int> FrameSent(
-      uint32_t /* timestamp */,
-      int64_t /* time_sent_in_us */,
-      int64_t capture_time_us,
-      absl::optional<int> encode_duration_us) override {
+  std::optional<int> FrameSent(uint32_t /* timestamp */,
+                               int64_t /* time_sent_in_us */,
+                               int64_t capture_time_us,
+                               std::optional<int> encode_duration_us) override {
     if (encode_duration_us) {
       int duration_per_frame_us =
           DurationPerInputFrame(capture_time_us, *encode_duration_us);
@@ -364,13 +363,13 @@
     usage_->FrameCaptured(frame, time_when_first_seen_us, last_capture_time_us);
   }
 
-  absl::optional<int> FrameSent(
+  std::optional<int> FrameSent(
       // These two argument used by old estimator.
       uint32_t timestamp,
       int64_t time_sent_in_us,
       // And these two by the new estimator.
       int64_t capture_time_us,
-      absl::optional<int> encode_duration_us) override {
+      std::optional<int> encode_duration_us) override {
     return usage_->FrameSent(timestamp, time_sent_in_us, capture_time_us,
                              encode_duration_us);
   }
@@ -405,7 +404,7 @@
       }
     }
 
-    absl::optional<int> overried_usage_value;
+    std::optional<int> overried_usage_value;
     switch (state_) {
       case State::kNormal:
         break;
@@ -473,7 +472,7 @@
     : env_(env),
       metrics_observer_(metrics_observer),
       num_process_times_(0),
-      // TODO(bugs.webrtc.org/9078): Use absl::optional
+      // TODO(bugs.webrtc.org/9078): Use std::optional
       last_capture_time_us_(-1),
       num_pixels_(0),
       max_framerate_(kDefaultFrameRate),
@@ -543,7 +542,7 @@
   usage_->Reset();
   last_capture_time_us_ = -1;
   num_process_times_ = 0;
-  encode_usage_percent_ = absl::nullopt;
+  encode_usage_percent_ = std::nullopt;
   OnTargetFramerateUpdated(max_framerate_);
 }
 
@@ -571,7 +570,7 @@
 void OveruseFrameDetector::FrameSent(uint32_t timestamp,
                                      int64_t time_sent_in_us,
                                      int64_t capture_time_us,
-                                     absl::optional<int> encode_duration_us) {
+                                     std::optional<int> encode_duration_us) {
   RTC_DCHECK_RUN_ON(&task_checker_);
   encode_duration_us = usage_->FrameSent(timestamp, time_sent_in_us,
                                          capture_time_us, encode_duration_us);
diff --git a/video/adaptation/overuse_frame_detector.h b/video/adaptation/overuse_frame_detector.h
index e1729a0..bfdc8eb 100644
--- a/video/adaptation/overuse_frame_detector.h
+++ b/video/adaptation/overuse_frame_detector.h
@@ -13,8 +13,8 @@
 
 #include <list>
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/field_trials_view.h"
 #include "api/sequence_checker.h"
@@ -105,7 +105,7 @@
   void FrameSent(uint32_t timestamp,
                  int64_t time_sent_in_us,
                  int64_t capture_time_us,
-                 absl::optional<int> encode_duration_us);
+                 std::optional<int> encode_duration_us);
 
   // Interface for cpu load estimation. Intended for internal use only.
   class ProcessingUsage {
@@ -116,13 +116,13 @@
                                int64_t time_when_first_seen_us,
                                int64_t last_capture_time_us) = 0;
     // Returns encode_time in us, if there's a new measurement.
-    virtual absl::optional<int> FrameSent(
+    virtual std::optional<int> FrameSent(
         // These two argument used by old estimator.
         uint32_t timestamp,
         int64_t time_sent_in_us,
         // And these two by the new estimator.
         int64_t capture_time_us,
-        absl::optional<int> encode_duration_us) = 0;
+        std::optional<int> encode_duration_us) = 0;
 
     virtual int Value() = 0;
     virtual ~ProcessingUsage() = default;
@@ -156,7 +156,7 @@
 
   // Stats metrics.
   CpuOveruseMetricsObserver* const metrics_observer_;
-  absl::optional<int> encode_usage_percent_ RTC_GUARDED_BY(task_checker_);
+  std::optional<int> encode_usage_percent_ RTC_GUARDED_BY(task_checker_);
 
   int64_t num_process_times_ RTC_GUARDED_BY(task_checker_);
 
diff --git a/video/adaptation/overuse_frame_detector_unittest.cc b/video/adaptation/overuse_frame_detector_unittest.cc
index 3c6ce57..b1abdd3 100644
--- a/video/adaptation/overuse_frame_detector_unittest.cc
+++ b/video/adaptation/overuse_frame_detector_unittest.cc
@@ -176,7 +176,7 @@
       clock_.AdvanceTime(TimeDelta::Micros(delay_us));
       overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(),
                                    capture_time_us,
-                                   absl::optional<int>(delay_us));
+                                   std::optional<int>(delay_us));
 
       overuse_detector_->CheckForOveruse(observer_);
       // Avoid turning clock backwards.
diff --git a/video/adaptation/pixel_limit_resource.cc b/video/adaptation/pixel_limit_resource.cc
index 872e169..9baed46 100644
--- a/video/adaptation/pixel_limit_resource.cc
+++ b/video/adaptation/pixel_limit_resource.cc
@@ -36,7 +36,7 @@
     VideoStreamInputStateProvider* input_state_provider)
     : task_queue_(task_queue),
       input_state_provider_(input_state_provider),
-      max_pixels_(absl::nullopt) {
+      max_pixels_(std::nullopt) {
   RTC_DCHECK(task_queue_);
   RTC_DCHECK(input_state_provider_);
 }
@@ -67,7 +67,7 @@
         // No pixel limit configured yet, try again later.
         return kResourceUsageCheckIntervalMs;
       }
-      absl::optional<int> frame_size_pixels =
+      std::optional<int> frame_size_pixels =
           input_state_provider_->InputState().frame_size_pixels();
       if (!frame_size_pixels.has_value()) {
         // We haven't observed a frame yet so we don't know if it's going to be
diff --git a/video/adaptation/pixel_limit_resource.h b/video/adaptation/pixel_limit_resource.h
index b42f924..3e5f9f4 100644
--- a/video/adaptation/pixel_limit_resource.h
+++ b/video/adaptation/pixel_limit_resource.h
@@ -11,9 +11,9 @@
 #ifndef VIDEO_ADAPTATION_PIXEL_LIMIT_RESOURCE_H_
 #define VIDEO_ADAPTATION_PIXEL_LIMIT_RESOURCE_H_
 
+#include <optional>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/adaptation/resource.h"
 #include "api/scoped_refptr.h"
 #include "call/adaptation/video_stream_input_state_provider.h"
@@ -50,7 +50,7 @@
  private:
   TaskQueueBase* const task_queue_;
   VideoStreamInputStateProvider* const input_state_provider_;
-  absl::optional<int> max_pixels_ RTC_GUARDED_BY(task_queue_);
+  std::optional<int> max_pixels_ RTC_GUARDED_BY(task_queue_);
   webrtc::ResourceListener* listener_ RTC_GUARDED_BY(task_queue_);
   RepeatingTaskHandle repeating_task_ RTC_GUARDED_BY(task_queue_);
 };
diff --git a/video/adaptation/quality_scaler_resource.h b/video/adaptation/quality_scaler_resource.h
index 0bdc25e..92e72db 100644
--- a/video/adaptation/quality_scaler_resource.h
+++ b/video/adaptation/quality_scaler_resource.h
@@ -12,10 +12,10 @@
 #define VIDEO_ADAPTATION_QUALITY_SCALER_RESOURCE_H_
 
 #include <memory>
+#include <optional>
 #include <queue>
 #include <string>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/scoped_refptr.h"
 #include "api/video/video_adaptation_reason.h"
diff --git a/video/adaptation/quality_scaler_resource_unittest.cc b/video/adaptation/quality_scaler_resource_unittest.cc
index 70d2975..3b9c523 100644
--- a/video/adaptation/quality_scaler_resource_unittest.cc
+++ b/video/adaptation/quality_scaler_resource_unittest.cc
@@ -11,8 +11,8 @@
 #include "video/adaptation/quality_scaler_resource.h"
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/video_codecs/video_encoder.h"
 #include "call/adaptation/test/mock_resource_listener.h"
diff --git a/video/adaptation/video_stream_encoder_resource.h b/video/adaptation/video_stream_encoder_resource.h
index e10f595..5e93b31 100644
--- a/video/adaptation/video_stream_encoder_resource.h
+++ b/video/adaptation/video_stream_encoder_resource.h
@@ -11,10 +11,10 @@
 #ifndef VIDEO_ADAPTATION_VIDEO_STREAM_ENCODER_RESOURCE_H_
 #define VIDEO_ADAPTATION_VIDEO_STREAM_ENCODER_RESOURCE_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/adaptation/resource.h"
 #include "api/sequence_checker.h"
 #include "api/task_queue/task_queue_base.h"
diff --git a/video/adaptation/video_stream_encoder_resource_manager.cc b/video/adaptation/video_stream_encoder_resource_manager.cc
index 2bb6f29..96b7f89 100644
--- a/video/adaptation/video_stream_encoder_resource_manager.cc
+++ b/video/adaptation/video_stream_encoder_resource_manager.cc
@@ -114,15 +114,15 @@
     return initial_framedrop_ < kMaxInitialFramedrop;
   }
 
-  absl::optional<uint32_t> single_active_stream_pixels() const {
+  std::optional<uint32_t> single_active_stream_pixels() const {
     return single_active_stream_pixels_;
   }
 
-  absl::optional<uint32_t> UseBandwidthAllocationBps() const {
+  std::optional<uint32_t> UseBandwidthAllocationBps() const {
     return (use_bandwidth_allocation_ &&
             bandwidth_allocation_ > DataRate::Zero())
-               ? absl::optional<uint32_t>(bandwidth_allocation_.bps())
-               : absl::nullopt;
+               ? std::optional<uint32_t>(bandwidth_allocation_.bps())
+               : std::nullopt;
   }
 
   bool last_stream_configuration_changed() const {
@@ -229,7 +229,7 @@
   int64_t set_start_bitrate_time_ms_;
   // Counts how many frames we've dropped in the initial framedrop phase.
   int initial_framedrop_;
-  absl::optional<uint32_t> single_active_stream_pixels_;
+  std::optional<uint32_t> single_active_stream_pixels_;
   bool use_bandwidth_allocation_;
   DataRate bandwidth_allocation_;
 
@@ -276,8 +276,8 @@
           QualityScalingExperiment::Enabled(field_trials_)),
       pixel_limit_resource_experiment_enabled_(
           field_trials.IsEnabled(kPixelLimitResourceFieldTrialName)),
-      encoder_target_bitrate_bps_(absl::nullopt),
-      encoder_settings_(absl::nullopt) {
+      encoder_target_bitrate_bps_(std::nullopt),
+      encoder_settings_(std::nullopt) {
   TRACE_EVENT0(
       "webrtc",
       "VideoStreamEncoderResourceManager::VideoStreamEncoderResourceManager");
@@ -479,7 +479,7 @@
 void VideoStreamEncoderResourceManager::OnEncodeCompleted(
     const EncodedImage& encoded_image,
     int64_t time_sent_in_us,
-    absl::optional<int> encode_duration_us,
+    std::optional<int> encode_duration_us,
     DataSize frame_size) {
   RTC_DCHECK_RUN_ON(encoder_queue_);
   // Inform `encode_usage_resource_` of the encode completed event.
@@ -504,13 +504,13 @@
   return initial_frame_dropper_->DropInitialFrames();
 }
 
-absl::optional<uint32_t>
+std::optional<uint32_t>
 VideoStreamEncoderResourceManager::SingleActiveStreamPixels() const {
   RTC_DCHECK_RUN_ON(encoder_queue_);
   return initial_frame_dropper_->single_active_stream_pixels();
 }
 
-absl::optional<uint32_t>
+std::optional<uint32_t>
 VideoStreamEncoderResourceManager::UseBandwidthAllocationBps() const {
   RTC_DCHECK_RUN_ON(encoder_queue_);
   return initial_frame_dropper_->UseBandwidthAllocationBps();
@@ -522,7 +522,7 @@
 }
 
 void VideoStreamEncoderResourceManager::UpdateQualityScalerSettings(
-    absl::optional<VideoEncoder::QpThresholds> qp_thresholds) {
+    std::optional<VideoEncoder::QpThresholds> qp_thresholds) {
   RTC_DCHECK_RUN_ON(encoder_queue_);
   if (qp_thresholds.has_value()) {
     if (quality_scaler_resource_->is_started()) {
@@ -580,7 +580,7 @@
       // Quality scaler has not already been configured.
 
       // Use experimental thresholds if available.
-      absl::optional<VideoEncoder::QpThresholds> experimental_thresholds;
+      std::optional<VideoEncoder::QpThresholds> experimental_thresholds;
       if (quality_scaling_experiment_enabled_) {
         experimental_thresholds = QualityScalingExperiment::GetQpThresholds(
             GetVideoCodecTypeOrGeneric(encoder_settings_), field_trials_);
@@ -590,13 +590,13 @@
                                       : scaling_settings.thresholds);
     }
   } else {
-    UpdateQualityScalerSettings(absl::nullopt);
+    UpdateQualityScalerSettings(std::nullopt);
   }
 
   // Set the qp-thresholds to the balanced settings if balanced mode.
   if (degradation_preference_ == DegradationPreference::BALANCED &&
       quality_scaler_resource_->is_started()) {
-    absl::optional<VideoEncoder::QpThresholds> thresholds =
+    std::optional<VideoEncoder::QpThresholds> thresholds =
         balanced_settings_.GetQpThresholds(
             GetVideoCodecTypeOrGeneric(encoder_settings_),
             LastFrameSizeOrDefault());
@@ -712,16 +712,15 @@
 
 void VideoStreamEncoderResourceManager::MaybeUpdateTargetFrameRate() {
   RTC_DCHECK_RUN_ON(encoder_queue_);
-  absl::optional<double> codec_max_frame_rate =
+  std::optional<double> codec_max_frame_rate =
       encoder_settings_.has_value()
-          ? absl::optional<double>(
-                encoder_settings_->video_codec().maxFramerate)
-          : absl::nullopt;
+          ? std::optional<double>(encoder_settings_->video_codec().maxFramerate)
+          : std::nullopt;
   // The current target framerate is the maximum frame rate as specified by
   // the current codec configuration or any limit imposed by the adaptation
   // module. This is used to make sure overuse detection doesn't needlessly
   // trigger in low and/or variable framerate scenarios.
-  absl::optional<double> target_frame_rate =
+  std::optional<double> target_frame_rate =
       video_source_restrictions_.max_frame_rate();
   if (!target_frame_rate.has_value() ||
       (codec_max_frame_rate.has_value() &&
@@ -776,7 +775,7 @@
     return false;
   }
 
-  absl::optional<int> num_spatial_layers;
+  std::optional<int> num_spatial_layers;
   if (simulcast_layers[0].scalability_mode.has_value() &&
       video_codec.numberOfSimulcastStreams == 1) {
     num_spatial_layers = ScalabilityModeToNumSpatialLayers(
diff --git a/video/adaptation/video_stream_encoder_resource_manager.h b/video/adaptation/video_stream_encoder_resource_manager.h
index 38f3f08..32e260d 100644
--- a/video/adaptation/video_stream_encoder_resource_manager.h
+++ b/video/adaptation/video_stream_encoder_resource_manager.h
@@ -14,12 +14,12 @@
 #include <atomic>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <unordered_map>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/adaptation/resource.h"
 #include "api/field_trials_view.h"
 #include "api/rtp_parameters.h"
@@ -119,7 +119,7 @@
                        int64_t time_when_first_seen_us);
   void OnEncodeCompleted(const EncodedImage& encoded_image,
                          int64_t time_sent_in_us,
-                         absl::optional<int> encode_duration_us,
+                         std::optional<int> encode_duration_us,
                          DataSize frame_size);
   void OnFrameDropped(EncodedImageCallback::DropReason reason);
 
@@ -132,8 +132,8 @@
   // If true, the VideoStreamEncoder should execute its logic to maybe drop
   // frames based on size and bitrate.
   bool DropInitialFrames() const;
-  absl::optional<uint32_t> SingleActiveStreamPixels() const;
-  absl::optional<uint32_t> UseBandwidthAllocationBps() const;
+  std::optional<uint32_t> SingleActiveStreamPixels() const;
+  std::optional<uint32_t> UseBandwidthAllocationBps() const;
 
   // VideoSourceRestrictionsListener implementation.
   // Updates `video_source_restrictions_`.
@@ -166,7 +166,7 @@
 
   // Use nullopt to disable quality scaling.
   void UpdateQualityScalerSettings(
-      absl::optional<VideoEncoder::QpThresholds> qp_thresholds);
+      std::optional<VideoEncoder::QpThresholds> qp_thresholds);
 
   void UpdateBandwidthQualityScalerSettings(
       bool bandwidth_quality_scaling_allowed,
@@ -214,11 +214,11 @@
   const bool quality_scaling_experiment_enabled_ RTC_GUARDED_BY(encoder_queue_);
   const bool pixel_limit_resource_experiment_enabled_
       RTC_GUARDED_BY(encoder_queue_);
-  absl::optional<uint32_t> encoder_target_bitrate_bps_
+  std::optional<uint32_t> encoder_target_bitrate_bps_
       RTC_GUARDED_BY(encoder_queue_);
-  absl::optional<VideoEncoder::RateControlParameters> encoder_rates_
+  std::optional<VideoEncoder::RateControlParameters> encoder_rates_
       RTC_GUARDED_BY(encoder_queue_);
-  absl::optional<EncoderSettings> encoder_settings_
+  std::optional<EncoderSettings> encoder_settings_
       RTC_GUARDED_BY(encoder_queue_);
 
   // Ties a resource to a reason for statistical reporting. This AdaptReason is
diff --git a/video/alignment_adjuster.cc b/video/alignment_adjuster.cc
index 1762bec..de32992 100644
--- a/video/alignment_adjuster.cc
+++ b/video/alignment_adjuster.cc
@@ -67,7 +67,7 @@
 int AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
     const VideoEncoder::EncoderInfo& encoder_info,
     VideoEncoderConfig* config,
-    absl::optional<size_t> max_layers) {
+    std::optional<size_t> max_layers) {
   const int requested_alignment = encoder_info.requested_resolution_alignment;
   if (!encoder_info.apply_alignment_to_all_simulcast_layers) {
     return requested_alignment;
diff --git a/video/alignment_adjuster.h b/video/alignment_adjuster.h
index 36ac062..086f633 100644
--- a/video/alignment_adjuster.h
+++ b/video/alignment_adjuster.h
@@ -34,7 +34,7 @@
   static int GetAlignmentAndMaybeAdjustScaleFactors(
       const VideoEncoder::EncoderInfo& info,
       VideoEncoderConfig* config,
-      absl::optional<size_t> max_layers);
+      std::optional<size_t> max_layers);
 };
 
 }  // namespace webrtc
diff --git a/video/alignment_adjuster_unittest.cc b/video/alignment_adjuster_unittest.cc
index 28e4bc0..95a5e13 100644
--- a/video/alignment_adjuster_unittest.cc
+++ b/video/alignment_adjuster_unittest.cc
@@ -125,7 +125,7 @@
   VideoEncoder::EncoderInfo info =
       GetEncoderInfo(kRequestedAlignment, kApplyAlignmentToAllLayers);
   int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
-      info, &config, absl::nullopt);
+      info, &config, std::nullopt);
   EXPECT_EQ(alignment, kAdjustedAlignment);
 
   // Verify adjusted scale factors.
@@ -150,7 +150,7 @@
   VideoEncoder::EncoderInfo info =
       GetEncoderInfo(kRequestedAlignment, kApplyAlignmentToAllLayers);
   int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
-      info, &config, absl::nullopt);
+      info, &config, std::nullopt);
   EXPECT_EQ(alignment, kRequestedAlignment);
 
   // Verify that scale factors are not adjusted.
@@ -175,7 +175,7 @@
   VideoEncoder::EncoderInfo info =
       GetEncoderInfo(kRequestedAlignment, kApplyAlignmentToAllLayers);
   int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
-      info, &config, absl::optional<size_t>(kMaxLayers));
+      info, &config, std::optional<size_t>(kMaxLayers));
   EXPECT_EQ(alignment, kAdjustedAlignment);
 
   // Verify adjusted scale factors.
diff --git a/video/buffered_frame_decryptor_unittest.cc b/video/buffered_frame_decryptor_unittest.cc
index 074777b..5089a0e 100644
--- a/video/buffered_frame_decryptor_unittest.cc
+++ b/video/buffered_frame_decryptor_unittest.cc
@@ -74,7 +74,7 @@
         kVideoRotation_0,
         VideoContentType::UNSPECIFIED,
         rtp_video_header,
-        /*color_space=*/absl::nullopt,
+        /*color_space=*/std::nullopt,
         RtpPacketInfos(),
         EncodedImageBuffer::Create(/*size=*/0));
     // clang-format on
diff --git a/video/config/BUILD.gn b/video/config/BUILD.gn
index 9c1c064..17930de 100644
--- a/video/config/BUILD.gn
+++ b/video/config/BUILD.gn
@@ -37,7 +37,6 @@
     "../../rtc_base/experiments:rate_control_settings",
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -56,7 +55,6 @@
     "../../rtc_base:checks",
     "../../rtc_base:refcount",
     "../../rtc_base:stringutils",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
diff --git a/video/config/encoder_stream_factory.cc b/video/config/encoder_stream_factory.cc
index d80f0d1..fc5254d 100644
--- a/video/config/encoder_stream_factory.cc
+++ b/video/config/encoder_stream_factory.cc
@@ -118,7 +118,7 @@
                            int size,
                            size_t simulcast_layers) {
   int base2_exponent = static_cast<int>(simulcast_layers) - 1;
-  const absl::optional<int> experimental_base2_exponent =
+  const std::optional<int> experimental_base2_exponent =
       webrtc::NormalizeSimulcastSizeExperiment::GetBase2Exponent(field_trials);
   if (experimental_base2_exponent &&
       (size > (1 << *experimental_base2_exponent))) {
@@ -131,7 +131,7 @@
 // `encoder_config.simulcast_layers` which come from `RtpEncodingParameters`.
 void OverrideStreamSettings(
     const webrtc::VideoEncoderConfig& encoder_config,
-    const absl::optional<webrtc::DataRate>& experimental_min_bitrate,
+    const std::optional<webrtc::DataRate>& experimental_min_bitrate,
     std::vector<webrtc::VideoStream>& layers) {
   RTC_DCHECK_LE(layers.size(), encoder_config.simulcast_layers.size());
 
@@ -248,7 +248,7 @@
 
 EncoderStreamFactory::EncoderStreamFactory(
     const webrtc::VideoEncoder::EncoderInfo& encoder_info,
-    absl::optional<webrtc::VideoSourceRestrictions> restrictions)
+    std::optional<webrtc::VideoSourceRestrictions> restrictions)
     : encoder_info_requested_resolution_alignment_(
           encoder_info.requested_resolution_alignment),
       restrictions_(restrictions) {}
@@ -262,7 +262,7 @@
   RTC_DCHECK_GE(encoder_config.simulcast_layers.size(),
                 encoder_config.number_of_streams);
 
-  const absl::optional<webrtc::DataRate> experimental_min_bitrate =
+  const std::optional<webrtc::DataRate> experimental_min_bitrate =
       GetExperimentalMinVideoBitrate(trials, encoder_config.codec_type);
 
   bool is_simulcast = (encoder_config.number_of_streams > 1);
@@ -306,7 +306,7 @@
     int width,
     int height,
     const webrtc::VideoEncoderConfig& encoder_config,
-    const absl::optional<webrtc::DataRate>& experimental_min_bitrate) const {
+    const std::optional<webrtc::DataRate>& experimental_min_bitrate) const {
   bool is_screencast = encoder_config.content_type ==
                        webrtc::VideoEncoderConfig::ContentType::kScreen;
 
@@ -316,7 +316,7 @@
   // - `encoder_config.max_bitrate_bps` comes from SDP; "b=AS" or conditionally
   //   "x-google-max-bitrate".
   // If `api_max_bitrate_bps` has a value then it is positive.
-  absl::optional<int> api_max_bitrate_bps;
+  std::optional<int> api_max_bitrate_bps;
   if (encoder_config.simulcast_layers[0].max_bitrate_bps > 0) {
     api_max_bitrate_bps = encoder_config.simulcast_layers[0].max_bitrate_bps;
   }
@@ -450,7 +450,7 @@
     int width,
     int height,
     const webrtc::VideoEncoderConfig& encoder_config,
-    const absl::optional<webrtc::DataRate>& experimental_min_bitrate) const {
+    const std::optional<webrtc::DataRate>& experimental_min_bitrate) const {
   std::vector<webrtc::Resolution> resolutions =
       GetStreamResolutions(trials, width, height, encoder_config);
 
@@ -475,7 +475,7 @@
   VideoAdapter adapter(encoder_info_requested_resolution_alignment_);
   adapter.OnOutputFormatRequest(requested_resolution.ToPair(),
                                 requested_resolution.PixelCount(),
-                                absl::nullopt);
+                                std::nullopt);
   if (restrictions_) {
     rtc::VideoSinkWants wants;
     wants.is_active = true;
diff --git a/video/config/encoder_stream_factory.h b/video/config/encoder_stream_factory.h
index 7792a81..3d0705e 100644
--- a/video/config/encoder_stream_factory.h
+++ b/video/config/encoder_stream_factory.h
@@ -25,8 +25,8 @@
     : public webrtc::VideoEncoderConfig::VideoStreamFactoryInterface {
  public:
   EncoderStreamFactory(const webrtc::VideoEncoder::EncoderInfo& encoder_info,
-                       absl::optional<webrtc::VideoSourceRestrictions>
-                           restrictions = absl::nullopt);
+                       std::optional<webrtc::VideoSourceRestrictions>
+                           restrictions = std::nullopt);
 
   std::vector<webrtc::VideoStream> CreateEncoderStreams(
       const webrtc::FieldTrialsView& trials,
@@ -39,7 +39,7 @@
       int width,
       int height,
       const webrtc::VideoEncoderConfig& encoder_config,
-      const absl::optional<webrtc::DataRate>& experimental_min_bitrate) const;
+      const std::optional<webrtc::DataRate>& experimental_min_bitrate) const;
 
   std::vector<webrtc::VideoStream>
   CreateSimulcastOrConferenceModeScreenshareStreams(
@@ -47,7 +47,7 @@
       int width,
       int height,
       const webrtc::VideoEncoderConfig& encoder_config,
-      const absl::optional<webrtc::DataRate>& experimental_min_bitrate) const;
+      const std::optional<webrtc::DataRate>& experimental_min_bitrate) const;
 
   webrtc::Resolution GetLayerResolutionFromRequestedResolution(
       int in_frame_width,
@@ -61,7 +61,7 @@
       const webrtc::VideoEncoderConfig& encoder_config) const;
 
   const int encoder_info_requested_resolution_alignment_;
-  const absl::optional<webrtc::VideoSourceRestrictions> restrictions_;
+  const std::optional<webrtc::VideoSourceRestrictions> restrictions_;
 };
 
 }  // namespace cricket
diff --git a/video/config/encoder_stream_factory_unittest.cc b/video/config/encoder_stream_factory_unittest.cc
index b20adb5..aa33367 100644
--- a/video/config/encoder_stream_factory_unittest.cc
+++ b/video/config/encoder_stream_factory_unittest.cc
@@ -69,7 +69,7 @@
     const FieldTrialsView& field_trials,
     const Resolution& resolution,
     const VideoEncoderConfig& encoder_config,
-    absl::optional<VideoSourceRestrictions> restrictions = absl::nullopt) {
+    std::optional<VideoSourceRestrictions> restrictions = std::nullopt) {
   VideoEncoder::EncoderInfo encoder_info;
   auto factory =
       rtc::make_ref_counted<EncoderStreamFactory>(encoder_info, restrictions);
@@ -99,8 +99,8 @@
   ExplicitKeyValueConfig field_trials("");
   VideoSourceRestrictions restrictions(
       /* max_pixels_per_frame= */ (320 * 320),
-      /* target_pixels_per_frame= */ absl::nullopt,
-      /* max_frame_rate= */ absl::nullopt);
+      /* target_pixels_per_frame= */ std::nullopt,
+      /* max_frame_rate= */ std::nullopt);
   VideoEncoderConfig encoder_config;
   encoder_config.number_of_streams = 1;
   encoder_config.simulcast_layers.resize(1);
diff --git a/video/config/simulcast.cc b/video/config/simulcast.cc
index a655c2e..08246ac 100644
--- a/video/config/simulcast.cc
+++ b/video/config/simulcast.cc
@@ -14,11 +14,11 @@
 #include <stdio.h>
 
 #include <algorithm>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/strings/match.h"
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/video/video_codec_constants.h"
 #include "media/base/media_constants.h"
@@ -198,7 +198,7 @@
 SimulcastFormat InterpolateSimulcastFormat(
     int width,
     int height,
-    absl::optional<double> max_roundup_rate,
+    std::optional<double> max_roundup_rate,
     bool enable_lowres_bitrate_interpolation,
     webrtc::VideoCodecType codec) {
   const auto formats =
@@ -247,7 +247,7 @@
     layers[s].num_temporal_layers = num_temporal_layers;
 
     SimulcastFormat interpolated_format = InterpolateSimulcastFormat(
-        layers[s].width, layers[s].height, /*max_roundup_rate=*/absl::nullopt,
+        layers[s].width, layers[s].height, /*max_roundup_rate=*/std::nullopt,
         enable_lowres_bitrate_interpolation, codec);
 
     layers[s].max_bitrate_bps = interpolated_format.max_bitrate.bps();
diff --git a/video/config/video_encoder_config.cc b/video/config/video_encoder_config.cc
index c3e81ec..24b8f2a 100644
--- a/video/config/video_encoder_config.cc
+++ b/video/config/video_encoder_config.cc
@@ -24,7 +24,7 @@
       max_bitrate_bps(-1),
       scale_resolution_down_by(-1.),
       max_qp(-1),
-      num_temporal_layers(absl::nullopt),
+      num_temporal_layers(std::nullopt),
       active(true) {}
 VideoStream::VideoStream(const VideoStream& other) = default;
 
diff --git a/video/config/video_encoder_config.h b/video/config/video_encoder_config.h
index 3f8f286..bd05ab0 100644
--- a/video/config/video_encoder_config.h
+++ b/video/config/video_encoder_config.h
@@ -13,10 +13,10 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/scoped_refptr.h"
 #include "api/video/resolution.h"
@@ -62,13 +62,13 @@
   // (meaning that this field _must_ be set), and for signaling the app-level
   // encoder settings (meaning that the field _may_ be set). We should separate
   // this and remove this optional instead.
-  absl::optional<size_t> num_temporal_layers;
+  std::optional<size_t> num_temporal_layers;
 
   // The priority of this stream, to be used when allocating resources
   // between multiple streams.
-  absl::optional<double> bitrate_priority;
+  std::optional<double> bitrate_priority;
 
-  absl::optional<ScalabilityMode> scalability_mode;
+  std::optional<ScalabilityMode> scalability_mode;
 
   // If this stream is enabled by the user, or not.
   bool active;
@@ -82,7 +82,7 @@
   // which can be lower than requested_resolution,
   // e.g. if source only provides lower resolution or
   // if resource adaptation is active.
-  absl::optional<Resolution> requested_resolution;
+  std::optional<Resolution> requested_resolution;
 };
 
 class VideoEncoderConfig {
@@ -90,7 +90,7 @@
   // These are reference counted to permit copying VideoEncoderConfig and be
   // kept alive until all encoder_specific_settings go out of scope.
   // TODO(kthelgason): Consider removing the need for copying VideoEncoderConfig
-  // and use absl::optional for encoder_specific_settings instead.
+  // and use std::optional for encoder_specific_settings instead.
   class EncoderSpecificSettings : public RefCountInterface {
    public:
     // TODO(pbos): Remove FillEncoderSpecificSettings as soon as VideoCodec is
diff --git a/video/corruption_detection/BUILD.gn b/video/corruption_detection/BUILD.gn
index 4e66857..336e896 100644
--- a/video/corruption_detection/BUILD.gn
+++ b/video/corruption_detection/BUILD.gn
@@ -25,7 +25,6 @@
     "../../modules/video_coding:video_coding_utility",
     "../../rtc_base:logging",
     "//third_party/abseil-cpp/absl/algorithm:container",
-    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -53,7 +52,6 @@
     "../../api/video:video_frame",
     "../../rtc_base:checks",
     "../../rtc_base:logging",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -76,7 +74,6 @@
       "../../api/video:video_frame",
       "../../api/video:video_frame_type",
       "../../test:test_support",
-      "//third_party/abseil-cpp/absl/types:optional",
       "//third_party/abseil-cpp/absl/types:variant",
     ]
   }
diff --git a/video/corruption_detection/frame_instrumentation_generator.cc b/video/corruption_detection/frame_instrumentation_generator.cc
index ee8b492..d0e6596 100644
--- a/video/corruption_detection/frame_instrumentation_generator.cc
+++ b/video/corruption_detection/frame_instrumentation_generator.cc
@@ -13,10 +13,10 @@
 #include <algorithm>
 #include <cstdint>
 #include <iterator>
+#include <optional>
 #include <vector>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/scoped_refptr.h"
 #include "api/video/encoded_image.h"
@@ -34,7 +34,7 @@
 namespace webrtc {
 namespace {
 
-absl::optional<FilterSettings> GetCorruptionFilterSettings(
+std::optional<FilterSettings> GetCorruptionFilterSettings(
     const EncodedImage& encoded_image,
     VideoCodecType video_codec_type,
     int layer_id) {
@@ -51,13 +51,13 @@
 
   int qp = encoded_image.qp_;
   if (qp == -1) {
-    absl::optional<uint32_t> parsed_qp = QpParser().Parse(
+    std::optional<uint32_t> parsed_qp = QpParser().Parse(
         video_codec_type, layer_id, encoded_image.data(), encoded_image.size());
     if (!parsed_qp.has_value()) {
       RTC_LOG(LS_VERBOSE) << "Missing QP for "
                           << CodecTypeToPayloadString(video_codec_type)
                           << " layer " << layer_id << ".";
-      return absl::nullopt;
+      return std::nullopt;
     }
     qp = *parsed_qp;
   }
@@ -75,7 +75,7 @@
   captured_frames_.push(frame);
 }
 
-absl::optional<
+std::optional<
     absl::variant<FrameInstrumentationSyncData, FrameInstrumentationData>>
 FrameInstrumentationGenerator::OnEncodedImage(
     const EncodedImage& encoded_image) {
@@ -89,7 +89,7 @@
       captured_frames_.front().rtp_timestamp() != rtp_timestamp_encoded_image) {
     RTC_LOG(LS_VERBOSE) << "No captured frames for RTC timestamp "
                         << rtp_timestamp_encoded_image << ".";
-    return absl::nullopt;
+    return std::nullopt;
   }
   VideoFrame captured_frame = captured_frames_.front();
 
@@ -116,7 +116,7 @@
   } else if (contexts_.find(layer_id) == contexts_.end()) {
     RTC_LOG(LS_INFO) << "The first frame of a spatial or simulcast layer is "
                         "not a key frame.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   int sequence_index = contexts_[layer_id].frame_sampler.GetCurrentIndex();
@@ -128,16 +128,16 @@
               /*sample_size=*/13);
   if (sample_coordinates.empty()) {
     if (!is_key_frame) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return FrameInstrumentationSyncData{.sequence_index = sequence_index,
                                         .is_key_frame = true};
   }
 
-  absl::optional<FilterSettings> filter_settings =
+  std::optional<FilterSettings> filter_settings =
       GetCorruptionFilterSettings(encoded_image, video_codec_type_, layer_id);
   if (!filter_settings.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   scoped_refptr<I420BufferInterface> captured_frame_buffer_as_i420 =
@@ -147,7 +147,7 @@
                       << VideoFrameBufferTypeToString(
                              captured_frame.video_frame_buffer()->type())
                       << " image to I420.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   FrameInstrumentationData data = {
diff --git a/video/corruption_detection/frame_instrumentation_generator.h b/video/corruption_detection/frame_instrumentation_generator.h
index a2004e5..2e0f909 100644
--- a/video/corruption_detection/frame_instrumentation_generator.h
+++ b/video/corruption_detection/frame_instrumentation_generator.h
@@ -13,10 +13,10 @@
 
 #include <cstdint>
 #include <map>
+#include <optional>
 #include <queue>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/video/encoded_image.h"
 #include "api/video/video_codec_type.h"
@@ -52,7 +52,7 @@
   ~FrameInstrumentationGenerator() = default;
 
   void OnCapturedFrame(VideoFrame frame);
-  absl::optional<
+  std::optional<
       absl::variant<FrameInstrumentationSyncData, FrameInstrumentationData>>
   OnEncodedImage(const EncodedImage& encoded_image);
 
diff --git a/video/corruption_detection/frame_instrumentation_generator_unittest.cc b/video/corruption_detection/frame_instrumentation_generator_unittest.cc
index 796f929..4af4af8 100644
--- a/video/corruption_detection/frame_instrumentation_generator_unittest.cc
+++ b/video/corruption_detection/frame_instrumentation_generator_unittest.cc
@@ -11,9 +11,9 @@
 #include "video/corruption_detection/frame_instrumentation_generator.h"
 
 #include <cstdint>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/scoped_refptr.h"
 #include "api/video/encoded_image.h"
@@ -142,7 +142,7 @@
   encoded_image._encodedHeight = kDefaultScaledHeight;
 
   generator.OnCapturedFrame(frame);
-  absl::optional<
+  std::optional<
       absl::variant<FrameInstrumentationSyncData, FrameInstrumentationData>>
       data = generator.OnEncodedImage(encoded_image);
 
@@ -182,7 +182,7 @@
   encoded_image._encodedHeight = kDefaultScaledHeight;
 
   generator.OnCapturedFrame(frame);
-  absl::optional<
+  std::optional<
       absl::variant<FrameInstrumentationSyncData, FrameInstrumentationData>>
       data = generator.OnEncodedImage(encoded_image);
 
@@ -224,7 +224,7 @@
 
   generator.OnCapturedFrame(frame);
   generator.OnEncodedImage(encoded_image1);
-  absl::optional<
+  std::optional<
       absl::variant<FrameInstrumentationSyncData, FrameInstrumentationData>>
       data = generator.OnEncodedImage(encoded_image2);
 
@@ -307,11 +307,11 @@
     generator.OnCapturedFrame(frame1);
     generator.OnCapturedFrame(frame2);
 
-    absl::optional<
+    std::optional<
         absl::variant<FrameInstrumentationSyncData, FrameInstrumentationData>>
         data1 = generator.OnEncodedImage(encoded_image1);
 
-    absl::optional<
+    std::optional<
         absl::variant<FrameInstrumentationSyncData, FrameInstrumentationData>>
         data2 = generator.OnEncodedImage(encoded_image2);
 
@@ -357,11 +357,11 @@
 
     generator.OnCapturedFrame(frame);
 
-    absl::optional<
+    std::optional<
         absl::variant<FrameInstrumentationSyncData, FrameInstrumentationData>>
         data1 = generator.OnEncodedImage(encoded_image1);
 
-    absl::optional<
+    std::optional<
         absl::variant<FrameInstrumentationSyncData, FrameInstrumentationData>>
         data2 = generator.OnEncodedImage(encoded_image2);
 
diff --git a/video/corruption_detection/halton_frame_sampler.h b/video/corruption_detection/halton_frame_sampler.h
index 877bc79..9908c56 100644
--- a/video/corruption_detection/halton_frame_sampler.h
+++ b/video/corruption_detection/halton_frame_sampler.h
@@ -12,9 +12,9 @@
 #define VIDEO_CORRUPTION_DETECTION_HALTON_FRAME_SAMPLER_H_
 
 #include <cstdint>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
 #include "api/video/video_frame_buffer.h"
 #include "video/corruption_detection/halton_sequence.h"
@@ -56,7 +56,7 @@
   Coordinates GetNextSampleCoordinates();
 
   HaltonSequence coordinate_sampler_prng_;
-  absl::optional<uint32_t> rtp_timestamp_last_frame_sampled_;
+  std::optional<uint32_t> rtp_timestamp_last_frame_sampled_;
   int frames_sampled_ = 0;
   int frames_until_next_sample_ = 0;
 };
diff --git a/video/decode_synchronizer.cc b/video/decode_synchronizer.cc
index 32702c2..94c4902 100644
--- a/video/decode_synchronizer.cc
+++ b/video/decode_synchronizer.cc
@@ -58,11 +58,11 @@
   RTC_DCHECK(stopped_);
 }
 
-absl::optional<uint32_t>
+std::optional<uint32_t>
 DecodeSynchronizer::SynchronizedFrameDecodeScheduler::ScheduledRtpTimestamp() {
   return next_frame_.has_value()
-             ? absl::make_optional(next_frame_->rtp_timestamp())
-             : absl::nullopt;
+             ? std::make_optional(next_frame_->rtp_timestamp())
+             : std::nullopt;
 }
 
 DecodeSynchronizer::ScheduledFrame
diff --git a/video/decode_synchronizer.h b/video/decode_synchronizer.h
index 1718186..d441fa0 100644
--- a/video/decode_synchronizer.h
+++ b/video/decode_synchronizer.h
@@ -15,10 +15,10 @@
 
 #include <functional>
 #include <memory>
+#include <optional>
 #include <set>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/metronome/metronome.h"
 #include "api/sequence_checker.h"
 #include "api/task_queue/task_queue_base.h"
@@ -103,7 +103,7 @@
     Timestamp LatestDecodeTime();
 
     // FrameDecodeScheduler implementation.
-    absl::optional<uint32_t> ScheduledRtpTimestamp() override;
+    std::optional<uint32_t> ScheduledRtpTimestamp() override;
     void ScheduleFrame(uint32_t rtp,
                        FrameDecodeTiming::FrameSchedule schedule,
                        FrameReleaseCallback cb) override;
@@ -112,7 +112,7 @@
 
    private:
     DecodeSynchronizer* sync_;
-    absl::optional<ScheduledFrame> next_frame_;
+    std::optional<ScheduledFrame> next_frame_;
     bool stopped_ = false;
   };
 
diff --git a/video/encoder_bitrate_adjuster.cc b/video/encoder_bitrate_adjuster.cc
index 8743099..c74ac49 100644
--- a/video/encoder_bitrate_adjuster.cc
+++ b/video/encoder_bitrate_adjuster.cc
@@ -193,11 +193,11 @@
       layer_info.media_utilization_factor = 0.0;
       for (size_t ti = 0; ti < active_tls[si]; ++ti) {
         RTC_DCHECK(overshoot_detectors_[si][ti]);
-        const absl::optional<double> ti_link_utilization_factor =
+        const std::optional<double> ti_link_utilization_factor =
             overshoot_detectors_[si][ti]->GetNetworkRateUtilizationFactor(
                 now.ms());
 
-        const absl::optional<double> ti_media_utilization_factor =
+        const std::optional<double> ti_media_utilization_factor =
             overshoot_detectors_[si][ti]->GetMediaRateUtilizationFactor(
                 now.ms());
         if (!ti_link_utilization_factor || !ti_media_utilization_factor) {
diff --git a/video/encoder_overshoot_detector.cc b/video/encoder_overshoot_detector.cc
index 8446c135..b9697f5 100644
--- a/video/encoder_overshoot_detector.cc
+++ b/video/encoder_overshoot_detector.cc
@@ -136,13 +136,13 @@
   return utilization_factor;
 }
 
-absl::optional<double>
-EncoderOvershootDetector::GetNetworkRateUtilizationFactor(int64_t time_ms) {
+std::optional<double> EncoderOvershootDetector::GetNetworkRateUtilizationFactor(
+    int64_t time_ms) {
   CullOldUpdates(time_ms);
 
   // No data points within window, return.
   if (utilization_factors_.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // TODO(sprang): Consider changing from arithmetic mean to some other
@@ -150,13 +150,13 @@
   return sum_network_utilization_factors_ / utilization_factors_.size();
 }
 
-absl::optional<double> EncoderOvershootDetector::GetMediaRateUtilizationFactor(
+std::optional<double> EncoderOvershootDetector::GetMediaRateUtilizationFactor(
     int64_t time_ms) {
   CullOldUpdates(time_ms);
 
   // No data points within window, return.
   if (utilization_factors_.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return sum_media_utilization_factors_ / utilization_factors_.size();
diff --git a/video/encoder_overshoot_detector.h b/video/encoder_overshoot_detector.h
index 12c4bba..e78b601 100644
--- a/video/encoder_overshoot_detector.h
+++ b/video/encoder_overshoot_detector.h
@@ -12,8 +12,8 @@
 #define VIDEO_ENCODER_OVERSHOOT_DETECTOR_H_
 
 #include <deque>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/units/data_rate.h"
 #include "api/video_codecs/video_codec.h"
 
@@ -34,11 +34,11 @@
   // This utilization factor reaches 1.0 only if the encoder produces encoded
   // frame in such a way that they can be sent onto the network at
   // `target_bitrate` without building growing queues.
-  absl::optional<double> GetNetworkRateUtilizationFactor(int64_t time_ms);
+  std::optional<double> GetNetworkRateUtilizationFactor(int64_t time_ms);
   // This utilization factor is based just on actual encoded frame sizes in
   // relation to ideal sizes. An undershoot may be compensated by an
   // overshoot so that the average over time is close to `target_bitrate`.
-  absl::optional<double> GetMediaRateUtilizationFactor(int64_t time_ms);
+  std::optional<double> GetMediaRateUtilizationFactor(int64_t time_ms);
   void Reset();
 
  private:
diff --git a/video/encoder_overshoot_detector_unittest.cc b/video/encoder_overshoot_detector_unittest.cc
index 27e58ad..95d0fd1 100644
--- a/video/encoder_overshoot_detector_unittest.cc
+++ b/video/encoder_overshoot_detector_unittest.cc
@@ -87,12 +87,12 @@
 
     // At constant utilization, both network and media utilization should be
     // close to expected.
-    const absl::optional<double> network_utilization_factor =
+    const std::optional<double> network_utilization_factor =
         detector_.GetNetworkRateUtilizationFactor(rtc::TimeMillis());
     EXPECT_NEAR(network_utilization_factor.value_or(-1),
                 expected_utilization_factor, allowed_error);
 
-    const absl::optional<double> media_utilization_factor =
+    const std::optional<double> media_utilization_factor =
         detector_.GetMediaRateUtilizationFactor(rtc::TimeMillis());
     EXPECT_NEAR(media_utilization_factor.value_or(-1),
                 expected_utilization_factor, allowed_error);
@@ -189,12 +189,12 @@
   }
 
   // Expect 5% overshoot for network rate, see above.
-  const absl::optional<double> network_utilization_factor =
+  const std::optional<double> network_utilization_factor =
       detector_.GetNetworkRateUtilizationFactor(rtc::TimeMillis());
   EXPECT_NEAR(network_utilization_factor.value_or(-1), 1.05, 0.01);
 
   // Expect media rate to be on average correct.
-  const absl::optional<double> media_utilization_factor =
+  const std::optional<double> media_utilization_factor =
       detector_.GetMediaRateUtilizationFactor(rtc::TimeMillis());
   EXPECT_NEAR(media_utilization_factor.value_or(-1), 1.00, 0.01);
 }
diff --git a/video/encoder_rtcp_feedback.cc b/video/encoder_rtcp_feedback.cc
index d9d9aea..42827e2 100644
--- a/video/encoder_rtcp_feedback.cc
+++ b/video/encoder_rtcp_feedback.cc
@@ -11,9 +11,9 @@
 #include "video/encoder_rtcp_feedback.h"
 
 #include <algorithm>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/video_codecs/video_encoder.h"
 #include "rtc_base/checks.h"
@@ -124,7 +124,7 @@
     loss_notification.dependencies_of_last_received_decodable =
         decodability_flag;
     loss_notification.last_received_decodable =
-        !decodability_flag ? absl::make_optional(false) : absl::nullopt;
+        !decodability_flag ? std::make_optional(false) : std::nullopt;
   } else if (!last_received.is_first && last_received.is_last) {
     if (decodability_flag) {
       // The frame has been received in full, and found to be decodable.
@@ -136,7 +136,7 @@
       // It is impossible to tell whether some dependencies were undecodable,
       // or whether the frame was unassemblable, but in either case, the frame
       // itself was undecodable.
-      loss_notification.dependencies_of_last_received_decodable = absl::nullopt;
+      loss_notification.dependencies_of_last_received_decodable = std::nullopt;
       loss_notification.last_received_decodable = false;
     }
   } else {  // !last_received.is_first && !last_received.is_last
@@ -146,12 +146,12 @@
       // (Messages of this type are not sent by WebRTC at the moment, but are
       // theoretically possible, for example for serving as acks.)
       loss_notification.dependencies_of_last_received_decodable = true;
-      loss_notification.last_received_decodable = absl::nullopt;
+      loss_notification.last_received_decodable = std::nullopt;
     } else {
       // It is impossible to tell whether some dependencies were undecodable,
       // or whether the frame was unassemblable, but in either case, the frame
       // itself was undecodable.
-      loss_notification.dependencies_of_last_received_decodable = absl::nullopt;
+      loss_notification.dependencies_of_last_received_decodable = std::nullopt;
       loss_notification.last_received_decodable = false;
     }
   }
diff --git a/video/end_to_end_tests/call_operation_tests.cc b/video/end_to_end_tests/call_operation_tests.cc
index fe965f2..f99565d 100644
--- a/video/end_to_end_tests/call_operation_tests.cc
+++ b/video/end_to_end_tests/call_operation_tests.cc
@@ -116,8 +116,8 @@
     // Create frames that are smaller than the send width/height, this is
     // done to check that the callbacks are done after processing video.
     std::unique_ptr<test::FrameGeneratorInterface> frame_generator(
-        test::CreateSquareFrameGenerator(kWidth, kHeight, absl::nullopt,
-                                         absl::nullopt));
+        test::CreateSquareFrameGenerator(kWidth, kHeight, std::nullopt,
+                                         std::nullopt));
     GetVideoSendStream()->SetSource(&frame_forwarder,
                                     DegradationPreference::MAINTAIN_FRAMERATE);
 
@@ -175,7 +175,7 @@
 
     frame_generator = test::CreateSquareFrameGenerator(
         test::VideoTestConstants::kDefaultWidth,
-        test::VideoTestConstants::kDefaultHeight, absl::nullopt, absl::nullopt);
+        test::VideoTestConstants::kDefaultHeight, std::nullopt, std::nullopt);
     GetVideoSendStream()->SetSource(&frame_forwarder,
                                     DegradationPreference::MAINTAIN_FRAMERATE);
     test::FrameGeneratorInterface::VideoFrameData frame_data =
diff --git a/video/end_to_end_tests/codec_tests.cc b/video/end_to_end_tests/codec_tests.cc
index e2ceb5e..6460cda 100644
--- a/video/end_to_end_tests/codec_tests.cc
+++ b/video/end_to_end_tests/codec_tests.cc
@@ -9,8 +9,8 @@
  */
 
 #include <memory>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/test/video/function_video_encoder_factory.h"
 #include "api/video/color_space.h"
@@ -52,7 +52,7 @@
  public:
   CodecObserver(int no_frames_to_wait_for,
                 VideoRotation rotation_to_test,
-                absl::optional<ColorSpace> color_space_to_test,
+                std::optional<ColorSpace> color_space_to_test,
                 const std::string& payload_name,
                 VideoEncoderFactory* encoder_factory,
                 VideoDecoderFactory* decoder_factory)
@@ -98,8 +98,8 @@
     if (expected_color_space_) {
       EXPECT_EQ(expected_color_space_,
                 video_frame.color_space()
-                    ? absl::make_optional(*video_frame.color_space())
-                    : absl::nullopt);
+                    ? std::make_optional(*video_frame.color_space())
+                    : std::nullopt);
     }
     if (++frame_counter_ == no_frames_to_wait_for_)
       observation_complete_.Set();
@@ -114,7 +114,7 @@
  private:
   int no_frames_to_wait_for_;
   VideoRotation expected_rotation_;
-  absl::optional<ColorSpace> expected_color_space_;
+  std::optional<ColorSpace> expected_color_space_;
   std::string payload_name_;
   VideoEncoderFactory* encoder_factory_;
   VideoDecoderFactory* decoder_factory_;
@@ -130,8 +130,8 @@
       [](const Environment& env, const SdpVideoFormat& format) {
         return CreateVp8Decoder(env);
       });
-  CodecObserver test(5, kVideoRotation_0, absl::nullopt, "VP8",
-                     &encoder_factory, &decoder_factory);
+  CodecObserver test(5, kVideoRotation_0, std::nullopt, "VP8", &encoder_factory,
+                     &decoder_factory);
   RunBaseTest(&test);
 }
 
@@ -144,7 +144,7 @@
       [](const Environment& env, const SdpVideoFormat& format) {
         return CreateVp8Decoder(env);
       });
-  CodecObserver test(5, kVideoRotation_90, absl::nullopt, "VP8",
+  CodecObserver test(5, kVideoRotation_90, std::nullopt, "VP8",
                      &encoder_factory, &decoder_factory);
   RunBaseTest(&test);
 }
@@ -157,7 +157,7 @@
       });
   test::FunctionVideoDecoderFactory decoder_factory(
       []() { return VP9Decoder::Create(); });
-  CodecObserver test(500, kVideoRotation_0, absl::nullopt, "VP9",
+  CodecObserver test(500, kVideoRotation_0, std::nullopt, "VP9",
                      &encoder_factory, &decoder_factory);
   RunBaseTest(&test);
 }
@@ -169,7 +169,7 @@
       });
   test::FunctionVideoDecoderFactory decoder_factory(
       []() { return VP9Decoder::Create(); });
-  CodecObserver test(5, kVideoRotation_90, absl::nullopt, "VP9",
+  CodecObserver test(5, kVideoRotation_90, std::nullopt, "VP9",
                      &encoder_factory, &decoder_factory);
   RunBaseTest(&test);
 }
@@ -229,7 +229,7 @@
       });
   test::FunctionVideoDecoderFactory decoder_factory(
       []() { return H264Decoder::Create(); });
-  CodecObserver test(500, kVideoRotation_0, absl::nullopt, "H264",
+  CodecObserver test(500, kVideoRotation_0, std::nullopt, "H264",
                      &encoder_factory, &decoder_factory);
   RunBaseTest(&test);
 }
@@ -241,7 +241,7 @@
       });
   test::FunctionVideoDecoderFactory decoder_factory(
       []() { return H264Decoder::Create(); });
-  CodecObserver test(5, kVideoRotation_90, absl::nullopt, "H264",
+  CodecObserver test(5, kVideoRotation_90, std::nullopt, "H264",
                      &encoder_factory, &decoder_factory);
   RunBaseTest(&test);
 }
@@ -255,7 +255,7 @@
       });
   test::FunctionVideoDecoderFactory decoder_factory(
       []() { return H264Decoder::Create(); });
-  CodecObserver test(500, kVideoRotation_0, absl::nullopt, "H264",
+  CodecObserver test(500, kVideoRotation_0, std::nullopt, "H264",
                      &encoder_factory, &decoder_factory);
   RunBaseTest(&test);
 }
@@ -269,7 +269,7 @@
       });
   test::FunctionVideoDecoderFactory decoder_factory(
       []() { return H264Decoder::Create(); });
-  CodecObserver test(500, kVideoRotation_0, absl::nullopt, "H264",
+  CodecObserver test(500, kVideoRotation_0, std::nullopt, "H264",
                      &encoder_factory, &decoder_factory);
   RunBaseTest(&test);
 }
diff --git a/video/end_to_end_tests/extended_reports_tests.cc b/video/end_to_end_tests/extended_reports_tests.cc
index 9ce5311..4e6cf0e 100644
--- a/video/end_to_end_tests/extended_reports_tests.cc
+++ b/video/end_to_end_tests/extended_reports_tests.cc
@@ -12,11 +12,11 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/rtp_headers.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/test/simulated_network.h"
diff --git a/video/end_to_end_tests/histogram_tests.cc b/video/end_to_end_tests/histogram_tests.cc
index d12242f..1d27f97 100644
--- a/video/end_to_end_tests/histogram_tests.cc
+++ b/video/end_to_end_tests/histogram_tests.cc
@@ -8,7 +8,8 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/test/video/function_video_encoder_factory.h"
 #include "modules/video_coding/codecs/vp8/include/vp8.h"
 #include "rtc_base/synchronization/mutex.h"
@@ -151,7 +152,7 @@
     const bool use_fec_;
     const bool screenshare_;
     test::FunctionVideoEncoderFactory encoder_factory_;
-    absl::optional<int64_t> start_runtime_ms_;
+    std::optional<int64_t> start_runtime_ms_;
     int num_frames_received_ RTC_GUARDED_BY(&mutex_);
   } test(use_rtx, use_fec, screenshare);
 
diff --git a/video/end_to_end_tests/multi_codec_receive_tests.cc b/video/end_to_end_tests/multi_codec_receive_tests.cc
index fe223af..e9c8bc4 100644
--- a/video/end_to_end_tests/multi_codec_receive_tests.cc
+++ b/video/end_to_end_tests/multi_codec_receive_tests.cc
@@ -120,8 +120,8 @@
   }
 
   Mutex mutex_;
-  absl::optional<uint32_t> last_timestamp_;  // Only accessed from pacer thread.
-  absl::optional<uint8_t> expected_payload_type_ RTC_GUARDED_BY(mutex_);
+  std::optional<uint32_t> last_timestamp_;  // Only accessed from pacer thread.
+  std::optional<uint8_t> expected_payload_type_ RTC_GUARDED_BY(mutex_);
   int num_sent_frames_ RTC_GUARDED_BY(mutex_) = 0;
   int num_rendered_frames_ RTC_GUARDED_BY(mutex_) = 0;
   std::vector<uint32_t> sent_timestamps_ RTC_GUARDED_BY(mutex_);
diff --git a/video/end_to_end_tests/multi_stream_tester.cc b/video/end_to_end_tests/multi_stream_tester.cc
index abd3238..7d82085 100644
--- a/video/end_to_end_tests/multi_stream_tester.cc
+++ b/video/end_to_end_tests/multi_stream_tester.cc
@@ -115,8 +115,8 @@
 
       auto* frame_generator = new test::FrameGeneratorCapturer(
           &env.clock(),
-          test::CreateSquareFrameGenerator(width, height, absl::nullopt,
-                                           absl::nullopt),
+          test::CreateSquareFrameGenerator(width, height, std::nullopt,
+                                           std::nullopt),
           30, env.task_queue_factory());
       frame_generators[i] = frame_generator;
       send_streams[i]->SetSource(frame_generator,
diff --git a/video/end_to_end_tests/resolution_bitrate_limits_tests.cc b/video/end_to_end_tests/resolution_bitrate_limits_tests.cc
index 7949376..06eb71e 100644
--- a/video/end_to_end_tests/resolution_bitrate_limits_tests.cc
+++ b/video/end_to_end_tests/resolution_bitrate_limits_tests.cc
@@ -103,13 +103,13 @@
                        public test::FakeEncoder {
  public:
   struct Bitrate {
-    const absl::optional<DataRate> min;
-    const absl::optional<DataRate> max;
+    const std::optional<DataRate> min;
+    const std::optional<DataRate> max;
   };
   struct TestConfig {
     const bool active;
     const Bitrate bitrate;
-    const absl::optional<ScalabilityMode> scalability_mode;
+    const std::optional<ScalabilityMode> scalability_mode;
   };
   struct Expectation {
     const uint32_t pixels = 0;
@@ -252,7 +252,7 @@
         .scalability_mode = ScalabilityMode::kL2T1}},
       // Expectations:
       {{.pixels = 1280 * 720,
-        .ne_bitrate = {absl::nullopt, DataRate::KilobitsPerSec(3000)}}});
+        .ne_bitrate = {std::nullopt, DataRate::KilobitsPerSec(3000)}}});
   RunBaseTest(&test);
 }
 TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest,
@@ -369,7 +369,7 @@
 }
 
 TEST_P(ResolutionBitrateLimitsTest, DefaultLimitsAppliedMiddleActive) {
-  const absl::optional<VideoEncoder::ResolutionBitrateLimits>
+  const std::optional<VideoEncoder::ResolutionBitrateLimits>
       kDefaultSinglecastLimits360p =
           EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
               PayloadStringToCodecType(payload_name_), 640 * 360);
@@ -388,7 +388,7 @@
 
 TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest,
        DefaultLimitsAppliedForOneSpatialLayer) {
-  const absl::optional<VideoEncoder::ResolutionBitrateLimits>
+  const std::optional<VideoEncoder::ResolutionBitrateLimits>
       kDefaultSinglecastLimits720p =
           EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
               PayloadStringToCodecType("VP9"), 1280 * 720);
diff --git a/video/end_to_end_tests/retransmission_tests.cc b/video/end_to_end_tests/retransmission_tests.cc
index f74af24..afcd8b9 100644
--- a/video/end_to_end_tests/retransmission_tests.cc
+++ b/video/end_to_end_tests/retransmission_tests.cc
@@ -191,7 +191,7 @@
     uint32_t local_ssrc_;
     uint32_t remote_ssrc_;
     Transport* receive_transport_;
-    absl::optional<uint16_t> sequence_number_to_retransmit_;
+    std::optional<uint16_t> sequence_number_to_retransmit_;
   } test;
 
   RunBaseTest(&test);
diff --git a/video/end_to_end_tests/rtp_rtcp_tests.cc b/video/end_to_end_tests/rtp_rtcp_tests.cc
index 00a46dd..7ea0ed0 100644
--- a/video/end_to_end_tests/rtp_rtcp_tests.cc
+++ b/video/end_to_end_tests/rtp_rtcp_tests.cc
@@ -456,9 +456,9 @@
       return SEND_PACKET;
     }
 
-    absl::optional<uint16_t> last_observed_sequence_number_
+    std::optional<uint16_t> last_observed_sequence_number_
         RTC_GUARDED_BY(mutex_);
-    absl::optional<uint32_t> last_observed_timestamp_ RTC_GUARDED_BY(mutex_);
+    std::optional<uint32_t> last_observed_timestamp_ RTC_GUARDED_BY(mutex_);
     size_t num_flexfec_packets_sent_ RTC_GUARDED_BY(mutex_);
     Mutex mutex_;
   } observer;
diff --git a/video/end_to_end_tests/stats_tests.cc b/video/end_to_end_tests/stats_tests.cc
index 226f5fc..4d14fa4 100644
--- a/video/end_to_end_tests/stats_tests.cc
+++ b/video/end_to_end_tests/stats_tests.cc
@@ -9,9 +9,9 @@
  */
 
 #include <memory>
+#include <optional>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/test/simulated_network.h"
 #include "api/test/video/function_video_encoder_factory.h"
@@ -691,7 +691,7 @@
     bool dropped_rtp_packet_requested_ RTC_GUARDED_BY(&mutex_) = false;
     std::vector<VideoReceiveStreamInterface*> receive_streams_;
     VideoSendStream* send_stream_ = nullptr;
-    absl::optional<int64_t> start_runtime_ms_;
+    std::optional<int64_t> start_runtime_ms_;
     TaskQueueBase* const task_queue_;
     rtc::scoped_refptr<PendingTaskSafetyFlag> task_safety_flag_ =
         PendingTaskSafetyFlag::CreateDetached();
diff --git a/video/frame_cadence_adapter.cc b/video/frame_cadence_adapter.cc
index 8a7852b..21dec7f 100644
--- a/video/frame_cadence_adapter.cc
+++ b/video/frame_cadence_adapter.cc
@@ -56,7 +56,7 @@
                        const VideoFrame& frame) = 0;
 
   // Returns the currently estimated input framerate.
-  virtual absl::optional<uint32_t> GetInputFrameRateFps() = 0;
+  virtual std::optional<uint32_t> GetInputFrameRateFps() = 0;
 
   // Updates the frame rate.
   virtual void UpdateFrameRate(Timestamp frame_timestamp) = 0;
@@ -79,7 +79,7 @@
     callback_->OnFrame(post_time, queue_overload, frame);
   }
 
-  absl::optional<uint32_t> GetInputFrameRateFps() override {
+  std::optional<uint32_t> GetInputFrameRateFps() override {
     RTC_DCHECK_RUN_ON(&sequence_checker_);
     return last_frame_rate_;
   }
@@ -92,7 +92,7 @@
   }
 
  private:
-  absl::optional<uint64_t> last_frame_rate_;
+  std::optional<uint64_t> last_frame_rate_;
   FrameCadenceAdapterInterface::Callback* const callback_;
   RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
   // Input frame rate statistics for use when not in zero-hertz mode.
@@ -127,7 +127,7 @@
   void OnFrame(Timestamp post_time,
                bool queue_overload,
                const VideoFrame& frame) override;
-  absl::optional<uint32_t> GetInputFrameRateFps() override;
+  std::optional<uint32_t> GetInputFrameRateFps() override;
   void UpdateFrameRate(Timestamp frame_timestamp) override {}
 
   // Notified on dropped frames.
@@ -139,7 +139,7 @@
 
   // Updates the restrictions of max frame rate for the video source.
   // Always called during construction using latest `restricted_frame_delay_`.
-  void UpdateVideoSourceRestrictions(absl::optional<double> max_frame_rate);
+  void UpdateVideoSourceRestrictions(std::optional<double> max_frame_rate);
 
  private:
   // The tracking state of each spatial layer. Used for determining when to
@@ -147,7 +147,7 @@
   struct SpatialLayerTracker {
     // If unset, the layer is disabled. Otherwise carries the quality
     // convergence status of the layer.
-    absl::optional<bool> quality_converged;
+    std::optional<bool> quality_converged;
   };
   // The state of a scheduled repeat.
   struct ScheduledRepeat {
@@ -201,9 +201,9 @@
   // parameter in the OnFrame callback will be true while
   // `queue_overload_count_` is larger than zero to allow the client to drop
   // frames and thereby mitigate delay buildups.
-  // Repeated frames are sent with `post_time` set to absl::nullopt.
-  void SendFrameNow(absl::optional<Timestamp> post_time,
-                    const VideoFrame& frame) RTC_RUN_ON(sequence_checker_);
+  // Repeated frames are sent with `post_time` set to std::nullopt.
+  void SendFrameNow(std::optional<Timestamp> post_time, const VideoFrame& frame)
+      RTC_RUN_ON(sequence_checker_);
   // Returns the repeat duration depending on if it's an idle repeat or not.
   TimeDelta RepeatDuration(bool idle_repeat) const
       RTC_RUN_ON(sequence_checker_);
@@ -239,7 +239,7 @@
   // for cancelling deferred repeated frame processing happening.
   int current_frame_id_ RTC_GUARDED_BY(sequence_checker_) = 0;
   // Has content when we are repeating frames.
-  absl::optional<ScheduledRepeat> scheduled_repeat_
+  std::optional<ScheduledRepeat> scheduled_repeat_
       RTC_GUARDED_BY(sequence_checker_);
   // Convergent state of each of the configured simulcast layers.
   std::vector<SpatialLayerTracker> layer_trackers_
@@ -250,7 +250,7 @@
       RTC_GUARDED_BY(sequence_checker_);
   // Can be set by UpdateVideoSourceRestrictions when the video source restricts
   // the max frame rate.
-  absl::optional<TimeDelta> restricted_frame_delay_
+  std::optional<TimeDelta> restricted_frame_delay_
       RTC_GUARDED_BY(sequence_checker_);
   // Set in OnSendFrame to reflect how many future frames will be forwarded with
   // the `queue_overload` flag set to true.
@@ -289,7 +289,7 @@
                bool queue_overload,
                const VideoFrame& frame) override;
 
-  absl::optional<uint32_t> GetInputFrameRateFps() override {
+  std::optional<uint32_t> GetInputFrameRateFps() override {
     RTC_DCHECK_RUN_ON(&queue_sequence_checker_);
     return last_frame_rate_;
   }
@@ -323,7 +323,7 @@
   RTC_NO_UNIQUE_ADDRESS SequenceChecker queue_sequence_checker_;
   rtc::scoped_refptr<PendingTaskSafetyFlag> queue_safety_flag_;
   // Input frame rate statistics for use when not in zero-hertz mode.
-  absl::optional<uint64_t> last_frame_rate_
+  std::optional<uint64_t> last_frame_rate_
       RTC_GUARDED_BY(queue_sequence_checker_);
   RateStatistics input_framerate_ RTC_GUARDED_BY(queue_sequence_checker_){
       FrameCadenceAdapterInterface::kFrameRateAveragingWindowSizeMs, 1000};
@@ -354,13 +354,13 @@
   // FrameCadenceAdapterInterface overrides.
   void Initialize(Callback* callback) override;
   void SetZeroHertzModeEnabled(
-      absl::optional<ZeroHertzModeParams> params) override;
-  absl::optional<uint32_t> GetInputFrameRateFps() override;
+      std::optional<ZeroHertzModeParams> params) override;
+  std::optional<uint32_t> GetInputFrameRateFps() override;
   void UpdateLayerQualityConvergence(size_t spatial_index,
                                      bool quality_converged) override;
   void UpdateLayerStatus(size_t spatial_index, bool enabled) override;
   void UpdateVideoSourceRestrictions(
-      absl::optional<double> max_frame_rate) override;
+      std::optional<double> max_frame_rate) override;
   void ProcessKeyFrameRequest() override;
 
   // VideoFrameSink overrides.
@@ -400,17 +400,17 @@
   // calculating input frame rate.
   const bool use_video_frame_timestamp_;
   // Used for verifying that timestamps are monotonically increasing.
-  absl::optional<Timestamp> last_incoming_frame_timestamp_;
+  std::optional<Timestamp> last_incoming_frame_timestamp_;
   bool incoming_frame_timestamp_monotonically_increasing_ = true;
 
   // The three possible modes we're under.
-  absl::optional<PassthroughAdapterMode> passthrough_adapter_;
-  absl::optional<ZeroHertzAdapterMode> zero_hertz_adapter_;
+  std::optional<PassthroughAdapterMode> passthrough_adapter_;
+  std::optional<ZeroHertzAdapterMode> zero_hertz_adapter_;
   // The `vsync_encode_adapter_` must be destroyed on the worker queue since
   // VSync metronome needs to happen on worker thread.
   std::unique_ptr<VSyncEncodeAdapterMode> vsync_encode_adapter_;
   // If set, zero-hertz mode has been enabled.
-  absl::optional<ZeroHertzModeParams> zero_hertz_params_;
+  std::optional<ZeroHertzModeParams> zero_hertz_params_;
   // Cache for the current adapter mode.
   AdapterMode* current_adapter_mode_ = nullptr;
 
@@ -419,20 +419,20 @@
   TaskQueueBase* const worker_queue_;
 
   // Timestamp for statistics reporting.
-  absl::optional<Timestamp> zero_hertz_adapter_created_timestamp_
+  std::optional<Timestamp> zero_hertz_adapter_created_timestamp_
       RTC_GUARDED_BY(queue_);
 
   // Set up during Initialize.
   Callback* callback_ = nullptr;
 
   // The source's constraints.
-  absl::optional<VideoTrackSourceConstraints> source_constraints_
+  std::optional<VideoTrackSourceConstraints> source_constraints_
       RTC_GUARDED_BY(queue_);
 
   // Stores the latest restriction in max frame rate set by
   // UpdateVideoSourceRestrictions. Ensures that a previously set restriction
   // can be maintained during reconstructions of the adapter.
-  absl::optional<double> restricted_max_frame_rate_ RTC_GUARDED_BY(queue_);
+  std::optional<double> restricted_max_frame_rate_ RTC_GUARDED_BY(queue_);
 
   // Race checker for incoming frames. This is the network thread in chromium,
   // but may vary from test contexts.
@@ -501,7 +501,7 @@
       layer_trackers_[spatial_index].quality_converged = false;
     }
   } else {
-    layer_trackers_[spatial_index].quality_converged = absl::nullopt;
+    layer_trackers_[spatial_index].quality_converged = std::nullopt;
   }
 }
 
@@ -526,7 +526,7 @@
   // Store the frame in the queue and schedule deferred processing.
   queued_frames_.push_back(frame);
   current_frame_id_++;
-  scheduled_repeat_ = absl::nullopt;
+  scheduled_repeat_ = std::nullopt;
   TimeDelta time_spent_since_post = clock_->CurrentTime() - post_time;
   queue_->PostDelayedHighPrecisionTask(
       SafeTask(safety_.flag(),
@@ -548,13 +548,13 @@
   MaybeStartRefreshFrameRequester();
 }
 
-absl::optional<uint32_t> ZeroHertzAdapterMode::GetInputFrameRateFps() {
+std::optional<uint32_t> ZeroHertzAdapterMode::GetInputFrameRateFps() {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   return max_fps_;
 }
 
 void ZeroHertzAdapterMode::UpdateVideoSourceRestrictions(
-    absl::optional<double> max_frame_rate) {
+    std::optional<double> max_frame_rate) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("webrtc"), __func__,
                        TRACE_EVENT_SCOPE_GLOBAL, "max_frame_rate",
@@ -564,7 +564,7 @@
     restricted_frame_delay_ = TimeDelta::Seconds(1) / *max_frame_rate;
   } else {
     // Source reports that the frame rate is now unrestricted.
-    restricted_frame_delay_ = absl::nullopt;
+    restricted_frame_delay_ = std::nullopt;
   }
 }
 
@@ -708,10 +708,10 @@
 
   // Schedule another repeat before sending the frame off which could take time.
   ScheduleRepeat(frame_id, HasQualityConverged());
-  SendFrameNow(absl::nullopt, frame);
+  SendFrameNow(std::nullopt, frame);
 }
 
-void ZeroHertzAdapterMode::SendFrameNow(absl::optional<Timestamp> post_time,
+void ZeroHertzAdapterMode::SendFrameNow(std::optional<Timestamp> post_time,
                                         const VideoFrame& frame) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   TRACE_EVENT0("webrtc", __func__);
@@ -903,14 +903,14 @@
 }
 
 void FrameCadenceAdapterImpl::SetZeroHertzModeEnabled(
-    absl::optional<ZeroHertzModeParams> params) {
+    std::optional<ZeroHertzModeParams> params) {
   RTC_DCHECK_RUN_ON(queue_);
   bool was_zero_hertz_enabled = zero_hertz_params_.has_value();
   zero_hertz_params_ = params;
   MaybeReconfigureAdapters(was_zero_hertz_enabled);
 }
 
-absl::optional<uint32_t> FrameCadenceAdapterImpl::GetInputFrameRateFps() {
+std::optional<uint32_t> FrameCadenceAdapterImpl::GetInputFrameRateFps() {
   RTC_DCHECK_RUN_ON(queue_);
   return current_adapter_mode_->GetInputFrameRateFps();
 }
@@ -945,7 +945,7 @@
 }
 
 void FrameCadenceAdapterImpl::UpdateVideoSourceRestrictions(
-    absl::optional<double> max_frame_rate) {
+    std::optional<double> max_frame_rate) {
   RTC_DCHECK_RUN_ON(queue_);
   // Store the restriction to ensure that it can be reapplied in possible
   // future adapter creations on configuration changes.
@@ -975,7 +975,7 @@
     if (zero_hertz_adapter_created_timestamp_.has_value()) {
       TimeDelta time_until_first_frame =
           clock_->CurrentTime() - *zero_hertz_adapter_created_timestamp_;
-      zero_hertz_adapter_created_timestamp_ = absl::nullopt;
+      zero_hertz_adapter_created_timestamp_ = std::nullopt;
       RTC_HISTOGRAM_COUNTS_10000(
           "WebRTC.Screenshare.ZeroHz.TimeUntilFirstFrameMs",
           time_until_first_frame.ms());
@@ -1073,7 +1073,7 @@
     current_adapter_mode_ = &zero_hertz_adapter_.value();
   } else {
     if (was_zero_hertz_enabled) {
-      zero_hertz_adapter_ = absl::nullopt;
+      zero_hertz_adapter_ = std::nullopt;
       RTC_LOG(LS_INFO) << "Zero hertz mode disabled.";
     }
     ConfigureCurrentAdapterWithoutZeroHertz();
diff --git a/video/frame_cadence_adapter.h b/video/frame_cadence_adapter.h
index 0dc2e5a..cdee92b 100644
--- a/video/frame_cadence_adapter.h
+++ b/video/frame_cadence_adapter.h
@@ -93,11 +93,11 @@
   // zero-hertz operation. If absl:::nullopt is passed, the cadence adapter will
   // switch to passthrough mode.
   virtual void SetZeroHertzModeEnabled(
-      absl::optional<ZeroHertzModeParams> params) = 0;
+      std::optional<ZeroHertzModeParams> params) = 0;
 
   // Returns the input framerate. This is measured by RateStatistics when
   // zero-hertz mode is off, and returns the max framerate in zero-hertz mode.
-  virtual absl::optional<uint32_t> GetInputFrameRateFps() = 0;
+  virtual std::optional<uint32_t> GetInputFrameRateFps() = 0;
 
   // Updates quality convergence status for an enabled spatial layer.
   // Convergence means QP has dropped to a low-enough level to warrant ceasing
@@ -112,7 +112,7 @@
   // The new `max_frame_rate` will only affect the cadence of Callback::OnFrame
   // for non-idle (non converged) repeated frames.
   virtual void UpdateVideoSourceRestrictions(
-      absl::optional<double> max_frame_rate) = 0;
+      std::optional<double> max_frame_rate) = 0;
 
   // Conditionally requests a refresh frame via
   // Callback::RequestRefreshFrame.
diff --git a/video/frame_cadence_adapter_unittest.cc b/video/frame_cadence_adapter_unittest.cc
index 237b142..e3bdf14 100644
--- a/video/frame_cadence_adapter_unittest.cc
+++ b/video/frame_cadence_adapter_unittest.cc
@@ -113,7 +113,7 @@
 
   for (int frame = 0; frame != 10; ++frame) {
     time_controller.AdvanceTime(TimeDelta::Millis(10));
-    absl::optional<int64_t> expected_fps =
+    std::optional<int64_t> expected_fps =
         rate.Rate(time_controller.GetClock()->TimeInMilliseconds());
     rate.Update(1, time_controller.GetClock()->TimeInMilliseconds());
     // FrameCadanceAdapter::OnFrame post the frame to another sequence.
@@ -186,7 +186,7 @@
   }
   // Turn off zero hertz on the next-last frame; after the last frame we
   // should see a value that tracks the rate oracle.
-  adapter->SetZeroHertzModeEnabled(absl::nullopt);
+  adapter->SetZeroHertzModeEnabled(std::nullopt);
   // Last frame.
   time_controller.AdvanceTime(TimeDelta::Millis(10));
   adapter->OnFrame(CreateFrameWithTimestamps(&time_controller));
@@ -926,7 +926,7 @@
     adapter_->UpdateVideoSourceRestrictions(kRestrictedMaxFps);
   });
   ScheduleDelayed(5.5 * kMinFrameDelay, [&] {
-    adapter_->UpdateVideoSourceRestrictions(absl::nullopt);
+    adapter_->UpdateVideoSourceRestrictions(std::nullopt);
   });
   ExpectFrameEntriesAtDelaysFromNow({
       1 * kMinFrameDelay,  // Original frame emitted at non-restricted rate.
@@ -1122,7 +1122,7 @@
   std::unique_ptr<FrameCadenceAdapterInterface> adapter;
   int frame_counter = 0;
   rtc::Event event;
-  absl::optional<Timestamp> start_time;
+  std::optional<Timestamp> start_time;
   test::ScopedKeyValueConfig no_field_trials;
   queue->PostTask([&] {
     adapter = CreateAdapter(no_field_trials, clock);
diff --git a/video/frame_decode_scheduler.h b/video/frame_decode_scheduler.h
index 29e27c2..762268a 100644
--- a/video/frame_decode_scheduler.h
+++ b/video/frame_decode_scheduler.h
@@ -13,8 +13,9 @@
 
 #include <stdint.h>
 
+#include <optional>
+
 #include "absl/functional/any_invocable.h"
-#include "absl/types/optional.h"
 #include "api/units/timestamp.h"
 #include "video/frame_decode_timing.h"
 
@@ -31,7 +32,7 @@
 
   // Returns the rtp timestamp of the next frame scheduled for release, or
   // `nullopt` if no frame is currently scheduled.
-  virtual absl::optional<uint32_t> ScheduledRtpTimestamp() = 0;
+  virtual std::optional<uint32_t> ScheduledRtpTimestamp() = 0;
 
   // Schedules a frame for release based on `schedule`. When released,
   // `callback` will be invoked with the `rtp` timestamp of the frame and the
diff --git a/video/frame_decode_timing.cc b/video/frame_decode_timing.cc
index 58ecd41..e7401a0 100644
--- a/video/frame_decode_timing.cc
+++ b/video/frame_decode_timing.cc
@@ -11,8 +11,8 @@
 #include "video/frame_decode_timing.h"
 
 #include <algorithm>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/units/time_delta.h"
 #include "rtc_base/logging.h"
 
@@ -25,7 +25,7 @@
   RTC_DCHECK(timing_);
 }
 
-absl::optional<FrameDecodeTiming::FrameSchedule>
+std::optional<FrameDecodeTiming::FrameSchedule>
 FrameDecodeTiming::OnFrameBufferUpdated(uint32_t next_temporal_unit_rtp,
                                         uint32_t last_temporal_unit_rtp,
                                         TimeDelta max_wait_for_frame,
@@ -44,7 +44,7 @@
     RTC_DLOG(LS_VERBOSE) << "Fast-forwarded frame " << next_temporal_unit_rtp
                          << " render time " << render_time << " with delay "
                          << max_wait;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   max_wait.Clamp(TimeDelta::Zero(), max_wait_for_frame);
diff --git a/video/frame_decode_timing.h b/video/frame_decode_timing.h
index 6bde470..c5b024f 100644
--- a/video/frame_decode_timing.h
+++ b/video/frame_decode_timing.h
@@ -38,7 +38,7 @@
     Timestamp render_time;
   };
 
-  absl::optional<FrameSchedule> OnFrameBufferUpdated(
+  std::optional<FrameSchedule> OnFrameBufferUpdated(
       uint32_t next_temporal_unit_rtp,
       uint32_t last_temporal_unit_rtp,
       TimeDelta max_wait_for_frame,
diff --git a/video/frame_decode_timing_unittest.cc b/video/frame_decode_timing_unittest.cc
index 83ea916..cb45d70 100644
--- a/video/frame_decode_timing_unittest.cc
+++ b/video/frame_decode_timing_unittest.cc
@@ -12,7 +12,8 @@
 
 #include <stdint.h>
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "api/units/time_delta.h"
 #include "modules/video_coding/timing/timing.h"
 #include "rtc_base/containers/flat_map.h"
@@ -98,7 +99,7 @@
 
   EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
                   90000, 180000, kMaxWaitForFrame, false),
-              Eq(absl::nullopt));
+              Eq(std::nullopt));
 }
 
 TEST_F(FrameDecodeTimingTest, NoFastForwardIfOnlyFrameToDecode) {
diff --git a/video/frame_encode_metadata_writer.cc b/video/frame_encode_metadata_writer.cc
index 4ff4871..1fd06a6 100644
--- a/video/frame_encode_metadata_writer.cc
+++ b/video/frame_encode_metadata_writer.cc
@@ -141,8 +141,8 @@
     size_t simulcast_svc_idx,
     EncodedImage* encoded_image) {
   MutexLock lock(&lock_);
-  absl::optional<size_t> outlier_frame_size;
-  absl::optional<int64_t> encode_start_ms;
+  std::optional<size_t> outlier_frame_size;
+  std::optional<int64_t> encode_start_ms;
   uint8_t timing_flags = VideoSendTiming::kNotTriggered;
 
   int64_t encode_done_ms = rtc::TimeMillis();
@@ -225,11 +225,11 @@
   stalled_encoder_logged_messages_ = 0;
 }
 
-absl::optional<int64_t>
+std::optional<int64_t>
 FrameEncodeMetadataWriter::ExtractEncodeStartTimeAndFillMetadata(
     size_t simulcast_svc_idx,
     EncodedImage* encoded_image) {
-  absl::optional<int64_t> result;
+  std::optional<int64_t> result;
   size_t num_simulcast_svc_streams = timing_frames_info_.size();
   if (simulcast_svc_idx < num_simulcast_svc_streams) {
     auto metadata_list = &timing_frames_info_[simulcast_svc_idx].frames;
diff --git a/video/frame_encode_metadata_writer.h b/video/frame_encode_metadata_writer.h
index 555bc9b..637d03a 100644
--- a/video/frame_encode_metadata_writer.h
+++ b/video/frame_encode_metadata_writer.h
@@ -12,9 +12,9 @@
 #define VIDEO_FRAME_ENCODE_METADATA_WRITER_H_
 
 #include <list>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/video/encoded_image.h"
 #include "api/video_codecs/video_codec.h"
 #include "api/video_codecs/video_encoder.h"
@@ -45,7 +45,7 @@
  private:
   // For non-internal-source encoders, returns encode started time and fixes
   // capture timestamp for the frame, if corrupted by the encoder.
-  absl::optional<int64_t> ExtractEncodeStartTimeAndFillMetadata(
+  std::optional<int64_t> ExtractEncodeStartTimeAndFillMetadata(
       size_t simulcast_svc_idx,
       EncodedImage* encoded_image) RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_);
 
@@ -55,7 +55,7 @@
     int64_t ntp_time_ms = 0;
     int64_t timestamp_us = 0;
     VideoRotation rotation = kVideoRotation_0;
-    absl::optional<ColorSpace> color_space;
+    std::optional<ColorSpace> color_space;
     bool is_steady_state_refresh_frame = false;
     RtpPacketInfos packet_infos;
   };
diff --git a/video/full_stack_tests.cc b/video/full_stack_tests.cc
index 5e30b86..7e46260 100644
--- a/video/full_stack_tests.cc
+++ b/video/full_stack_tests.cc
@@ -8,13 +8,13 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/flags/flag.h"
 #include "absl/flags/parse.h"
-#include "absl/types/optional.h"
 #include "api/test/simulated_network.h"
 #include "api/test/test_dependency_factory.h"
 #include "api/test/video_quality_test_fixture.h"
diff --git a/video/picture_id_tests.cc b/video/picture_id_tests.cc
index e78f7d3..14abcb1 100644
--- a/video/picture_id_tests.cc
+++ b/video/picture_id_tests.cc
@@ -98,7 +98,7 @@
     parsed->timestamp = rtp_packet.Timestamp();
     parsed->ssrc = rtp_packet.Ssrc();
 
-    absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload =
+    std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload =
         depacketizer_->Parse(rtp_packet.PayloadBuffer());
     EXPECT_TRUE(parsed_payload);
 
diff --git a/video/quality_convergence_controller.cc b/video/quality_convergence_controller.cc
index a19cb8c..d897635 100644
--- a/video/quality_convergence_controller.cc
+++ b/video/quality_convergence_controller.cc
@@ -41,7 +41,7 @@
 
 void QualityConvergenceController::Initialize(
     int number_of_layers,
-    absl::optional<int> static_qp_threshold,
+    std::optional<int> static_qp_threshold,
     VideoCodecType codec,
     const FieldTrialsView& trials) {
   RTC_DCHECK(sequence_checker_.IsCurrent());
diff --git a/video/quality_convergence_controller.h b/video/quality_convergence_controller.h
index a09dc87..16978fd 100644
--- a/video/quality_convergence_controller.h
+++ b/video/quality_convergence_controller.h
@@ -12,9 +12,9 @@
 #define VIDEO_QUALITY_CONVERGENCE_CONTROLLER_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/sequence_checker.h"
 #include "api/video/video_codec_type.h"
@@ -25,7 +25,7 @@
 class QualityConvergenceController {
  public:
   void Initialize(int number_of_layers,
-                  absl::optional<int> static_qp_threshold,
+                  std::optional<int> static_qp_threshold,
                   VideoCodecType codec,
                   const FieldTrialsView& trials);
 
diff --git a/video/quality_scaling_tests.cc b/video/quality_scaling_tests.cc
index cd67e68..12b5650 100644
--- a/video/quality_scaling_tests.cc
+++ b/video/quality_scaling_tests.cc
@@ -57,17 +57,17 @@
  protected:
   const std::string kPrefix = "WebRTC-Video-QualityScaling/Enabled-";
   const std::string kEnd = ",0,0,0.9995,0.9999,1/";
-  const absl::optional<VideoEncoder::ResolutionBitrateLimits>
+  const std::optional<VideoEncoder::ResolutionBitrateLimits>
       kSinglecastLimits720pVp8 =
           EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
               kVideoCodecVP8,
               1280 * 720);
-  const absl::optional<VideoEncoder::ResolutionBitrateLimits>
+  const std::optional<VideoEncoder::ResolutionBitrateLimits>
       kSinglecastLimits360pVp9 =
           EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
               kVideoCodecVP9,
               640 * 360);
-  const absl::optional<VideoEncoder::ResolutionBitrateLimits>
+  const std::optional<VideoEncoder::ResolutionBitrateLimits>
       kSinglecastLimits720pVp9 =
           EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
               kVideoCodecVP9,
@@ -78,7 +78,7 @@
  protected:
   struct TestParams {
     bool active;
-    absl::optional<ScalabilityMode> scalability_mode;
+    std::optional<ScalabilityMode> scalability_mode;
   };
   ScalingObserver(const std::string& payload_name,
                   const std::vector<TestParams>& test_params,
diff --git a/video/rate_utilization_tracker.cc b/video/rate_utilization_tracker.cc
index 9403ff1..ad7125a 100644
--- a/video/rate_utilization_tracker.cc
+++ b/video/rate_utilization_tracker.cc
@@ -63,10 +63,10 @@
   CullOldData(time);
 }
 
-absl::optional<double> RateUtilizationTracker::GetRateUtilizationFactor(
+std::optional<double> RateUtilizationTracker::GetRateUtilizationFactor(
     Timestamp time) const {
   if (data_points_.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   RTC_CHECK_GE(time, data_points_.back().time);
@@ -104,7 +104,7 @@
 
   if (allocated_send_data_size.IsZero() && current_rate_.IsZero()) {
     // No allocated rate across all of the data points, ignore.
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Calculate the rate past the very last data point until the polling time.
diff --git a/video/rate_utilization_tracker.h b/video/rate_utilization_tracker.h
index 23f4088..619d542 100644
--- a/video/rate_utilization_tracker.h
+++ b/video/rate_utilization_tracker.h
@@ -12,8 +12,8 @@
 #define VIDEO_RATE_UTILIZATION_TRACKER_H_
 
 #include <deque>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/units/data_rate.h"
 #include "api/units/data_size.h"
 #include "api/units/time_delta.h"
@@ -46,7 +46,7 @@
   // The timestamps used should never decrease relative the last one.
   void OnDataRateChanged(DataRate rate, Timestamp time);
   void OnDataProduced(DataSize size, Timestamp time);
-  absl::optional<double> GetRateUtilizationFactor(Timestamp time) const;
+  std::optional<double> GetRateUtilizationFactor(Timestamp time) const;
 
  private:
   struct RateUsageUpdate {
diff --git a/video/receive_statistics_proxy.cc b/video/receive_statistics_proxy.cc
index 05dafbd..e74968b 100644
--- a/video/receive_statistics_proxy.cc
+++ b/video/receive_statistics_proxy.cc
@@ -96,7 +96,7 @@
 }
 
 void ReceiveStatisticsProxy::UpdateHistograms(
-    absl::optional<int> fraction_lost,
+    std::optional<int> fraction_lost,
     const StreamDataCounters& rtp_stats,
     const StreamDataCounters* rtx_stats) {
   RTC_DCHECK_RUN_ON(&main_thread_);
@@ -170,7 +170,7 @@
         round(render_pixel_tracker_.ComputeTotalRate()));
   }
 
-  absl::optional<int> sync_offset_ms =
+  std::optional<int> sync_offset_ms =
       sync_offset_counter_.Avg(kMinRequiredSamples);
   if (sync_offset_ms) {
     RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.AVSyncOffsetInMs",
@@ -197,18 +197,18 @@
                << key_frames_permille << '\n';
   }
 
-  absl::optional<int> qp = qp_counters_.vp8.Avg(kMinRequiredSamples);
+  std::optional<int> qp = qp_counters_.vp8.Avg(kMinRequiredSamples);
   if (qp) {
     RTC_HISTOGRAM_COUNTS_200("WebRTC.Video.Decoded.Vp8.Qp", *qp);
     log_stream << "WebRTC.Video.Decoded.Vp8.Qp " << *qp << '\n';
   }
 
-  absl::optional<int> decode_ms = decode_time_counter_.Avg(kMinRequiredSamples);
+  std::optional<int> decode_ms = decode_time_counter_.Avg(kMinRequiredSamples);
   if (decode_ms) {
     RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.DecodeTimeInMs", *decode_ms);
     log_stream << "WebRTC.Video.DecodeTimeInMs " << *decode_ms << '\n';
   }
-  absl::optional<int> jb_delay_ms =
+  std::optional<int> jb_delay_ms =
       jitter_delay_counter_.Avg(kMinRequiredSamples);
   if (jb_delay_ms) {
     RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.JitterBufferDelayInMs",
@@ -216,21 +216,21 @@
     log_stream << "WebRTC.Video.JitterBufferDelayInMs " << *jb_delay_ms << '\n';
   }
 
-  absl::optional<int> target_delay_ms =
+  std::optional<int> target_delay_ms =
       target_delay_counter_.Avg(kMinRequiredSamples);
   if (target_delay_ms) {
     RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.TargetDelayInMs",
                                *target_delay_ms);
     log_stream << "WebRTC.Video.TargetDelayInMs " << *target_delay_ms << '\n';
   }
-  absl::optional<int> current_delay_ms =
+  std::optional<int> current_delay_ms =
       current_delay_counter_.Avg(kMinRequiredSamples);
   if (current_delay_ms) {
     RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.CurrentDelayInMs",
                                *current_delay_ms);
     log_stream << "WebRTC.Video.CurrentDelayInMs " << *current_delay_ms << '\n';
   }
-  absl::optional<int> delay_ms = oneway_delay_counter_.Avg(kMinRequiredSamples);
+  std::optional<int> delay_ms = oneway_delay_counter_.Avg(kMinRequiredSamples);
   if (delay_ms)
     RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.OnewayDelayInMs", *delay_ms);
 
@@ -242,7 +242,7 @@
     auto stats = it.second;
     std::string uma_prefix = UmaPrefixForContentType(content_type);
 
-    absl::optional<int> e2e_delay_ms =
+    std::optional<int> e2e_delay_ms =
         stats.e2e_delay_counter.Avg(kMinRequiredSamples);
     if (e2e_delay_ms) {
       RTC_HISTOGRAM_COUNTS_SPARSE_10000(uma_prefix + ".EndToEndDelayInMs",
@@ -250,14 +250,14 @@
       log_stream << uma_prefix << ".EndToEndDelayInMs"
                  << " " << *e2e_delay_ms << '\n';
     }
-    absl::optional<int> e2e_delay_max_ms = stats.e2e_delay_counter.Max();
+    std::optional<int> e2e_delay_max_ms = stats.e2e_delay_counter.Max();
     if (e2e_delay_max_ms && e2e_delay_ms) {
       RTC_HISTOGRAM_COUNTS_SPARSE_100000(uma_prefix + ".EndToEndDelayMaxInMs",
                                          *e2e_delay_max_ms);
       log_stream << uma_prefix << ".EndToEndDelayMaxInMs"
                  << " " << *e2e_delay_max_ms << '\n';
     }
-    absl::optional<int> interframe_delay_ms =
+    std::optional<int> interframe_delay_ms =
         stats.interframe_delay_counter.Avg(kMinRequiredSamples);
     if (interframe_delay_ms) {
       RTC_HISTOGRAM_COUNTS_SPARSE_10000(uma_prefix + ".InterframeDelayInMs",
@@ -265,7 +265,7 @@
       log_stream << uma_prefix << ".InterframeDelayInMs"
                  << " " << *interframe_delay_ms << '\n';
     }
-    absl::optional<int> interframe_delay_max_ms =
+    std::optional<int> interframe_delay_max_ms =
         stats.interframe_delay_counter.Max();
     if (interframe_delay_max_ms && interframe_delay_ms) {
       RTC_HISTOGRAM_COUNTS_SPARSE_10000(uma_prefix + ".InterframeDelayMaxInMs",
@@ -274,7 +274,7 @@
                  << " " << *interframe_delay_max_ms << '\n';
     }
 
-    absl::optional<uint32_t> interframe_delay_95p_ms =
+    std::optional<uint32_t> interframe_delay_95p_ms =
         stats.interframe_delay_percentiles.GetPercentile(0.95f);
     if (interframe_delay_95p_ms && interframe_delay_ms != -1) {
       RTC_HISTOGRAM_COUNTS_SPARSE_10000(
@@ -284,7 +284,7 @@
                  << " " << *interframe_delay_95p_ms << '\n';
     }
 
-    absl::optional<int> width = stats.received_width.Avg(kMinRequiredSamples);
+    std::optional<int> width = stats.received_width.Avg(kMinRequiredSamples);
     if (width) {
       RTC_HISTOGRAM_COUNTS_SPARSE_10000(uma_prefix + ".ReceivedWidthInPixels",
                                         *width);
@@ -292,7 +292,7 @@
                  << " " << *width << '\n';
     }
 
-    absl::optional<int> height = stats.received_height.Avg(kMinRequiredSamples);
+    std::optional<int> height = stats.received_height.Avg(kMinRequiredSamples);
     if (height) {
       RTC_HISTOGRAM_COUNTS_SPARSE_10000(uma_prefix + ".ReceivedHeightInPixels",
                                         *height);
@@ -300,7 +300,7 @@
                  << " " << *height << '\n';
     }
 
-    absl::optional<double> corruption_score = stats.corruption_score.GetMean();
+    std::optional<double> corruption_score = stats.corruption_score.GetMean();
     if (corruption_score) {
       // Granularity level: 2e-3.
       RTC_HISTOGRAM_COUNTS_SPARSE(uma_prefix + ".CorruptionLikelihoodPermille",
@@ -336,7 +336,7 @@
                    << " " << key_frames_permille << '\n';
       }
 
-      absl::optional<int> qp = stats.qp_counter.Avg(kMinRequiredSamples);
+      std::optional<int> qp = stats.qp_counter.Avg(kMinRequiredSamples);
       if (qp) {
         RTC_HISTOGRAM_COUNTS_SPARSE_200(uma_prefix + ".Decoded.Vp8.Qp", *qp);
         log_stream << uma_prefix << ".Decoded.Vp8.Qp"
@@ -409,13 +409,13 @@
   stats_.network_frame_rate = static_cast<int>(framerate);
 }
 
-absl::optional<int64_t>
+std::optional<int64_t>
 ReceiveStatisticsProxy::GetCurrentEstimatedPlayoutNtpTimestampMs(
     int64_t now_ms) const {
   RTC_DCHECK_RUN_ON(&main_thread_);
   if (!last_estimated_playout_ntp_timestamp_ms_ ||
       !last_estimated_playout_time_ms_) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   int64_t elapsed_ms = now_ms - *last_estimated_playout_time_ms_;
   return *last_estimated_playout_ntp_timestamp_ms_ + elapsed_ms;
@@ -590,7 +590,7 @@
 }
 
 void ReceiveStatisticsProxy::OnDecodedFrame(const VideoFrame& frame,
-                                            absl::optional<uint8_t> qp,
+                                            std::optional<uint8_t> qp,
                                             TimeDelta decode_time,
                                             VideoContentType content_type,
                                             VideoFrameType frame_type) {
@@ -626,7 +626,7 @@
 
 void ReceiveStatisticsProxy::OnDecodedFrame(
     const VideoFrameMetaData& frame_meta,
-    absl::optional<uint8_t> qp,
+    std::optional<uint8_t> qp,
     TimeDelta decode_time,
     TimeDelta processing_delay,
     TimeDelta assembly_time,
diff --git a/video/receive_statistics_proxy.h b/video/receive_statistics_proxy.h
index a678602..7af28fd 100644
--- a/video/receive_statistics_proxy.h
+++ b/video/receive_statistics_proxy.h
@@ -13,10 +13,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/sequence_checker.h"
 #include "api/task_queue/pending_task_safety_flag.h"
 #include "api/task_queue/task_queue_base.h"
@@ -57,7 +57,7 @@
   VideoReceiveStreamInterface::Stats GetStats() const;
 
   void OnDecodedFrame(const VideoFrame& frame,
-                      absl::optional<uint8_t> qp,
+                      std::optional<uint8_t> qp,
                       TimeDelta decode_time,
                       VideoContentType content_type,
                       VideoFrameType frame_type);
@@ -66,7 +66,7 @@
   // above OnDecodedFrame method, which is called back on the thread where
   // the actual decoding happens.
   void OnDecodedFrame(const VideoFrameMetaData& frame_meta,
-                      absl::optional<uint8_t> qp,
+                      std::optional<uint8_t> qp,
                       TimeDelta decode_time,
                       TimeDelta processing_delay,
                       TimeDelta assembly_time,
@@ -123,7 +123,7 @@
 
   // Produce histograms. Must be called after DecoderThreadStopped(), typically
   // at the end of the call.
-  void UpdateHistograms(absl::optional<int> fraction_lost,
+  void UpdateHistograms(std::optional<int> fraction_lost,
                         const StreamDataCounters& rtp_stats,
                         const StreamDataCounters* rtx_stats);
 
@@ -153,7 +153,7 @@
   // Removes info about old frames and then updates the framerate.
   void UpdateFramerate(int64_t now_ms) const;
 
-  absl::optional<int64_t> GetCurrentEstimatedPlayoutNtpTimestampMs(
+  std::optional<int64_t> GetCurrentEstimatedPlayoutNtpTimestampMs(
       int64_t now_ms) const;
 
   Clock* const clock_;
@@ -186,11 +186,11 @@
   mutable std::map<int64_t, size_t> frame_window_ RTC_GUARDED_BY(main_thread_);
   VideoContentType last_content_type_ RTC_GUARDED_BY(&main_thread_);
   VideoCodecType last_codec_type_ RTC_GUARDED_BY(main_thread_);
-  absl::optional<int64_t> first_frame_received_time_ms_
+  std::optional<int64_t> first_frame_received_time_ms_
       RTC_GUARDED_BY(main_thread_);
-  absl::optional<int64_t> first_decoded_frame_time_ms_
+  std::optional<int64_t> first_decoded_frame_time_ms_
       RTC_GUARDED_BY(main_thread_);
-  absl::optional<int64_t> last_decoded_frame_time_ms_
+  std::optional<int64_t> last_decoded_frame_time_ms_
       RTC_GUARDED_BY(main_thread_);
   size_t num_delayed_frames_rendered_ RTC_GUARDED_BY(main_thread_);
   int64_t sum_missed_render_deadline_ms_ RTC_GUARDED_BY(main_thread_);
@@ -198,10 +198,10 @@
   // called from const GetStats().
   mutable rtc::MovingMaxCounter<TimingFrameInfo> timing_frame_info_counter_
       RTC_GUARDED_BY(main_thread_);
-  absl::optional<int> num_unique_frames_ RTC_GUARDED_BY(main_thread_);
-  absl::optional<int64_t> last_estimated_playout_ntp_timestamp_ms_
+  std::optional<int> num_unique_frames_ RTC_GUARDED_BY(main_thread_);
+  std::optional<int64_t> last_estimated_playout_ntp_timestamp_ms_
       RTC_GUARDED_BY(main_thread_);
-  absl::optional<int64_t> last_estimated_playout_time_ms_
+  std::optional<int64_t> last_estimated_playout_time_ms_
       RTC_GUARDED_BY(main_thread_);
 
   // The thread on which this instance is constructed and some of its main
diff --git a/video/receive_statistics_proxy_unittest.cc b/video/receive_statistics_proxy_unittest.cc
index 4b5af07..22bed59 100644
--- a/video/receive_statistics_proxy_unittest.cc
+++ b/video/receive_statistics_proxy_unittest.cc
@@ -12,11 +12,11 @@
 
 #include <limits>
 #include <memory>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
 #include "api/units/frequency.h"
 #include "api/units/time_delta.h"
@@ -63,7 +63,7 @@
     return statistics_proxy_->GetStats();
   }
 
-  void FlushAndUpdateHistograms(absl::optional<int> fraction_lost,
+  void FlushAndUpdateHistograms(std::optional<int> fraction_lost,
                                 const StreamDataCounters& rtp_stats,
                                 const StreamDataCounters* rtx_stats) {
     time_controller_.AdvanceTime(TimeDelta::Zero());
@@ -117,7 +117,7 @@
   EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
   for (uint32_t i = 1; i <= 3; ++i) {
-    statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                       VideoContentType::UNSPECIFIED,
                                       VideoFrameType::kVideoFrameKey);
     EXPECT_EQ(i, FlushAndGetStats().frames_decoded);
@@ -130,12 +130,12 @@
       TimeDelta::Seconds(metrics::kMinRunTimeInSeconds) * kFps;
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
   for (int i = 0; i < kRequiredSamples; ++i) {
-    statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                       VideoContentType::UNSPECIFIED,
                                       VideoFrameType::kVideoFrameKey);
     time_controller_.AdvanceTime(1 / kFps);
   }
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   EXPECT_METRIC_EQ(1,
                    metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
   EXPECT_METRIC_EQ(1, metrics::NumEvents("WebRTC.Video.DecodedFramesPerSecond",
@@ -148,12 +148,12 @@
       TimeDelta::Seconds(metrics::kMinRunTimeInSeconds) * kFps;
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
   for (int i = 0; i < kRequiredSamples - 1; ++i) {
-    statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                       VideoContentType::UNSPECIFIED,
                                       VideoFrameType::kVideoFrameKey);
     time_controller_.AdvanceTime(1 / kFps);
   }
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   EXPECT_METRIC_EQ(0,
                    metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
 }
@@ -165,9 +165,9 @@
   TimeDelta expected_total_decode_time = TimeDelta::Zero();
   unsigned int expected_frames_decoded = 0;
   for (uint32_t i = 1; i <= 3; ++i) {
-    statistics_proxy_->OnDecodedFrame(
-        frame, absl::nullopt, TimeDelta::Millis(1),
-        VideoContentType::UNSPECIFIED, VideoFrameType::kVideoFrameKey);
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Millis(1),
+                                      VideoContentType::UNSPECIFIED,
+                                      VideoFrameType::kVideoFrameKey);
     expected_total_decode_time += TimeDelta::Millis(1);
     ++expected_frames_decoded;
     time_controller_.AdvanceTime(TimeDelta::Zero());
@@ -202,9 +202,9 @@
   frame.set_packet_infos(RtpPacketInfos(packet_infos));
   for (int i = 1; i <= 3; ++i) {
     time_controller_.AdvanceTime(kProcessingDelay);
-    statistics_proxy_->OnDecodedFrame(
-        frame, absl::nullopt, TimeDelta::Millis(1),
-        VideoContentType::UNSPECIFIED, VideoFrameType::kVideoFrameKey);
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Millis(1),
+                                      VideoContentType::UNSPECIFIED,
+                                      VideoFrameType::kVideoFrameKey);
     expected_total_processing_delay += i * kProcessingDelay;
     ++expected_frames_decoded;
     time_controller_.AdvanceTime(TimeDelta::Zero());
@@ -239,7 +239,7 @@
   RtpPacketInfos::vector_type single_packet_frame = {RtpPacketInfo(
       /*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/{}, /*receive_time=*/Now())};
   frame.set_packet_infos(RtpPacketInfos(single_packet_frame));
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Millis(1),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Millis(1),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameKey);
   ++expected_frames_decoded;
@@ -302,7 +302,7 @@
 }
 
 TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesQpSum) {
-  EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
+  EXPECT_EQ(std::nullopt, statistics_proxy_->GetStats().qp_sum);
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
   statistics_proxy_->OnDecodedFrame(frame, 3u, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
@@ -315,7 +315,7 @@
 }
 
 TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesTotalDecodeTime) {
-  EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
+  EXPECT_EQ(std::nullopt, statistics_proxy_->GetStats().qp_sum);
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
   statistics_proxy_->OnDecodedFrame(frame, 3u, TimeDelta::Millis(4),
                                     VideoContentType::UNSPECIFIED,
@@ -351,25 +351,25 @@
   const TimeDelta kInterframeDelay2 = TimeDelta::Millis(200);
   const TimeDelta kInterframeDelay3 = TimeDelta::Millis(100);
   EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameKey);
   EXPECT_EQ(-1, FlushAndGetStats().interframe_delay_max_ms);
 
   time_controller_.AdvanceTime(kInterframeDelay1);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameDelta);
   EXPECT_EQ(kInterframeDelay1.ms(), FlushAndGetStats().interframe_delay_max_ms);
 
   time_controller_.AdvanceTime(kInterframeDelay2);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameDelta);
   EXPECT_EQ(kInterframeDelay2.ms(), FlushAndGetStats().interframe_delay_max_ms);
 
   time_controller_.AdvanceTime(kInterframeDelay3);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameDelta);
   // kInterframeDelay3 is smaller than kInterframeDelay2.
@@ -382,26 +382,26 @@
   const TimeDelta kInterframeDelay2 = TimeDelta::Millis(750);
   const TimeDelta kInterframeDelay3 = TimeDelta::Millis(700);
   EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameKey);
   EXPECT_EQ(-1, FlushAndGetStats().interframe_delay_max_ms);
 
   time_controller_.AdvanceTime(kInterframeDelay1);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameDelta);
   EXPECT_EQ(kInterframeDelay1.ms(), FlushAndGetStats().interframe_delay_max_ms);
 
   time_controller_.AdvanceTime(kInterframeDelay2);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameDelta);
   // Still first delay is the maximum
   EXPECT_EQ(kInterframeDelay1.ms(), FlushAndGetStats().interframe_delay_max_ms);
 
   time_controller_.AdvanceTime(kInterframeDelay3);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameDelta);
   // Now the first sample is out of the window, so the second is the maximum.
@@ -510,24 +510,24 @@
 
 TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithoutQpQpSumWontExist) {
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
-  EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  EXPECT_EQ(std::nullopt, statistics_proxy_->GetStats().qp_sum);
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameKey);
-  EXPECT_EQ(absl::nullopt, FlushAndGetStats().qp_sum);
+  EXPECT_EQ(std::nullopt, FlushAndGetStats().qp_sum);
 }
 
 TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithoutQpResetsQpSum) {
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
-  EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
+  EXPECT_EQ(std::nullopt, statistics_proxy_->GetStats().qp_sum);
   statistics_proxy_->OnDecodedFrame(frame, 3u, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameKey);
   EXPECT_EQ(3u, FlushAndGetStats().qp_sum);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameDelta);
-  EXPECT_EQ(absl::nullopt, FlushAndGetStats().qp_sum);
+  EXPECT_EQ(std::nullopt, FlushAndGetStats().qp_sum);
 }
 
 TEST_F(ReceiveStatisticsProxyTest, OnRenderedFrameIncreasesFramesRendered) {
@@ -540,8 +540,8 @@
 }
 
 TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsOnCorruptionScore) {
-  EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().corruption_score_sum);
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt, statistics_proxy_->GetStats().corruption_score_sum);
+  EXPECT_EQ(std::nullopt,
             statistics_proxy_->GetStats().corruption_score_squared_sum);
   EXPECT_EQ(0u, statistics_proxy_->GetStats().corruption_score_count);
 
@@ -576,8 +576,8 @@
 
 TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsDecoderInfo) {
   auto init_stats = statistics_proxy_->GetStats();
-  EXPECT_EQ(init_stats.decoder_implementation_name, absl::nullopt);
-  EXPECT_EQ(init_stats.power_efficient_decoder, absl::nullopt);
+  EXPECT_EQ(init_stats.decoder_implementation_name, std::nullopt);
+  EXPECT_EQ(init_stats.power_efficient_decoder, std::nullopt);
 
   const VideoDecoder::DecoderInfo decoder_info{
       .implementation_name = "decoderName", .is_hardware_accelerated = true};
@@ -682,12 +682,12 @@
   const int kDeltaFrames = 22;
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
   for (int i = 0; i < kKeyFrames; i++) {
-    statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                       VideoContentType::UNSPECIFIED,
                                       VideoFrameType::kVideoFrameKey);
   }
   for (int i = 0; i < kDeltaFrames; i++) {
-    statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                       VideoContentType::UNSPECIFIED,
                                       VideoFrameType::kVideoFrameDelta);
   }
@@ -715,7 +715,7 @@
   const int64_t kLongEndToEndDelay = 100;
   const uint32_t kExpectedRtpTimestamp = 2;
   TimingFrameInfo info;
-  absl::optional<TimingFrameInfo> result;
+  std::optional<TimingFrameInfo> result;
   info.rtp_timestamp = kExpectedRtpTimestamp - 1;
   info.capture_time_ms = 0;
   info.decode_finish_ms = kShortEndToEndDelay;
@@ -740,7 +740,7 @@
   const uint32_t kExpectedRtpTimestamp = 2;
   const TimeDelta kShortDelay = TimeDelta::Seconds(1);
   const TimeDelta kLongDelay = TimeDelta::Seconds(10);
-  absl::optional<TimingFrameInfo> result;
+  std::optional<TimingFrameInfo> result;
   info.rtp_timestamp = kExpectedRtpTimestamp;
   info.capture_time_ms = 0;
   info.decode_finish_ms = kShortEndToEndDelay;
@@ -762,11 +762,11 @@
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
   statistics_proxy_->OnCompleteFrame(true, 1000, VideoContentType::UNSPECIFIED);
   statistics_proxy_->OnDecodedFrame(
-      frame, absl::nullopt, TimeDelta::Millis(1000),
+      frame, std::nullopt, TimeDelta::Millis(1000),
       VideoContentType::UNSPECIFIED, VideoFrameType::kVideoFrameKey);
   FlushAndGetStats();
 
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   EXPECT_METRIC_EQ(
       1, metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
@@ -780,7 +780,7 @@
   const TimeDelta kLifetime = TimeDelta::Seconds(3);
   time_controller_.AdvanceTime(kLifetime);
   // No frames received.
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   EXPECT_METRIC_EQ(
       0, metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
@@ -808,7 +808,7 @@
   const int64_t kVideoNtpMs = 21;
   const int64_t kSyncOffsetMs = 22;
   const double kFreqKhz = 90.0;
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             statistics_proxy_->GetStats().estimated_playout_ntp_timestamp_ms);
   statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs, kFreqKhz);
   EXPECT_EQ(kVideoNtpMs, FlushAndGetStats().estimated_playout_ntp_timestamp_ms);
@@ -838,7 +838,7 @@
     statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs,
                                            kFreqKhz);
   }
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs"));
   EXPECT_METRIC_EQ(
       1, metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs));
@@ -862,7 +862,7 @@
   time_controller_.AdvanceTime(kFreqOffsetProcessInterval);
   //) Process interval passed, max diff: 4.
   statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs, kFreqKhz);
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   // Average reported: (2 + 4) / 2 = 3.
   EXPECT_METRIC_EQ(1,
                    metrics::NumSamples("WebRTC.Video.RtpToNtpFreqOffsetInKhz"));
@@ -876,7 +876,7 @@
   for (int i = 0; i < kMinRequiredSamples; ++i)
     statistics_proxy_->OnPreDecode(kVideoCodecVP8, kQp);
 
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
   EXPECT_METRIC_EQ(1, metrics::NumEvents("WebRTC.Video.Decoded.Vp8.Qp", kQp));
 }
@@ -887,7 +887,7 @@
   for (int i = 0; i < kMinRequiredSamples - 1; ++i)
     statistics_proxy_->OnPreDecode(kVideoCodecVP8, kQp);
 
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
 }
@@ -896,7 +896,7 @@
   for (int i = 0; i < kMinRequiredSamples; ++i)
     statistics_proxy_->OnPreDecode(kVideoCodecVP8, -1);
 
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
 }
@@ -911,7 +911,7 @@
     statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes,
                                        VideoContentType::UNSPECIFIED);
     statistics_proxy_->OnDecodedFrame(
-        frame, absl::nullopt, TimeDelta::Millis(1000),
+        frame, std::nullopt, TimeDelta::Millis(1000),
         VideoContentType::UNSPECIFIED, VideoFrameType::kVideoFrameDelta);
   }
   FlushAndGetStats();
@@ -920,7 +920,7 @@
   EXPECT_EQ(kMinRequiredSamples - 1,
             statistics_proxy_->GetStats().frame_counts.delta_frames);
 
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   EXPECT_METRIC_EQ(
       0, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
@@ -936,7 +936,7 @@
     statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes,
                                        VideoContentType::UNSPECIFIED);
     statistics_proxy_->OnDecodedFrame(
-        frame, absl::nullopt, TimeDelta::Millis(1000),
+        frame, std::nullopt, TimeDelta::Millis(1000),
         VideoContentType::UNSPECIFIED, VideoFrameType::kVideoFrameDelta);
   }
   FlushAndGetStats();
@@ -945,7 +945,7 @@
   EXPECT_EQ(kMinRequiredSamples,
             statistics_proxy_->GetStats().frame_counts.delta_frames);
 
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   EXPECT_METRIC_EQ(
       1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
@@ -961,14 +961,14 @@
     statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes,
                                        VideoContentType::UNSPECIFIED);
     statistics_proxy_->OnDecodedFrame(
-        frame, absl::nullopt, TimeDelta::Millis(1000),
+        frame, std::nullopt, TimeDelta::Millis(1000),
         VideoContentType::UNSPECIFIED, VideoFrameType::kVideoFrameKey);
   }
   for (int i = 0; i < kMinRequiredSamples; ++i) {
     statistics_proxy_->OnCompleteFrame(false, kFrameSizeBytes,
                                        VideoContentType::UNSPECIFIED);
     statistics_proxy_->OnDecodedFrame(
-        frame, absl::nullopt, TimeDelta::Millis(1000),
+        frame, std::nullopt, TimeDelta::Millis(1000),
         VideoContentType::UNSPECIFIED, VideoFrameType::kVideoFrameDelta);
   }
   FlushAndGetStats();
@@ -978,7 +978,7 @@
   EXPECT_EQ(kMinRequiredSamples,
             statistics_proxy_->GetStats().frame_counts.delta_frames);
 
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   EXPECT_METRIC_EQ(
       1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
@@ -1000,7 +1000,7 @@
         kMinPlayoutDelayMs, kRenderDelayMs);
   }
 
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
   EXPECT_METRIC_EQ(0,
@@ -1024,7 +1024,7 @@
         kMinPlayoutDelayMs, kRenderDelayMs);
   }
 
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   EXPECT_METRIC_EQ(1,
                    metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
@@ -1050,7 +1050,7 @@
     // i.e. bad
     frame.set_ntp_time_ms(
         time_controller_.GetClock()->CurrentNtpInMilliseconds());
-    statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                       VideoContentType::UNSPECIFIED,
                                       VideoFrameType::kVideoFrameKey);
     statistics_proxy_->OnRenderedFrame(MetaData(frame));
@@ -1088,7 +1088,7 @@
     statistics_proxy_->OnRenderedFrame(MetaData(CreateFrame(kWidth, kHeight)));
   }
 
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   EXPECT_METRIC_EQ(0,
                    metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
@@ -1105,7 +1105,7 @@
     statistics_proxy_->OnRenderedFrame(MetaData(CreateFrame(kWidth, kHeight)));
   }
 
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   EXPECT_METRIC_EQ(1,
                    metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
@@ -1123,7 +1123,7 @@
 
 TEST_F(ReceiveStatisticsProxyTest, ZeroDelayReportedIfFrameNotDelayed) {
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameKey);
 
@@ -1134,7 +1134,7 @@
   // Min run time has passed.
   time_controller_.AdvanceTime(
       TimeDelta::Seconds((metrics::kMinRunTimeInSeconds)));
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   EXPECT_METRIC_EQ(1,
                    metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
   EXPECT_METRIC_EQ(
@@ -1146,7 +1146,7 @@
 TEST_F(ReceiveStatisticsProxyTest,
        DelayedFrameHistogramsAreNotUpdatedIfMinRuntimeHasNotPassed) {
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameKey);
 
@@ -1157,7 +1157,7 @@
   // Min run time has not passed.
   time_controller_.AdvanceTime(
       TimeDelta::Seconds(metrics::kMinRunTimeInSeconds) - TimeDelta::Millis(1));
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   EXPECT_METRIC_EQ(0,
                    metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
@@ -1168,14 +1168,14 @@
 TEST_F(ReceiveStatisticsProxyTest,
        DelayedFramesHistogramsAreNotUpdatedIfNoRenderedFrames) {
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameKey);
 
   // Min run time has passed. No rendered frames.
   time_controller_.AdvanceTime(
       TimeDelta::Seconds((metrics::kMinRunTimeInSeconds)));
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   EXPECT_METRIC_EQ(0,
                    metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
@@ -1185,7 +1185,7 @@
 
 TEST_F(ReceiveStatisticsProxyTest, DelayReportedIfFrameIsDelayed) {
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameKey);
 
@@ -1196,7 +1196,7 @@
   // Min run time has passed.
   time_controller_.AdvanceTime(
       TimeDelta::Seconds(metrics::kMinRunTimeInSeconds));
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   EXPECT_METRIC_EQ(1,
                    metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
   EXPECT_METRIC_EQ(
@@ -1210,7 +1210,7 @@
 
 TEST_F(ReceiveStatisticsProxyTest, AverageDelayOfDelayedFramesIsReported) {
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     VideoContentType::UNSPECIFIED,
                                     VideoFrameType::kVideoFrameKey);
 
@@ -1229,7 +1229,7 @@
   // Min run time has passed.
   time_controller_.AdvanceTime(
       TimeDelta::Seconds(metrics::kMinRunTimeInSeconds));
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   EXPECT_METRIC_EQ(1,
                    metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
   EXPECT_METRIC_EQ(
@@ -1252,7 +1252,7 @@
   RtcpPacketTypeCounter counter;
   statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
 
-  statistics_proxy_->UpdateHistograms(absl::nullopt, data_counters, nullptr);
+  statistics_proxy_->UpdateHistograms(std::nullopt, data_counters, nullptr);
   EXPECT_METRIC_EQ(0,
                    metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
   EXPECT_METRIC_EQ(0,
@@ -1277,7 +1277,7 @@
   counter.nack_packets = kNackPackets;
   statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
 
-  statistics_proxy_->UpdateHistograms(absl::nullopt, data_counters, nullptr);
+  statistics_proxy_->UpdateHistograms(std::nullopt, data_counters, nullptr);
   EXPECT_METRIC_EQ(1,
                    metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
   EXPECT_METRIC_EQ(1,
@@ -1364,18 +1364,18 @@
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
 
   for (int i = 0; i < kMinRequiredSamples; ++i) {
-    statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                       content_type_,
                                       VideoFrameType::kVideoFrameKey);
     time_controller_.AdvanceTime(kInterFrameDelay);
   }
   // One extra with double the interval.
   time_controller_.AdvanceTime(kInterFrameDelay);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     content_type_,
                                     VideoFrameType::kVideoFrameDelta);
 
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   const TimeDelta kExpectedInterFrame =
       (kInterFrameDelay * (kMinRequiredSamples - 1) + kInterFrameDelay * 2) /
       kMinRequiredSamples;
@@ -1402,24 +1402,24 @@
 
   for (int i = 0; i <= kMinRequiredSamples - kLastFivePercentsSamples; ++i) {
     time_controller_.AdvanceTime(kInterFrameDelay);
-    statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                       content_type_,
                                       VideoFrameType::kVideoFrameKey);
   }
   // Last 5% of intervals are double in size.
   for (int i = 0; i < kLastFivePercentsSamples; ++i) {
     time_controller_.AdvanceTime(2 * kInterFrameDelay);
-    statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                       content_type_,
                                       VideoFrameType::kVideoFrameKey);
   }
   // Final sample is outlier and 10 times as big.
   time_controller_.AdvanceTime(10 * kInterFrameDelay);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     content_type_,
                                     VideoFrameType::kVideoFrameKey);
 
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   const TimeDelta kExpectedInterFrame = kInterFrameDelay * 2;
   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
     EXPECT_METRIC_EQ(
@@ -1439,7 +1439,7 @@
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
 
   for (int i = 0; i < kMinRequiredSamples; ++i) {
-    statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                       content_type_,
                                       VideoFrameType::kVideoFrameKey);
     time_controller_.AdvanceTime(kInterFrameDelay);
@@ -1447,7 +1447,7 @@
 
   // `kMinRequiredSamples` samples, and thereby intervals, is required. That
   // means we're one frame short of having a valid data set.
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
   EXPECT_METRIC_EQ(0,
@@ -1463,7 +1463,7 @@
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
 
   for (int i = 0; i <= kMinRequiredSamples; ++i) {
-    statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                       content_type_,
                                       VideoFrameType::kVideoFrameKey);
     time_controller_.AdvanceTime(kInterFrameDelay);
@@ -1475,15 +1475,15 @@
   time_controller_.AdvanceTime(TimeDelta::Seconds(5));
   // Insert two more frames. The interval during the pause should be
   // disregarded in the stats.
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     content_type_,
                                     VideoFrameType::kVideoFrameKey);
   time_controller_.AdvanceTime(kInterFrameDelay);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     content_type_,
                                     VideoFrameType::kVideoFrameDelta);
 
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
     EXPECT_METRIC_EQ(
         1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
@@ -1519,7 +1519,7 @@
   FlushAndGetStats();
   EXPECT_EQ(3u, statistics_proxy_->GetStats().corruption_score_count);
 
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
     EXPECT_METRIC_EQ(
@@ -1553,7 +1553,7 @@
   for (int i = 0; i < kMinRequiredSamples; ++i) {
     VideoFrameMetaData meta = MetaData(frame);
     statistics_proxy_->OnDecodedFrame(
-        meta, absl::nullopt, TimeDelta::Zero(), TimeDelta::Zero(),
+        meta, std::nullopt, TimeDelta::Zero(), TimeDelta::Zero(),
         TimeDelta::Zero(), content_type_, VideoFrameType::kVideoFrameKey);
     statistics_proxy_->OnRenderedFrame(meta);
     time_controller_.AdvanceTime(kInterFrameDelay);
@@ -1562,11 +1562,11 @@
   time_controller_.AdvanceTime(kFreezeDelay);
   VideoFrameMetaData meta = MetaData(frame);
   statistics_proxy_->OnDecodedFrame(
-      meta, absl::nullopt, TimeDelta::Zero(), TimeDelta::Zero(),
+      meta, std::nullopt, TimeDelta::Zero(), TimeDelta::Zero(),
       TimeDelta::Zero(), content_type_, VideoFrameType::kVideoFrameDelta);
   statistics_proxy_->OnRenderedFrame(meta);
 
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   const TimeDelta kExpectedTimeBetweenFreezes =
       kInterFrameDelay * (kMinRequiredSamples - 1);
   const int kExpectedNumberFreezesPerMinute = 60 / kCallDuration.seconds();
@@ -1601,7 +1601,7 @@
 
   for (int i = 0; i < kMinRequiredSamples; ++i) {
     time_controller_.AdvanceTime(kFrameDuration);
-    statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                       content_type_,
                                       VideoFrameType::kVideoFrameKey);
     statistics_proxy_->OnRenderedFrame(MetaData(frame));
@@ -1610,7 +1610,7 @@
   // Freezes and pauses should be included into harmonic frame rate.
   // Add freeze.
   time_controller_.AdvanceTime(kFreezeDuration);
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     content_type_,
                                     VideoFrameType::kVideoFrameDelta);
   statistics_proxy_->OnRenderedFrame(MetaData(frame));
@@ -1618,12 +1618,12 @@
   // Add pause.
   time_controller_.AdvanceTime(kPauseDuration);
   statistics_proxy_->OnStreamInactive();
-  statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                     content_type_,
                                     VideoFrameType::kVideoFrameDelta);
   statistics_proxy_->OnRenderedFrame(MetaData(frame));
 
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   double kSumSquaredFrameDurationSecs =
       (kMinRequiredSamples - 1) *
       (kFrameDuration.seconds<double>() * kFrameDuration.seconds<double>());
@@ -1651,7 +1651,7 @@
   for (int i = 0; i <= kMinRequiredSamples; ++i) {
     VideoFrameMetaData meta = MetaData(frame);
     statistics_proxy_->OnDecodedFrame(
-        meta, absl::nullopt, TimeDelta::Zero(), TimeDelta::Zero(),
+        meta, std::nullopt, TimeDelta::Zero(), TimeDelta::Zero(),
         TimeDelta::Zero(), content_type_, VideoFrameType::kVideoFrameKey);
     statistics_proxy_->OnRenderedFrame(meta);
     time_controller_.AdvanceTime(kInterFrameDelay);
@@ -1663,13 +1663,13 @@
   for (int i = 0; i <= kMinRequiredSamples * 3; ++i) {
     VideoFrameMetaData meta = MetaData(frame);
     statistics_proxy_->OnDecodedFrame(
-        meta, absl::nullopt, TimeDelta::Zero(), TimeDelta::Zero(),
+        meta, std::nullopt, TimeDelta::Zero(), TimeDelta::Zero(),
         TimeDelta::Zero(), content_type_, VideoFrameType::kVideoFrameDelta);
     statistics_proxy_->OnRenderedFrame(meta);
     time_controller_.AdvanceTime(kInterFrameDelay);
   }
 
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   // Average of two playback intervals.
   const TimeDelta kExpectedTimeBetweenFreezes =
       kInterFrameDelay * kMinRequiredSamples * 2;
@@ -1694,19 +1694,19 @@
   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
 
   for (int i = 0; i <= kMinRequiredSamples; ++i) {
-    statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                       content_type_,
                                       VideoFrameType::kVideoFrameKey);
     time_controller_.AdvanceTime(kInterFrameDelay);
     statistics_proxy_->OnStreamInactive();
     time_controller_.AdvanceTime(kPauseDuration);
-    statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, TimeDelta::Zero(),
+    statistics_proxy_->OnDecodedFrame(frame, std::nullopt, TimeDelta::Zero(),
                                       content_type_,
                                       VideoFrameType::kVideoFrameDelta);
     time_controller_.AdvanceTime(kInterFrameDelay);
   }
 
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   // No freezes should be detected, as all long inter-frame delays were
   // pauses.
@@ -1728,7 +1728,7 @@
   for (int i = 0; i < kMinRequiredSamples; ++i) {
     VideoFrameMetaData meta = MetaData(frame_hd);
     statistics_proxy_->OnDecodedFrame(
-        meta, absl::nullopt, TimeDelta::Zero(), TimeDelta::Zero(),
+        meta, std::nullopt, TimeDelta::Zero(), TimeDelta::Zero(),
         TimeDelta::Zero(), content_type_, VideoFrameType::kVideoFrameKey);
     statistics_proxy_->OnRenderedFrame(meta);
     time_controller_.AdvanceTime(kInterFrameDelay);
@@ -1737,7 +1737,7 @@
   for (int i = 0; i < 2 * kMinRequiredSamples; ++i) {
     VideoFrameMetaData meta = MetaData(frame_sd);
     statistics_proxy_->OnDecodedFrame(
-        meta, absl::nullopt, TimeDelta::Zero(), TimeDelta::Zero(),
+        meta, std::nullopt, TimeDelta::Zero(), TimeDelta::Zero(),
         TimeDelta::Zero(), content_type_, VideoFrameType::kVideoFrameKey);
     statistics_proxy_->OnRenderedFrame(meta);
     time_controller_.AdvanceTime(kInterFrameDelay);
@@ -1745,7 +1745,7 @@
   // Extra last frame.
   statistics_proxy_->OnRenderedFrame(MetaData(frame_sd));
 
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   const int kExpectedTimeInHdPercents = 33;
   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
@@ -1788,7 +1788,7 @@
                                     VideoFrameType::kVideoFrameKey);
   statistics_proxy_->OnRenderedFrame(MetaData(frame));
 
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   const int kExpectedTimeInHdPercents = 66;
   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
     EXPECT_METRIC_EQ(
@@ -1811,7 +1811,7 @@
   webrtc::VideoFrame frame_ld = CreateFrame(320, 180);
 
   // Call once to pass content type.
-  statistics_proxy_->OnDecodedFrame(frame_hd, absl::nullopt, TimeDelta::Zero(),
+  statistics_proxy_->OnDecodedFrame(frame_hd, std::nullopt, TimeDelta::Zero(),
                                     content_type_,
                                     VideoFrameType::kVideoFrameKey);
 
@@ -1824,7 +1824,7 @@
   // Downscale.
   statistics_proxy_->OnRenderedFrame(MetaData(frame_ld));
   time_controller_.AdvanceTime(kInterFrameDelay);
-  statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
+  statistics_proxy_->UpdateHistograms(std::nullopt, StreamDataCounters(),
                                       nullptr);
   const int kExpectedDownscales = 30;  // 2 per 4 seconds = 30 per minute.
   if (!videocontenttypehelpers::IsScreenshare(content_type_)) {
@@ -1846,7 +1846,7 @@
                                       VideoFrameType::kVideoFrameKey);
     time_controller_.AdvanceTime(kInterFrameDelay);
   }
-  FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
+  FlushAndUpdateHistograms(std::nullopt, StreamDataCounters(), nullptr);
   EXPECT_METRIC_EQ(
       1, metrics::NumEvents("WebRTC.Video.DecodeTimeInMs", kDecodeTime.ms()));
 }
diff --git a/video/render/BUILD.gn b/video/render/BUILD.gn
index 7940187..6b23583 100644
--- a/video/render/BUILD.gn
+++ b/video/render/BUILD.gn
@@ -26,7 +26,6 @@
     "../../rtc_base:event_tracer",
     "../../rtc_base:macromagic",
     "../../rtc_base:race_checker",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -44,6 +43,5 @@
     "../../rtc_base:logging",
     "../../rtc_base:timeutils",
     "../../system_wrappers:metrics",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
diff --git a/video/render/incoming_video_stream.cc b/video/render/incoming_video_stream.cc
index 650036d..20495eb 100644
--- a/video/render/incoming_video_stream.cc
+++ b/video/render/incoming_video_stream.cc
@@ -11,9 +11,9 @@
 #include "video/render/incoming_video_stream.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/units/time_delta.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/trace_event.h"
@@ -58,7 +58,7 @@
 void IncomingVideoStream::Dequeue() {
   TRACE_EVENT0("webrtc", "IncomingVideoStream::Dequeue");
   RTC_DCHECK_RUN_ON(incoming_render_queue_.get());
-  absl::optional<VideoFrame> frame_to_render = render_buffers_.FrameToRender();
+  std::optional<VideoFrame> frame_to_render = render_buffers_.FrameToRender();
   if (frame_to_render)
     callback_->OnFrame(*frame_to_render);
 
diff --git a/video/render/video_render_frames.cc b/video/render/video_render_frames.cc
index 4b2e703..df17e3c 100644
--- a/video/render/video_render_frames.cc
+++ b/video/render/video_render_frames.cc
@@ -88,8 +88,8 @@
   return static_cast<int32_t>(incoming_frames_.size());
 }
 
-absl::optional<VideoFrame> VideoRenderFrames::FrameToRender() {
-  absl::optional<VideoFrame> render_frame;
+std::optional<VideoFrame> VideoRenderFrames::FrameToRender() {
+  std::optional<VideoFrame> render_frame;
   // Get the newest frame that can be released for rendering.
   while (!incoming_frames_.empty() && TimeToNextFrameRelease() <= 0) {
     if (render_frame) {
diff --git a/video/render/video_render_frames.h b/video/render/video_render_frames.h
index 7f48eae..c69f9df 100644
--- a/video/render/video_render_frames.h
+++ b/video/render/video_render_frames.h
@@ -15,8 +15,8 @@
 #include <stdint.h>
 
 #include <list>
+#include <optional>
 
-#include "absl/types/optional.h"
 #include "api/video/video_frame.h"
 
 namespace webrtc {
@@ -32,7 +32,7 @@
   int32_t AddFrame(VideoFrame&& new_frame);
 
   // Get a frame for rendering, or false if it's not time to render.
-  absl::optional<VideoFrame> FrameToRender();
+  std::optional<VideoFrame> FrameToRender();
 
   // Returns the number of ms to next frame to render
   uint32_t TimeToNextFrameRelease();
diff --git a/video/rtp_streams_synchronizer2.cc b/video/rtp_streams_synchronizer2.cc
index 0fbb391..a38fa9f 100644
--- a/video/rtp_streams_synchronizer2.cc
+++ b/video/rtp_streams_synchronizer2.cc
@@ -10,7 +10,8 @@
 
 #include "video/rtp_streams_synchronizer2.h"
 
-#include "absl/types/optional.h"
+#include <optional>
+
 #include "call/syncable.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
@@ -94,7 +95,7 @@
 
   int64_t last_audio_receive_time_ms =
       audio_measurement_.latest_receive_time_ms;
-  absl::optional<Syncable::Info> audio_info = syncable_audio_->GetInfo();
+  std::optional<Syncable::Info> audio_info = syncable_audio_->GetInfo();
   if (!audio_info || !UpdateMeasurements(&audio_measurement_, *audio_info)) {
     return;
   }
@@ -105,7 +106,7 @@
   }
 
   int64_t last_video_receive_ms = video_measurement_.latest_receive_time_ms;
-  absl::optional<Syncable::Info> video_info = syncable_video_->GetInfo();
+  std::optional<Syncable::Info> video_info = syncable_video_->GetInfo();
   if (!video_info || !UpdateMeasurements(&video_measurement_, *video_info)) {
     return;
   }
diff --git a/video/rtp_video_stream_receiver2.cc b/video/rtp_video_stream_receiver2.cc
index 88417de..d6c859f 100644
--- a/video/rtp_video_stream_receiver2.cc
+++ b/video/rtp_video_stream_receiver2.cc
@@ -13,12 +13,12 @@
 #include <algorithm>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "absl/memory/memory.h"
-#include "absl/types/optional.h"
 #include "api/video/video_codec_type.h"
 #include "media/base/media_constants.h"
 #include "modules/pacing/packet_router.h"
@@ -186,7 +186,7 @@
   RTC_DCHECK(!lntf_state_)
       << "SendLossNotification() called twice in a row with no call to "
          "SendBufferedRtcpFeedback() in between.";
-  lntf_state_ = absl::make_optional<LossNotificationState>(
+  lntf_state_ = std::make_optional<LossNotificationState>(
       last_decoded_seq_num, last_received_seq_num, decodability_flag);
 }
 
@@ -195,7 +195,7 @@
 
   bool request_key_frame = false;
   std::vector<uint16_t> nack_sequence_numbers;
-  absl::optional<LossNotificationState> lntf_state;
+  std::optional<LossNotificationState> lntf_state;
 
   std::swap(request_key_frame, request_key_frame_);
   std::swap(nack_sequence_numbers, nack_sequence_numbers_);
@@ -245,8 +245,8 @@
       config_(*config),
       packet_router_(packet_router),
       ntp_estimator_(&env_.clock()),
-      forced_playout_delay_max_ms_("max_ms", absl::nullopt),
-      forced_playout_delay_min_ms_("min_ms", absl::nullopt),
+      forced_playout_delay_max_ms_("max_ms", std::nullopt),
+      forced_playout_delay_min_ms_("min_ms", std::nullopt),
       rtp_receive_statistics_(rtp_receive_statistics),
       ulpfec_receiver_(
           MaybeConstructUlpfecReceiver(config->rtp.remote_ssrc,
@@ -369,20 +369,20 @@
   h26x_packet_buffer_.reset();
 }
 
-absl::optional<Syncable::Info> RtpVideoStreamReceiver2::GetSyncInfo() const {
+std::optional<Syncable::Info> RtpVideoStreamReceiver2::GetSyncInfo() const {
   RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
   Syncable::Info info;
-  absl::optional<RtpRtcpInterface::SenderReportStats> last_sr =
+  std::optional<RtpRtcpInterface::SenderReportStats> last_sr =
       rtp_rtcp_->GetSenderReportStats();
   if (!last_sr.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   info.capture_time_ntp_secs = last_sr->last_remote_timestamp.seconds();
   info.capture_time_ntp_frac = last_sr->last_remote_timestamp.fractions();
   info.capture_time_source_clock = last_sr->last_remote_rtp_timestamp;
 
   if (!last_received_rtp_timestamp_ || !last_received_rtp_system_time_) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   info.latest_received_capture_timestamp = *last_received_rtp_timestamp_;
   info.latest_receive_time_ms = last_received_rtp_system_time_->ms();
@@ -548,7 +548,7 @@
     if (!video_header.playout_delay.emplace().Set(
             TimeDelta::Millis(*forced_playout_delay_min_ms_),
             TimeDelta::Millis(*forced_playout_delay_max_ms_))) {
-      video_header.playout_delay = absl::nullopt;
+      video_header.playout_delay = std::nullopt;
     }
   } else {
     video_header.playout_delay = rtp_packet.GetExtension<PlayoutDelayLimits>();
@@ -826,7 +826,7 @@
   RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
   RTC_DCHECK(frame);
 
-  const absl::optional<RTPVideoHeader::GenericDescriptorInfo>& descriptor =
+  const std::optional<RTPVideoHeader::GenericDescriptorInfo>& descriptor =
       frame->GetRtpVideoHeader().generic;
 
   if (loss_notification_controller_ && descriptor) {
@@ -1013,31 +1013,31 @@
                                    ulpfec_payload_type, this, &env_.clock());
 }
 
-absl::optional<int64_t> RtpVideoStreamReceiver2::LastReceivedPacketMs() const {
+std::optional<int64_t> RtpVideoStreamReceiver2::LastReceivedPacketMs() const {
   RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
   if (last_received_rtp_system_time_) {
-    return absl::optional<int64_t>(last_received_rtp_system_time_->ms());
+    return std::optional<int64_t>(last_received_rtp_system_time_->ms());
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<uint32_t>
-RtpVideoStreamReceiver2::LastReceivedFrameRtpTimestamp() const {
+std::optional<uint32_t> RtpVideoStreamReceiver2::LastReceivedFrameRtpTimestamp()
+    const {
   RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
   return last_received_rtp_timestamp_;
 }
 
-absl::optional<int64_t> RtpVideoStreamReceiver2::LastReceivedKeyframePacketMs()
+std::optional<int64_t> RtpVideoStreamReceiver2::LastReceivedKeyframePacketMs()
     const {
   RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
   if (last_received_keyframe_rtp_system_time_) {
-    return absl::optional<int64_t>(
+    return std::optional<int64_t>(
         last_received_keyframe_rtp_system_time_->ms());
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<RtpRtcpInterface::SenderReportStats>
+std::optional<RtpRtcpInterface::SenderReportStats>
 RtpVideoStreamReceiver2::GetSenderReportStats() const {
   RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
   return rtp_rtcp_->GetSenderReportStats();
@@ -1071,9 +1071,9 @@
 
   auto parse_and_insert = [&](const RtpPacketReceived& packet) {
     RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
-    absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload =
+    std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload =
         type_it->second->Parse(packet.PayloadBuffer());
-    if (parsed_payload == absl::nullopt) {
+    if (parsed_payload == std::nullopt) {
       RTC_LOG(LS_WARNING) << "Failed parsing payload.";
       return false;
     }
@@ -1164,13 +1164,13 @@
   rtp_rtcp_->IncomingRtcpPacket(
       rtc::MakeArrayView(rtcp_packet, rtcp_packet_length));
 
-  absl::optional<TimeDelta> rtt = rtp_rtcp_->LastRtt();
+  std::optional<TimeDelta> rtt = rtp_rtcp_->LastRtt();
   if (!rtt.has_value()) {
     // Waiting for valid rtt.
     return true;
   }
 
-  absl::optional<RtpRtcpInterface::SenderReportStats> last_sr =
+  std::optional<RtpRtcpInterface::SenderReportStats> last_sr =
       rtp_rtcp_->GetSenderReportStats();
   if (!last_sr.has_value()) {
     // Waiting for RTCP.
@@ -1182,7 +1182,7 @@
   if (time_since_received <= 1) {
     ntp_estimator_.UpdateRtcpTimestamp(*rtt, last_sr->last_remote_timestamp,
                                        last_sr->last_remote_rtp_timestamp);
-    absl::optional<int64_t> remote_to_local_clock_offset =
+    std::optional<int64_t> remote_to_local_clock_offset =
         ntp_estimator_.EstimateRemoteToLocalClockOffset();
     if (remote_to_local_clock_offset.has_value()) {
       capture_clock_offset_updater_.SetRemoteToLocalClockOffset(
diff --git a/video/rtp_video_stream_receiver2.h b/video/rtp_video_stream_receiver2.h
index 221fc09..141f15c 100644
--- a/video/rtp_video_stream_receiver2.h
+++ b/video/rtp_video_stream_receiver2.h
@@ -13,10 +13,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/crypto/frame_decryptor_interface.h"
 #include "api/environment/environment.h"
 #include "api/sequence_checker.h"
@@ -112,7 +112,7 @@
   void StopReceive();
 
   // Produces the transport-related timestamps; current_delay_ms is left unset.
-  absl::optional<Syncable::Info> GetSyncInfo() const;
+  std::optional<Syncable::Info> GetSyncInfo() const;
 
   bool DeliverRtcp(const uint8_t* rtcp_packet, size_t rtcp_packet_length);
 
@@ -204,11 +204,11 @@
   int red_payload_type() const;
   void SetProtectionPayloadTypes(int red_payload_type, int ulpfec_payload_type);
 
-  absl::optional<int64_t> LastReceivedPacketMs() const;
-  absl::optional<uint32_t> LastReceivedFrameRtpTimestamp() const;
-  absl::optional<int64_t> LastReceivedKeyframePacketMs() const;
+  std::optional<int64_t> LastReceivedPacketMs() const;
+  std::optional<uint32_t> LastReceivedFrameRtpTimestamp() const;
+  std::optional<int64_t> LastReceivedKeyframePacketMs() const;
 
-  absl::optional<RtpRtcpInterface::SenderReportStats> GetSenderReportStats()
+  std::optional<RtpRtcpInterface::SenderReportStats> GetSenderReportStats()
       const;
 
  private:
@@ -279,7 +279,7 @@
     std::vector<uint16_t> nack_sequence_numbers_
         RTC_GUARDED_BY(packet_sequence_checker_);
 
-    absl::optional<LossNotificationState> lntf_state_
+    std::optional<LossNotificationState> lntf_state_
         RTC_GUARDED_BY(packet_sequence_checker_);
   };
   enum ParseGenericDependenciesResult {
@@ -353,7 +353,7 @@
   const KeyFrameReqMethod keyframe_request_method_;
 
   RtcpFeedbackBuffer rtcp_feedback_buffer_;
-  // TODO(tommi): Consider absl::optional<NackRequester> instead of unique_ptr
+  // TODO(tommi): Consider std::optional<NackRequester> instead of unique_ptr
   // since nack is usually configured.
   std::unique_ptr<NackRequester> nack_module_
       RTC_GUARDED_BY(packet_sequence_checker_);
@@ -377,15 +377,15 @@
   std::unique_ptr<FrameDependencyStructure> video_structure_
       RTC_GUARDED_BY(packet_sequence_checker_);
   // Frame id of the last frame with the attached video structure.
-  // absl::nullopt when `video_structure_ == nullptr`;
-  absl::optional<int64_t> video_structure_frame_id_
+  // std::nullopt when `video_structure_ == nullptr`;
+  std::optional<int64_t> video_structure_frame_id_
       RTC_GUARDED_BY(packet_sequence_checker_);
   Timestamp last_logged_failed_to_parse_dd_
       RTC_GUARDED_BY(packet_sequence_checker_) = Timestamp::MinusInfinity();
 
   std::unique_ptr<RtpFrameReferenceFinder> reference_finder_
       RTC_GUARDED_BY(packet_sequence_checker_);
-  absl::optional<VideoCodecType> current_codec_
+  std::optional<VideoCodecType> current_codec_
       RTC_GUARDED_BY(packet_sequence_checker_);
   uint32_t last_assembled_frame_rtp_timestamp_
       RTC_GUARDED_BY(packet_sequence_checker_);
@@ -408,13 +408,13 @@
 
   bool has_received_frame_ RTC_GUARDED_BY(packet_sequence_checker_);
 
-  absl::optional<uint32_t> last_received_rtp_timestamp_
+  std::optional<uint32_t> last_received_rtp_timestamp_
       RTC_GUARDED_BY(packet_sequence_checker_);
-  absl::optional<uint32_t> last_received_keyframe_rtp_timestamp_
+  std::optional<uint32_t> last_received_keyframe_rtp_timestamp_
       RTC_GUARDED_BY(packet_sequence_checker_);
-  absl::optional<Timestamp> last_received_rtp_system_time_
+  std::optional<Timestamp> last_received_rtp_system_time_
       RTC_GUARDED_BY(packet_sequence_checker_);
-  absl::optional<Timestamp> last_received_keyframe_rtp_system_time_
+  std::optional<Timestamp> last_received_keyframe_rtp_system_time_
       RTC_GUARDED_BY(packet_sequence_checker_);
 
   // Handles incoming encrypted frames and forwards them to the
@@ -422,7 +422,7 @@
   std::unique_ptr<BufferedFrameDecryptor> buffered_frame_decryptor_
       RTC_PT_GUARDED_BY(packet_sequence_checker_);
   bool frames_decryptable_ RTC_GUARDED_BY(worker_task_checker_);
-  absl::optional<ColorSpace> last_color_space_;
+  std::optional<ColorSpace> last_color_space_;
 
   AbsoluteCaptureTimeInterpolator absolute_capture_time_interpolator_
       RTC_GUARDED_BY(packet_sequence_checker_);
diff --git a/video/rtp_video_stream_receiver2_unittest.cc b/video/rtp_video_stream_receiver2_unittest.cc
index 335bb81..0034f72 100644
--- a/video/rtp_video_stream_receiver2_unittest.cc
+++ b/video/rtp_video_stream_receiver2_unittest.cc
@@ -400,7 +400,7 @@
   rtp_packet.SetSsrc(kSsrc);
   rtp_packet.SetExtension<AbsoluteCaptureTimeExtension>(
       AbsoluteCaptureTime{kAbsoluteCaptureTimestamp,
-                          /*estimated_capture_clock_offset=*/absl::nullopt});
+                          /*estimated_capture_clock_offset=*/std::nullopt});
 
   RTPVideoHeader video_header =
       GetGenericVideoHeader(VideoFrameType::kVideoFrameKey);
@@ -433,7 +433,7 @@
   rtp_packet.SetSsrc(kSsrc);
   rtp_packet.SetExtension<AbsoluteCaptureTimeExtension>(
       AbsoluteCaptureTime{kAbsoluteCaptureTimestamp,
-                          /*estimated_capture_clock_offset=*/absl::nullopt});
+                          /*estimated_capture_clock_offset=*/std::nullopt});
 
   RTPVideoHeader video_header =
       GetGenericVideoHeader(VideoFrameType::kVideoFrameKey);
diff --git a/video/screenshare_loopback.cc b/video/screenshare_loopback.cc
index 882e58f..c6cade7 100644
--- a/video/screenshare_loopback.cc
+++ b/video/screenshare_loopback.cc
@@ -11,12 +11,12 @@
 #include <stdio.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/flags/flag.h"
 #include "absl/flags/parse.h"
-#include "absl/types/optional.h"
 #include "api/test/simulated_network.h"
 #include "api/test/video_quality_test_fixture.h"
 #include "api/transport/bitrate_settings.h"
diff --git a/video/send_statistics_proxy.cc b/video/send_statistics_proxy.cc
index 324a5d6..8c97a27 100644
--- a/video/send_statistics_proxy.cc
+++ b/video/send_statistics_proxy.cc
@@ -97,38 +97,38 @@
           codec_info->codecSpecific.VP8.temporalIdx == kNoTemporalIdx);
 }
 
-absl::optional<int> GetFallbackMaxPixels(const std::string& group) {
+std::optional<int> GetFallbackMaxPixels(const std::string& group) {
   if (group.empty())
-    return absl::nullopt;
+    return std::nullopt;
 
   int min_pixels;
   int max_pixels;
   int min_bps;
   if (sscanf(group.c_str(), "-%d,%d,%d", &min_pixels, &max_pixels, &min_bps) !=
       3) {
-    return absl::optional<int>();
+    return std::optional<int>();
   }
 
   if (min_pixels <= 0 || max_pixels <= 0 || max_pixels < min_pixels)
-    return absl::optional<int>();
+    return std::optional<int>();
 
-  return absl::optional<int>(max_pixels);
+  return std::optional<int>(max_pixels);
 }
 
-absl::optional<int> GetFallbackMaxPixelsIfFieldTrialEnabled(
+std::optional<int> GetFallbackMaxPixelsIfFieldTrialEnabled(
     const webrtc::FieldTrialsView& field_trials) {
   std::string group = field_trials.Lookup(kVp8ForcedFallbackEncoderFieldTrial);
   return (absl::StartsWith(group, "Enabled"))
              ? GetFallbackMaxPixels(group.substr(7))
-             : absl::optional<int>();
+             : std::optional<int>();
 }
 
-absl::optional<int> GetFallbackMaxPixelsIfFieldTrialDisabled(
+std::optional<int> GetFallbackMaxPixelsIfFieldTrialDisabled(
     const webrtc::FieldTrialsView& field_trials) {
   std::string group = field_trials.Lookup(kVp8ForcedFallbackEncoderFieldTrial);
   return (absl::StartsWith(group, "Disabled"))
              ? GetFallbackMaxPixels(group.substr(8))
-             : absl::optional<int>();
+             : std::optional<int>();
 }
 }  // namespace
 
@@ -978,7 +978,7 @@
   stats->total_encode_time_ms += encoded_image.timing_.encode_finish_ms -
                                  encoded_image.timing_.encode_start_ms;
   stats->scalability_mode =
-      codec_info ? codec_info->scalability_mode : absl::nullopt;
+      codec_info ? codec_info->scalability_mode : std::nullopt;
   // Report resolution of the top spatial layer.
   bool is_top_spatial_layer =
       codec_info == nullptr || codec_info->end_of_picture;
@@ -1040,7 +1040,7 @@
     track.encoded_frame_rate.AddSamples(1);
   }
 
-  absl::optional<int> downscales =
+  std::optional<int> downscales =
       adaptation_limitations_.MaskedQualityCounts().resolution_adaptations;
   stats_.bw_limited_resolution |=
       (downscales.has_value() && downscales.value() > 0);
@@ -1063,7 +1063,7 @@
   // Clear cached scalability mode values, they may no longer be accurate.
   for (auto& pair : stats_.substreams) {
     VideoSendStream::StreamStats& stream_stats = pair.second;
-    stream_stats.scalability_mode = absl::nullopt;
+    stream_stats.scalability_mode = std::nullopt;
   }
 }
 
@@ -1271,8 +1271,8 @@
 }
 
 void SendStatisticsProxy::TryUpdateInitialQualityResolutionAdaptUp(
-    absl::optional<int> old_quality_downscales,
-    absl::optional<int> updated_quality_downscales) {
+    std::optional<int> old_quality_downscales,
+    std::optional<int> updated_quality_downscales) {
   if (uma_container_->initial_quality_changes_.down == 0)
     return;
 
diff --git a/video/send_statistics_proxy.h b/video/send_statistics_proxy.h
index e9ac243..ab1605c 100644
--- a/video/send_statistics_proxy.h
+++ b/video/send_statistics_proxy.h
@@ -167,7 +167,7 @@
     bool is_active = false;
     int on_off_events = 0;
     int64_t elapsed_ms = 0;
-    absl::optional<int64_t> last_update_ms;
+    std::optional<int64_t> last_update_ms;
     const int max_frame_diff_ms = 2000;
   };
   struct FallbackEncoderInfoDisabled {
@@ -218,8 +218,8 @@
       RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 
   struct MaskedAdaptationCounts {
-    absl::optional<int> resolution_adaptations = absl::nullopt;
-    absl::optional<int> num_framerate_reductions = absl::nullopt;
+    std::optional<int> resolution_adaptations = std::nullopt;
+    std::optional<int> num_framerate_reductions = std::nullopt;
   };
 
   struct Adaptations {
@@ -275,8 +275,8 @@
       RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
   void UpdateAdaptationStats() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
   void TryUpdateInitialQualityResolutionAdaptUp(
-      absl::optional<int> old_quality_downscales,
-      absl::optional<int> updated_quality_downscales)
+      std::optional<int> old_quality_downscales,
+      std::optional<int> updated_quality_downscales)
       RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 
   void UpdateEncoderFallbackStats(const CodecSpecificInfo* codec_info,
@@ -291,8 +291,8 @@
   Clock* const clock_;
   const std::string payload_name_;
   const RtpConfig rtp_config_;
-  const absl::optional<int> fallback_max_pixels_;
-  const absl::optional<int> fallback_max_pixels_disabled_;
+  const std::optional<int> fallback_max_pixels_;
+  const std::optional<int> fallback_max_pixels_disabled_;
   mutable Mutex mutex_;
   VideoEncoderConfig::ContentType content_type_ RTC_GUARDED_BY(mutex_);
   const int64_t start_ms_;
@@ -305,7 +305,7 @@
   // Trackers mapped by ssrc.
   std::map<uint32_t, Trackers> trackers_ RTC_GUARDED_BY(mutex_);
 
-  absl::optional<int64_t> last_outlier_timestamp_ RTC_GUARDED_BY(mutex_);
+  std::optional<int64_t> last_outlier_timestamp_ RTC_GUARDED_BY(mutex_);
 
   int last_num_spatial_layers_ RTC_GUARDED_BY(mutex_);
   int last_num_simulcast_streams_ RTC_GUARDED_BY(mutex_);
@@ -324,7 +324,7 @@
   };
   // Stores the last change in encoder implementation in an optional, so that
   // the event can be consumed.
-  absl::optional<EncoderChangeEvent> encoder_changed_;
+  std::optional<EncoderChangeEvent> encoder_changed_;
 
   // Contains stats used for UMA histograms. These stats will be reset if
   // content type changes between real-time video and screenshare, since these
diff --git a/video/send_statistics_proxy_unittest.cc b/video/send_statistics_proxy_unittest.cc
index f743299..01b0349 100644
--- a/video/send_statistics_proxy_unittest.cc
+++ b/video/send_statistics_proxy_unittest.cc
@@ -382,7 +382,7 @@
   EncodedImage encoded_image;
   CodecSpecificInfo codec_info;
   auto ssrc = config_.rtp.ssrcs[0];
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             statistics_proxy_->GetStats().substreams[ssrc].qp_sum);
   encoded_image.qp_ = 3;
   statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
@@ -397,10 +397,10 @@
   CodecSpecificInfo codec_info;
   auto ssrc = config_.rtp.ssrcs[0];
   encoded_image.qp_ = -1;
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             statistics_proxy_->GetStats().substreams[ssrc].qp_sum);
   statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             statistics_proxy_->GetStats().substreams[ssrc].qp_sum);
 }
 
@@ -412,16 +412,16 @@
   ScalabilityMode layer1_mode = ScalabilityMode::kL1T3;
   auto ssrc0 = config_.rtp.ssrcs[0];
   auto ssrc1 = config_.rtp.ssrcs[1];
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             statistics_proxy_->GetStats().substreams[ssrc0].scalability_mode);
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             statistics_proxy_->GetStats().substreams[ssrc1].scalability_mode);
   encoded_image.SetSimulcastIndex(0);
   codec_info.scalability_mode = layer0_mode;
   statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
   EXPECT_THAT(statistics_proxy_->GetStats().substreams[ssrc0].scalability_mode,
               layer0_mode);
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             statistics_proxy_->GetStats().substreams[ssrc1].scalability_mode);
   encoded_image.SetSimulcastIndex(1);
   codec_info.scalability_mode = layer1_mode;
@@ -2533,7 +2533,7 @@
 
   EXPECT_NE(GetStreamStats(kFirstSsrc).type,
             VideoSendStream::StreamStats::StreamType::kRtx);
-  EXPECT_EQ(GetStreamStats(kFirstSsrc).referenced_media_ssrc, absl::nullopt);
+  EXPECT_EQ(GetStreamStats(kFirstSsrc).referenced_media_ssrc, std::nullopt);
   EXPECT_EQ(GetStreamStats(kFirstRtxSsrc).type,
             VideoSendStream::StreamStats::StreamType::kRtx);
   EXPECT_EQ(GetStreamStats(kFirstRtxSsrc).referenced_media_ssrc, kFirstSsrc);
@@ -2553,7 +2553,7 @@
 
   EXPECT_NE(GetStreamStats(kFirstSsrc).type,
             VideoSendStream::StreamStats::StreamType::kFlexfec);
-  EXPECT_EQ(GetStreamStats(kFirstSsrc).referenced_media_ssrc, absl::nullopt);
+  EXPECT_EQ(GetStreamStats(kFirstSsrc).referenced_media_ssrc, std::nullopt);
   EXPECT_EQ(GetStreamStats(kFlexFecSsrc).type,
             VideoSendStream::StreamStats::StreamType::kFlexfec);
   EXPECT_EQ(GetStreamStats(kFlexFecSsrc).referenced_media_ssrc, kFirstSsrc);
diff --git a/video/sv_loopback.cc b/video/sv_loopback.cc
index 86bdaf5..7d22030 100644
--- a/video/sv_loopback.cc
+++ b/video/sv_loopback.cc
@@ -11,12 +11,12 @@
 #include <stdio.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/flags/flag.h"
 #include "absl/flags/parse.h"
-#include "absl/types/optional.h"
 #include "api/test/simulated_network.h"
 #include "api/test/video_quality_test_fixture.h"
 #include "api/transport/bitrate_settings.h"
diff --git a/video/task_queue_frame_decode_scheduler.cc b/video/task_queue_frame_decode_scheduler.cc
index cd109c2..624f8ab 100644
--- a/video/task_queue_frame_decode_scheduler.cc
+++ b/video/task_queue_frame_decode_scheduler.cc
@@ -53,18 +53,17 @@
                  // this scheduled release should be skipped.
                  if (scheduled_rtp_ != rtp)
                    return;
-                 scheduled_rtp_ = absl::nullopt;
+                 scheduled_rtp_ = std::nullopt;
                  std::move(cb)(rtp, schedule.render_time);
                }),
       wait);
 }
 
 void TaskQueueFrameDecodeScheduler::CancelOutstanding() {
-  scheduled_rtp_ = absl::nullopt;
+  scheduled_rtp_ = std::nullopt;
 }
 
-absl::optional<uint32_t>
-TaskQueueFrameDecodeScheduler::ScheduledRtpTimestamp() {
+std::optional<uint32_t> TaskQueueFrameDecodeScheduler::ScheduledRtpTimestamp() {
   return scheduled_rtp_;
 }
 
diff --git a/video/task_queue_frame_decode_scheduler.h b/video/task_queue_frame_decode_scheduler.h
index 69c6dae..1d95c3e 100644
--- a/video/task_queue_frame_decode_scheduler.h
+++ b/video/task_queue_frame_decode_scheduler.h
@@ -27,7 +27,7 @@
       const TaskQueueFrameDecodeScheduler&) = delete;
 
   // FrameDecodeScheduler implementation.
-  absl::optional<uint32_t> ScheduledRtpTimestamp() override;
+  std::optional<uint32_t> ScheduledRtpTimestamp() override;
   void ScheduleFrame(uint32_t rtp,
                      FrameDecodeTiming::FrameSchedule schedule,
                      FrameReleaseCallback cb) override;
@@ -38,7 +38,7 @@
   Clock* const clock_;
   TaskQueueBase* const bookkeeping_queue_;
 
-  absl::optional<uint32_t> scheduled_rtp_;
+  std::optional<uint32_t> scheduled_rtp_;
   ScopedTaskSafetyDetached task_safety_;
   bool stopped_ = false;
 };
diff --git a/video/task_queue_frame_decode_scheduler_unittest.cc b/video/task_queue_frame_decode_scheduler_unittest.cc
index 20258c6..38b43e6 100644
--- a/video/task_queue_frame_decode_scheduler_unittest.cc
+++ b/video/task_queue_frame_decode_scheduler_unittest.cc
@@ -13,9 +13,9 @@
 #include <stddef.h>
 
 #include <memory>
+#include <optional>
 #include <utility>
 
-#include "absl/types/optional.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
 #include "test/gmock.h"
@@ -93,7 +93,7 @@
   time_controller_.AdvanceTime(decode_delay / 2);
   EXPECT_THAT(scheduler.ScheduledRtpTimestamp(), Optional(rtp));
   scheduler.CancelOutstanding();
-  EXPECT_THAT(scheduler.ScheduledRtpTimestamp(), Eq(absl::nullopt));
+  EXPECT_THAT(scheduler.ScheduledRtpTimestamp(), Eq(std::nullopt));
   time_controller_.AdvanceTime(decode_delay / 2);
 
   scheduler.Stop();
diff --git a/video/video_analyzer.h b/video/video_analyzer.h
index 8c8100c..ee0cda9 100644
--- a/video/video_analyzer.h
+++ b/video/video_analyzer.h
@@ -110,8 +110,8 @@
                     int64_t render_time_ms,
                     size_t encoded_frame_size);
 
-    absl::optional<VideoFrame> reference;
-    absl::optional<VideoFrame> render;
+    std::optional<VideoFrame> reference;
+    std::optional<VideoFrame> render;
     bool dropped;
     int64_t input_time_ms;
     int64_t send_time_ms;
@@ -259,7 +259,7 @@
   SamplesStatsCounter audio_jitter_buffer_ms_ RTC_GUARDED_BY(comparison_lock_);
   SamplesStatsCounter pixels_ RTC_GUARDED_BY(comparison_lock_);
   // Rendered frame with worst PSNR is saved for further analysis.
-  absl::optional<FrameWithPsnr> worst_frame_ RTC_GUARDED_BY(comparison_lock_);
+  std::optional<FrameWithPsnr> worst_frame_ RTC_GUARDED_BY(comparison_lock_);
   // Freeze metrics.
   SamplesStatsCounter time_between_freezes_ RTC_GUARDED_BY(comparison_lock_);
   uint32_t freeze_count_ RTC_GUARDED_BY(comparison_lock_);
@@ -292,13 +292,13 @@
   int64_t wallclock_time_ RTC_GUARDED_BY(cpu_measurement_lock_);
 
   std::deque<VideoFrame> frames_ RTC_GUARDED_BY(lock_);
-  absl::optional<VideoFrame> last_rendered_frame_ RTC_GUARDED_BY(lock_);
+  std::optional<VideoFrame> last_rendered_frame_ RTC_GUARDED_BY(lock_);
   RtpTimestampUnwrapper wrap_handler_ RTC_GUARDED_BY(lock_);
   std::map<int64_t, int64_t> send_times_ RTC_GUARDED_BY(lock_);
   std::map<int64_t, int64_t> recv_times_ RTC_GUARDED_BY(lock_);
   std::map<int64_t, size_t> encoded_frame_sizes_ RTC_GUARDED_BY(lock_);
-  absl::optional<uint32_t> first_encoded_timestamp_ RTC_GUARDED_BY(lock_);
-  absl::optional<uint32_t> first_sent_timestamp_ RTC_GUARDED_BY(lock_);
+  std::optional<uint32_t> first_encoded_timestamp_ RTC_GUARDED_BY(lock_);
+  std::optional<uint32_t> first_sent_timestamp_ RTC_GUARDED_BY(lock_);
   const double avg_psnr_threshold_;
   const double avg_ssim_threshold_;
   bool is_quick_test_enabled_;
diff --git a/video/video_loopback.cc b/video/video_loopback.cc
index 6358105..bcd3b35 100644
--- a/video/video_loopback.cc
+++ b/video/video_loopback.cc
@@ -12,12 +12,12 @@
 #include <stdio.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "absl/flags/flag.h"
 #include "absl/flags/parse.h"
-#include "absl/types/optional.h"
 #include "api/test/simulated_network.h"
 #include "api/test/video_quality_test_fixture.h"
 #include "api/transport/bitrate_settings.h"
diff --git a/video/video_quality_observer2.cc b/video/video_quality_observer2.cc
index 0afc2f5..421ed10 100644
--- a/video/video_quality_observer2.cc
+++ b/video/video_quality_observer2.cc
@@ -165,7 +165,7 @@
 
       bool was_freeze = false;
       if (render_interframe_delays_.Size() >= kMinFrameSamplesToDetectFreeze) {
-        const absl::optional<int64_t> avg_interframe_delay =
+        const std::optional<int64_t> avg_interframe_delay =
             render_interframe_delays_.GetAverageRoundedDown();
         RTC_DCHECK(avg_interframe_delay);
         was_freeze = interframe_delay_ms >=
@@ -231,12 +231,12 @@
 }
 
 void VideoQualityObserver::OnDecodedFrame(uint32_t rtp_frame_timestamp,
-                                          absl::optional<uint8_t> qp,
+                                          std::optional<uint8_t> qp,
                                           VideoCodecType codec) {
   if (!qp)
     return;
 
-  absl::optional<int> qp_blocky_threshold;
+  std::optional<int> qp_blocky_threshold;
   // TODO(ilnik): add other codec types when we have QP for them.
   switch (codec) {
     case kVideoCodecVP8:
@@ -246,7 +246,7 @@
       qp_blocky_threshold = kBlockyQpThresholdVp9;
       break;
     default:
-      qp_blocky_threshold = absl::nullopt;
+      qp_blocky_threshold = std::nullopt;
   }
 
   RTC_DCHECK(blocky_frames_.find(rtp_frame_timestamp) == blocky_frames_.end());
diff --git a/video/video_quality_observer2.h b/video/video_quality_observer2.h
index 3587785..00650b5 100644
--- a/video/video_quality_observer2.h
+++ b/video/video_quality_observer2.h
@@ -13,10 +13,10 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <set>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/video/video_codec_type.h"
 #include "api/video/video_content_type.h"
 #include "rtc_base/numerics/moving_average.h"
@@ -37,7 +37,7 @@
   ~VideoQualityObserver() = default;
 
   void OnDecodedFrame(uint32_t rtp_frame_timestamp,
-                      absl::optional<uint8_t> qp,
+                      std::optional<uint8_t> qp,
                       VideoCodecType codec);
 
   void OnRenderedFrame(const VideoFrameMetaData& frame_meta);
diff --git a/video/video_quality_test.cc b/video/video_quality_test.cc
index 571547e..824f088 100644
--- a/video/video_quality_test.cc
+++ b/video/video_quality_test.cc
@@ -805,7 +805,7 @@
 
     decode_all_receive_streams = params_.ss[video_idx].selected_stream ==
                                  params_.ss[video_idx].streams.size();
-    absl::optional<int> decode_sub_stream;
+    std::optional<int> decode_sub_stream;
     if (!decode_all_receive_streams)
       decode_sub_stream = params_.ss[video_idx].selected_stream;
     CreateMatchingVideoReceiveConfigs(
@@ -978,10 +978,10 @@
     thumbnail_encoder_configs_.push_back(thumbnail_encoder_config.Copy());
     thumbnail_send_configs_.push_back(thumbnail_send_config.Copy());
 
-    AddMatchingVideoReceiveConfigs(
-        &thumbnail_receive_configs_, thumbnail_send_config, send_transport,
-        &video_decoder_factory_, absl::nullopt, false,
-        test::VideoTestConstants::kNackRtpHistoryMs);
+    AddMatchingVideoReceiveConfigs(&thumbnail_receive_configs_,
+                                   thumbnail_send_config, send_transport,
+                                   &video_decoder_factory_, std::nullopt, false,
+                                   test::VideoTestConstants::kNackRtpHistoryMs);
   }
   for (size_t i = 0; i < thumbnail_send_configs_.size(); ++i) {
     thumbnail_send_streams_.push_back(receiver_call_->CreateVideoSendStream(
@@ -1019,7 +1019,7 @@
             clock_,
             test::CreateSquareFrameGenerator(static_cast<int>(thumbnail.width),
                                              static_cast<int>(thumbnail.height),
-                                             absl::nullopt, absl::nullopt),
+                                             std::nullopt, std::nullopt),
             thumbnail.max_framerate, *task_queue_factory_);
     EXPECT_TRUE(frame_generator_capturer->Init());
     thumbnail_capturers_.push_back(std::move(frame_generator_capturer));
@@ -1086,23 +1086,23 @@
     } else if (params_.video[video_idx].clip_path == "Generator") {
       frame_generator = test::CreateSquareFrameGenerator(
           static_cast<int>(params_.video[video_idx].width),
-          static_cast<int>(params_.video[video_idx].height), absl::nullopt,
-          absl::nullopt);
+          static_cast<int>(params_.video[video_idx].height), std::nullopt,
+          std::nullopt);
     } else if (params_.video[video_idx].clip_path == "GeneratorI420A") {
       frame_generator = test::CreateSquareFrameGenerator(
           static_cast<int>(params_.video[video_idx].width),
           static_cast<int>(params_.video[video_idx].height),
-          test::FrameGeneratorInterface::OutputType::kI420A, absl::nullopt);
+          test::FrameGeneratorInterface::OutputType::kI420A, std::nullopt);
     } else if (params_.video[video_idx].clip_path == "GeneratorI010") {
       frame_generator = test::CreateSquareFrameGenerator(
           static_cast<int>(params_.video[video_idx].width),
           static_cast<int>(params_.video[video_idx].height),
-          test::FrameGeneratorInterface::OutputType::kI010, absl::nullopt);
+          test::FrameGeneratorInterface::OutputType::kI010, std::nullopt);
     } else if (params_.video[video_idx].clip_path == "GeneratorNV12") {
       frame_generator = test::CreateSquareFrameGenerator(
           static_cast<int>(params_.video[video_idx].width),
           static_cast<int>(params_.video[video_idx].height),
-          test::FrameGeneratorInterface::OutputType::kNV12, absl::nullopt);
+          test::FrameGeneratorInterface::OutputType::kNV12, std::nullopt);
     } else if (params_.video[video_idx].clip_path.empty()) {
       video_sources_[video_idx] = test::CreateVideoCapturer(
           params_.video[video_idx].width, params_.video[video_idx].height,
@@ -1114,8 +1114,8 @@
         // Failed to get actual camera, use chroma generator as backup.
         frame_generator = test::CreateSquareFrameGenerator(
             static_cast<int>(params_.video[video_idx].width),
-            static_cast<int>(params_.video[video_idx].height), absl::nullopt,
-            absl::nullopt);
+            static_cast<int>(params_.video[video_idx].height), std::nullopt,
+            std::nullopt);
       }
     } else {
       frame_generator = test::CreateFromYuvFileFrameGenerator(
diff --git a/video/video_receive_stream2.cc b/video/video_receive_stream2.cc
index 85a3afa..c6a20ef 100644
--- a/video/video_receive_stream2.cc
+++ b/video/video_receive_stream2.cc
@@ -15,12 +15,12 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/crypto/frame_decryptor_interface.h"
 #include "api/scoped_refptr.h"
@@ -89,7 +89,7 @@
     return buffer_;
   }
 
-  absl::optional<webrtc::ColorSpace> color_space() const override {
+  std::optional<webrtc::ColorSpace> color_space() const override {
     return color_space_;
   }
 
@@ -109,7 +109,7 @@
   VideoCodecType codec_;
   bool is_key_frame_;
   EncodedResolution resolution_;
-  absl::optional<webrtc::ColorSpace> color_space_;
+  std::optional<webrtc::ColorSpace> color_space_;
 };
 
 RenderResolution InitialDecoderResolution(const FieldTrialsView& field_trials) {
@@ -157,7 +157,7 @@
          frame.EncodedImage()._encodedHeight == 0;
 }
 
-std::string OptionalDelayToLogString(const absl::optional<TimeDelta> opt) {
+std::string OptionalDelayToLogString(const std::optional<TimeDelta> opt) {
   return opt.has_value() ? ToLogString(*opt) : "<unset>";
 }
 
@@ -566,7 +566,7 @@
     }
   }
 
-  absl::optional<RtpRtcpInterface::SenderReportStats> rtcp_sr_stats =
+  std::optional<RtpRtcpInterface::SenderReportStats> rtcp_sr_stats =
       rtp_video_stream_receiver_.GetSenderReportStats();
   if (rtcp_sr_stats) {
     stats.last_sender_report_timestamp_ms =
@@ -583,7 +583,7 @@
 
 void VideoReceiveStream2::UpdateHistograms() {
   RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
-  absl::optional<int> fraction_lost;
+  std::optional<int> fraction_lost;
   StreamDataCounters rtp_stats;
   StreamStatistician* statistician =
       rtp_receive_statistics_->GetStatistician(remote_ssrc());
@@ -694,7 +694,7 @@
 void VideoReceiveStream2::OnCompleteFrame(std::unique_ptr<EncodedFrame> frame) {
   RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
 
-  if (absl::optional<VideoPlayoutDelay> playout_delay =
+  if (std::optional<VideoPlayoutDelay> playout_delay =
           frame->EncodedImage().PlayoutDelay()) {
     frame_minimum_playout_delay_ = playout_delay->min();
     frame_maximum_playout_delay_ = playout_delay->max();
@@ -724,13 +724,12 @@
   return remote_ssrc();
 }
 
-absl::optional<Syncable::Info> VideoReceiveStream2::GetInfo() const {
+std::optional<Syncable::Info> VideoReceiveStream2::GetInfo() const {
   RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
-  absl::optional<Syncable::Info> info =
-      rtp_video_stream_receiver_.GetSyncInfo();
+  std::optional<Syncable::Info> info = rtp_video_stream_receiver_.GetSyncInfo();
 
   if (!info)
-    return absl::nullopt;
+    return std::nullopt;
 
   info->current_delay_ms = timing_->TargetVideoDelay().ms();
   return info;
@@ -810,7 +809,7 @@
   RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
   Timestamp now = env_.clock().CurrentTime();
 
-  absl::optional<int64_t> last_packet_ms =
+  std::optional<int64_t> last_packet_ms =
       rtp_video_stream_receiver_.LastReceivedPacketMs();
 
   // To avoid spamming keyframe requests for a stream that is not active we
@@ -825,7 +824,7 @@
   if (stream_is_active && !IsReceivingKeyFrame(now) &&
       (!config_.crypto_options.sframe.require_frame_encryption ||
        rtp_video_stream_receiver_.IsDecryptable())) {
-    absl::optional<uint32_t> last_timestamp =
+    std::optional<uint32_t> last_timestamp =
         rtp_video_stream_receiver_.LastReceivedFrameRtpTimestamp();
     RTC_LOG(LS_WARNING) << "No decodable frame in " << wait
                         << " requesting keyframe. Last RTP timestamp "
@@ -850,7 +849,7 @@
   RTC_DCHECK_RUN_ON(&decode_sequence_checker_);
 
   bool force_request_key_frame = false;
-  absl::optional<int64_t> decoded_frame_picture_id;
+  std::optional<int64_t> decoded_frame_picture_id;
 
   if (!video_receiver_.IsExternalDecoderRegistered(frame->PayloadType())) {
     // Look for the decoder with this payload type.
@@ -935,8 +934,7 @@
   }
 
   if (encoded_frame_output_enabled) {
-    absl::optional<RecordableEncodedFrame::EncodedResolution>
-        pending_resolution;
+    std::optional<RecordableEncodedFrame::EncodedResolution> pending_resolution;
     {
       // Fish out `pending_resolution_` to avoid taking the mutex on every lap
       // or dispatching under the mutex in the flush loop.
@@ -994,7 +992,7 @@
 
 bool VideoReceiveStream2::IsReceivingKeyFrame(Timestamp now) const {
   RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
-  absl::optional<int64_t> last_keyframe_packet_ms =
+  std::optional<int64_t> last_keyframe_packet_ms =
       rtp_video_stream_receiver_.LastReceivedKeyframePacketMs();
 
   // If we recently have been receiving packets belonging to a keyframe then
@@ -1007,13 +1005,13 @@
 
 void VideoReceiveStream2::UpdatePlayoutDelays() const {
   RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
-  const std::initializer_list<absl::optional<TimeDelta>> min_delays = {
+  const std::initializer_list<std::optional<TimeDelta>> min_delays = {
       frame_minimum_playout_delay_, base_minimum_playout_delay_,
       syncable_minimum_playout_delay_};
 
   // Since nullopt < anything, this will return the largest of the minumum
   // delays, or nullopt if all are nullopt.
-  absl::optional<TimeDelta> minimum_delay = std::max(min_delays);
+  std::optional<TimeDelta> minimum_delay = std::max(min_delays);
   if (minimum_delay) {
     auto num_playout_delays_set =
         absl::c_count_if(min_delays, [](auto opt) { return opt.has_value(); });
@@ -1061,7 +1059,7 @@
   // Save old state, set the new state.
   RecordingState old_state;
 
-  absl::optional<Timestamp> last_keyframe_request;
+  std::optional<Timestamp> last_keyframe_request;
   {
     // TODO(bugs.webrtc.org/11993): Post this to the network thread.
     RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
diff --git a/video/video_receive_stream2.h b/video/video_receive_stream2.h
index b6e86b2..f161f63 100644
--- a/video/video_receive_stream2.h
+++ b/video/video_receive_stream2.h
@@ -13,10 +13,10 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/sequence_checker.h"
 #include "api/task_queue/pending_task_safety_flag.h"
@@ -178,7 +178,7 @@
 
   // Implements Syncable.
   uint32_t id() const override;
-  absl::optional<Syncable::Info> GetInfo() const override;
+  std::optional<Syncable::Info> GetInfo() const override;
   bool GetPlayoutRtpTimestamp(uint32_t* rtp_timestamp,
                               int64_t* time_ms) const override;
   void SetEstimatedPlayoutNtpTimestampMs(int64_t ntp_timestamp_ms,
@@ -213,7 +213,7 @@
 
     // The picture id of the frame that was decoded, or nullopt if the frame was
     // not decoded.
-    absl::optional<int64_t> decoded_frame_picture_id;
+    std::optional<int64_t> decoded_frame_picture_id;
 
     // True if the next frame decoded must be a keyframe. This value will set
     // the value of `keyframe_required_`, which will force the frame buffer to
@@ -288,7 +288,7 @@
       RTC_GUARDED_BY(packet_sequence_checker_);
   std::unique_ptr<RtxReceiveStream> rtx_receive_stream_
       RTC_GUARDED_BY(packet_sequence_checker_);
-  absl::optional<uint32_t> updated_rtx_ssrc_
+  std::optional<uint32_t> updated_rtx_ssrc_
       RTC_GUARDED_BY(packet_sequence_checker_);
   std::unique_ptr<RtpStreamReceiverInterface> rtx_receiver_
       RTC_GUARDED_BY(packet_sequence_checker_);
@@ -300,7 +300,7 @@
   // If we have successfully decoded any frame.
   bool frame_decoded_ RTC_GUARDED_BY(decode_sequence_checker_) = false;
 
-  absl::optional<Timestamp> last_keyframe_request_
+  std::optional<Timestamp> last_keyframe_request_
       RTC_GUARDED_BY(packet_sequence_checker_);
 
   // Keyframe request intervals are configurable through field trials.
@@ -312,17 +312,17 @@
   // biggest delay is used. -1 means use default value from the `timing_`.
   //
   // Minimum delay as decided by the RTP playout delay extension.
-  absl::optional<TimeDelta> frame_minimum_playout_delay_
+  std::optional<TimeDelta> frame_minimum_playout_delay_
       RTC_GUARDED_BY(worker_sequence_checker_);
   // Minimum delay as decided by the setLatency function in "webrtc/api".
-  absl::optional<TimeDelta> base_minimum_playout_delay_
+  std::optional<TimeDelta> base_minimum_playout_delay_
       RTC_GUARDED_BY(worker_sequence_checker_);
   // Minimum delay as decided by the A/V synchronization feature.
-  absl::optional<TimeDelta> syncable_minimum_playout_delay_
+  std::optional<TimeDelta> syncable_minimum_playout_delay_
       RTC_GUARDED_BY(worker_sequence_checker_);
 
   // Maximum delay as decided by the RTP playout delay extension.
-  absl::optional<TimeDelta> frame_maximum_playout_delay_
+  std::optional<TimeDelta> frame_maximum_playout_delay_
       RTC_GUARDED_BY(worker_sequence_checker_);
 
   // Function that is triggered with encoded frames, if not empty.
@@ -334,9 +334,9 @@
   // Lock to avoid unnecessary per-frame idle wakeups in the code.
   webrtc::Mutex pending_resolution_mutex_;
   // Signal from decode queue to OnFrame callback to fill pending_resolution_.
-  // absl::nullopt - no resolution needed. 0x0 - next OnFrame to fill with
+  // std::nullopt - no resolution needed. 0x0 - next OnFrame to fill with
   // received resolution. Not 0x0 - OnFrame has filled a resolution.
-  absl::optional<RecordableEncodedFrame::EncodedResolution> pending_resolution_
+  std::optional<RecordableEncodedFrame::EncodedResolution> pending_resolution_
       RTC_GUARDED_BY(pending_resolution_mutex_);
   // Buffered encoded frames held while waiting for decoded resolution.
   std::vector<std::unique_ptr<EncodedFrame>> buffered_encoded_frames_
@@ -351,7 +351,7 @@
   // VideoReceiveStream2 destruction.
   std::unique_ptr<TaskQueueBase, TaskQueueDeleter> decode_queue_;
 
-  absl::optional<uint32_t> last_decoded_rtp_timestamp_;
+  std::optional<uint32_t> last_decoded_rtp_timestamp_;
 };
 
 }  // namespace internal
diff --git a/video/video_receive_stream2_unittest.cc b/video/video_receive_stream2_unittest.cc
index d1cee24..ef89290 100644
--- a/video/video_receive_stream2_unittest.cc
+++ b/video/video_receive_stream2_unittest.cc
@@ -15,13 +15,13 @@
 #include <deque>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <queue>
 #include <tuple>
 #include <utility>
 #include <vector>
 
 #include "absl/memory/memory.h"
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
 #include "api/metronome/test/fake_metronome.h"
@@ -84,8 +84,8 @@
 auto RenderedFrame() {
   return RenderedFrameWith(_);
 }
-testing::Matcher<absl::optional<VideoFrame>> DidNotReceiveFrame() {
-  return Eq(absl::nullopt);
+testing::Matcher<std::optional<VideoFrame>> DidNotReceiveFrame() {
+  return Eq(std::nullopt);
 }
 
 constexpr TimeDelta kDefaultTimeOut = TimeDelta::Millis(50);
@@ -115,14 +115,14 @@
   }
 
   // If `advance_time`, then the clock will always advance by `timeout`.
-  absl::optional<VideoFrame> WaitForFrame(TimeDelta timeout,
-                                          bool advance_time = false) {
+  std::optional<VideoFrame> WaitForFrame(TimeDelta timeout,
+                                         bool advance_time = false) {
     auto start = time_controller_->GetClock()->CurrentTime();
     if (last_frame_.empty()) {
       time_controller_->AdvanceTime(TimeDelta::Zero());
       time_controller_->Wait([this] { return !last_frame_.empty(); }, timeout);
     }
-    absl::optional<VideoFrame> ret;
+    std::optional<VideoFrame> ret;
     if (!last_frame_.empty()) {
       ret = last_frame_.front();
       last_frame_.pop_front();
@@ -232,8 +232,8 @@
   }
 
   void RecreateReceiveStream(
-      absl::optional<VideoReceiveStreamInterface::RecordingState> state =
-          absl::nullopt) {
+      std::optional<VideoReceiveStreamInterface::RecordingState> state =
+          std::nullopt) {
     if (video_receive_stream_) {
       video_receive_stream_->UnregisterFromTransport();
       video_receive_stream_ = nullptr;
@@ -379,7 +379,7 @@
           .Build();
   video_receive_stream_->OnCompleteFrame(std::move(test_frame0));
   EXPECT_THAT(timing_->RenderParameters().max_composition_delay_in_frames,
-              Eq(absl::nullopt));
+              Eq(std::nullopt));
   time_controller_.AdvanceTime(k30FpsDelay);
 
   // Max composition delay not set for playout delay 0,0.
@@ -393,7 +393,7 @@
           .Build();
   video_receive_stream_->OnCompleteFrame(std::move(test_frame1));
   EXPECT_THAT(timing_->RenderParameters().max_composition_delay_in_frames,
-              Eq(absl::nullopt));
+              Eq(std::nullopt));
   time_controller_.AdvanceTime(k30FpsDelay);
 
   // Max composition delay not set for playout delay X,Y, where X,Y>0.
@@ -407,7 +407,7 @@
           .Build();
   video_receive_stream_->OnCompleteFrame(std::move(test_frame2));
   EXPECT_THAT(timing_->RenderParameters().max_composition_delay_in_frames,
-              Eq(absl::nullopt));
+              Eq(std::nullopt));
 
   time_controller_.AdvanceTime(k30FpsDelay);
 
@@ -1066,7 +1066,7 @@
             .AsLast()
             .Build());
     EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay, /*advance_time=*/true),
-                Eq(absl::nullopt));
+                Eq(std::nullopt));
   }
   uint32_t current_rtp = RtpTimestampForFrame(id);
   Timestamp send_15fps_end_time =
@@ -1084,7 +1084,7 @@
             .AsLast()
             .Build());
     EXPECT_THAT(fake_renderer_.WaitForFrame(k15FpsDelay, /*advance_time=*/true),
-                Eq(absl::nullopt));
+                Eq(std::nullopt));
   }
 
   ++id;
diff --git a/video/video_send_stream_impl.cc b/video/video_send_stream_impl.cc
index 181f146..77f40f9 100644
--- a/video/video_send_stream_impl.cc
+++ b/video/video_send_stream_impl.cc
@@ -15,12 +15,12 @@
 #include <cstdint>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "absl/algorithm/container.h"
-#include "absl/types/optional.h"
 #include "api/adaptation/resource.h"
 #include "api/call/bitrate_allocation.h"
 #include "api/crypto/crypto_options.h"
@@ -181,7 +181,7 @@
   return pad_up_to_bitrate_bps;
 }
 
-absl::optional<AlrExperimentSettings> GetAlrSettings(
+std::optional<AlrExperimentSettings> GetAlrSettings(
     const FieldTrialsView& field_trials,
     VideoEncoderConfig::ContentType content_type) {
   if (content_type == VideoEncoderConfig::ContentType::kScreen) {
@@ -208,15 +208,15 @@
 
 // Returns an optional that has value iff TransportSeqNumExtensionConfigured
 // is `true` for the given video send stream config.
-absl::optional<float> GetConfiguredPacingFactor(
+std::optional<float> GetConfiguredPacingFactor(
     const VideoSendStream::Config& config,
     VideoEncoderConfig::ContentType content_type,
     const PacingConfig& default_pacing_config,
     const FieldTrialsView& field_trials) {
   if (!TransportSeqNumExtensionConfigured(config))
-    return absl::nullopt;
+    return std::nullopt;
 
-  absl::optional<AlrExperimentSettings> alr_settings =
+  std::optional<AlrExperimentSettings> alr_settings =
       GetAlrSettings(field_trials, content_type);
   if (alr_settings)
     return alr_settings->pacing_factor;
@@ -472,12 +472,12 @@
   RTC_CHECK(
       AlrExperimentSettings::MaxOneFieldTrialEnabled(env_.field_trials()));
 
-  absl::optional<bool> enable_alr_bw_probing;
+  std::optional<bool> enable_alr_bw_probing;
 
   // If send-side BWE is enabled, check if we should apply updated probing and
   // pacing settings.
   if (configured_pacing_factor_) {
-    absl::optional<AlrExperimentSettings> alr_settings =
+    std::optional<AlrExperimentSettings> alr_settings =
         GetAlrSettings(env_.field_trials(), content_type_);
     int queue_time_limit_ms;
     if (alr_settings) {
@@ -575,7 +575,7 @@
   return stats_proxy_.GetStats();
 }
 
-absl::optional<float> VideoSendStreamImpl::GetPacingFactorOverride() const {
+std::optional<float> VideoSendStreamImpl::GetPacingFactorOverride() const {
   return configured_pacing_factor_;
 }
 
@@ -782,8 +782,8 @@
       !config_.suspend_below_min_bitrate,
       encoder_bitrate_priority_,
       (content_type_ == VideoEncoderConfig::ContentType::kRealtimeVideo)
-          ? absl::optional(TrackRateElasticity::kCanConsumeExtraRate)
-          : absl::nullopt};
+          ? std::optional(TrackRateElasticity::kCanConsumeExtraRate)
+          : std::nullopt};
 }
 
 void VideoSendStreamImpl::OnEncoderConfigurationChanged(
@@ -802,7 +802,7 @@
     const VideoCodecType codec_type =
         PayloadStringToCodecType(config_.rtp.payload_name);
 
-    const absl::optional<DataRate> experimental_min_bitrate =
+    const std::optional<DataRate> experimental_min_bitrate =
         GetExperimentalMinVideoBitrate(env_.field_trials(), codec_type);
     encoder_min_bitrate_bps_ =
         experimental_min_bitrate
@@ -947,10 +947,10 @@
   return protection_bitrate_bps;
 }
 
-absl::optional<DataRate> VideoSendStreamImpl::GetUsedRate() const {
+std::optional<DataRate> VideoSendStreamImpl::GetUsedRate() const {
   // This value is for real-time video. Screenshare may have unused bandwidth
   // that can be shared, and this needs to be changed to support that.
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace internal
diff --git a/video/video_send_stream_impl.h b/video/video_send_stream_impl.h
index ea405ff..fd91e00 100644
--- a/video/video_send_stream_impl.h
+++ b/video/video_send_stream_impl.h
@@ -16,10 +16,10 @@
 #include <atomic>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/environment/environment.h"
 #include "api/field_trials_view.h"
 #include "api/metronome/metronome.h"
@@ -117,7 +117,7 @@
 
   std::map<uint32_t, RtpPayloadState> GetRtpPayloadStates() const;
 
-  const absl::optional<float>& configured_pacing_factor() const {
+  const std::optional<float>& configured_pacing_factor() const {
     return configured_pacing_factor_;
   }
 
@@ -129,7 +129,7 @@
                          SendDelayStats* send_delay_stats)
         : stats_proxy_(*stats_proxy), send_delay_stats_(*send_delay_stats) {}
 
-    void OnSendPacket(absl::optional<uint16_t> packet_id,
+    void OnSendPacket(std::optional<uint16_t> packet_id,
                       Timestamp capture_time,
                       uint32_t ssrc) override {
       stats_proxy_.OnSendPacket(ssrc, capture_time);
@@ -143,10 +143,10 @@
     SendDelayStats& send_delay_stats_;
   };
 
-  absl::optional<float> GetPacingFactorOverride() const;
+  std::optional<float> GetPacingFactorOverride() const;
   // Implements BitrateAllocatorObserver.
   uint32_t OnBitrateUpdated(BitrateAllocationUpdate update) override;
-  absl::optional<DataRate> GetUsedRate() const override;
+  std::optional<DataRate> GetUsedRate() const override;
 
   // Implements VideoStreamEncoderInterface::EncoderSink
   void OnEncoderConfigurationChanged(
@@ -229,12 +229,12 @@
   // throttle sending of similar bitrate allocations.
   struct VbaSendContext {
     VideoBitrateAllocation last_sent_allocation;
-    absl::optional<VideoBitrateAllocation> throttled_allocation;
+    std::optional<VideoBitrateAllocation> throttled_allocation;
     int64_t last_send_time_ms;
   };
-  absl::optional<VbaSendContext> video_bitrate_allocation_context_
+  std::optional<VbaSendContext> video_bitrate_allocation_context_
       RTC_GUARDED_BY(thread_checker_);
-  const absl::optional<float> configured_pacing_factor_;
+  const std::optional<float> configured_pacing_factor_;
 };
 }  // namespace internal
 }  // namespace webrtc
diff --git a/video/video_send_stream_impl_unittest.cc b/video/video_send_stream_impl_unittest.cc
index 08ac956..8ce4c8f 100644
--- a/video/video_send_stream_impl_unittest.cc
+++ b/video/video_send_stream_impl_unittest.cc
@@ -15,11 +15,11 @@
 #include <cstdint>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/call/bitrate_allocation.h"
 #include "api/environment/environment.h"
@@ -1233,7 +1233,7 @@
   EXPECT_CALL(bitrate_allocator_,
               AddObserver(vss_impl.get(),
                           Field(&MediaStreamAllocationConfig::rate_elasticity,
-                                absl::nullopt)));
+                                std::nullopt)));
   vss_impl->Start();
   EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get()));
   vss_impl->Stop();
diff --git a/video/video_send_stream_tests.cc b/video/video_send_stream_tests.cc
index da9ded0..92014e6 100644
--- a/video/video_send_stream_tests.cc
+++ b/video/video_send_stream_tests.cc
@@ -86,7 +86,7 @@
   explicit VideoSendStreamPeer(webrtc::VideoSendStream* base_class_stream)
       : internal_stream_(
             static_cast<internal::VideoSendStreamImpl*>(base_class_stream)) {}
-  absl::optional<float> GetPacingFactorOverride() const {
+  std::optional<float> GetPacingFactorOverride() const {
     return internal_stream_->GetPacingFactorOverride();
   }
 
@@ -1426,7 +1426,7 @@
     TestState test_state_ = kBeforeStopCapture;
     Clock* const clock_;
     Mutex mutex_;
-    absl::optional<int64_t> last_packet_time_ms_ RTC_GUARDED_BY(mutex_);
+    std::optional<int64_t> last_packet_time_ms_ RTC_GUARDED_BY(mutex_);
     test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(mutex_);
   } test;
 
@@ -3316,10 +3316,10 @@
   }
 
   ScalableVideoController::StreamLayersConfig GetScalabilityConfig() const {
-    absl::optional<ScalabilityMode> scalability_mode =
+    std::optional<ScalabilityMode> scalability_mode =
         ScalabilityModeFromString(params_.scalability_mode);
     EXPECT_TRUE(scalability_mode.has_value());
-    absl::optional<ScalableVideoController::StreamLayersConfig> config =
+    std::optional<ScalableVideoController::StreamLayersConfig> config =
         ScalabilityStructureConfig(*scalability_mode);
     EXPECT_TRUE(config.has_value());
     EXPECT_EQ(config->num_spatial_layers, params_.num_spatial_layers);
@@ -3331,8 +3331,8 @@
   VideoCodecVP9 vp9_settings_;
   webrtc::VideoEncoderConfig encoder_config_;
   bool last_packet_marker_ = false;
-  absl::optional<uint16_t> last_packet_sequence_number_;
-  absl::optional<uint32_t> last_packet_timestamp_;
+  std::optional<uint16_t> last_packet_sequence_number_;
+  std::optional<uint32_t> last_packet_timestamp_;
   RTPVideoHeaderVP9 last_vp9_;
   std::map<int, int> last_temporal_idx_by_spatial_idx_;
   Mutex mutex_;
@@ -3451,7 +3451,7 @@
         vp9_settings_.numberOfSpatialLayers = params_.num_spatial_layers;
         vp9_settings_.interLayerPred = params_.inter_layer_pred;
       } else {
-        absl::optional<ScalabilityMode> mode =
+        std::optional<ScalabilityMode> mode =
             ScalabilityModeFromString(params_.scalability_mode);
         encoder_config->simulcast_layers[0].scalability_mode = mode;
         EXPECT_TRUE(mode.has_value());
@@ -3780,7 +3780,7 @@
 class PacingFactorObserver : public test::SendTest {
  public:
   PacingFactorObserver(bool configure_send_side,
-                       absl::optional<float> expected_pacing_factor)
+                       std::optional<float> expected_pacing_factor)
       : test::SendTest(test::VideoTestConstants::kDefaultTimeout),
         configure_send_side_(configure_send_side),
         expected_pacing_factor_(expected_pacing_factor) {}
@@ -3836,7 +3836,7 @@
 
  private:
   const bool configure_send_side_;
-  const absl::optional<float> expected_pacing_factor_;
+  const std::optional<float> expected_pacing_factor_;
 };
 
 std::string GetAlrProbingExperimentString() {
@@ -3857,7 +3857,7 @@
 TEST_F(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
   test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
   // Send-side bwe off, use configuration should not be overridden.
-  PacingFactorObserver test_without_send_side(false, absl::nullopt);
+  PacingFactorObserver test_without_send_side(false, std::nullopt);
   RunBaseTest(&test_without_send_side);
 }
 
@@ -4120,7 +4120,7 @@
       parsed.timestamp = rtp_packet.Timestamp();
       parsed.ssrc = rtp_packet.Ssrc();
 
-      absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload =
+      std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload =
           depacketizer_->Parse(rtp_packet.PayloadBuffer());
       EXPECT_TRUE(parsed_payload);
 
diff --git a/video/video_source_sink_controller.cc b/video/video_source_sink_controller.cc
index 2f7b375..3a49044 100644
--- a/video/video_source_sink_controller.cc
+++ b/video/video_source_sink_controller.cc
@@ -71,13 +71,13 @@
   return restrictions_;
 }
 
-absl::optional<size_t> VideoSourceSinkController::pixels_per_frame_upper_limit()
+std::optional<size_t> VideoSourceSinkController::pixels_per_frame_upper_limit()
     const {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   return pixels_per_frame_upper_limit_;
 }
 
-absl::optional<double> VideoSourceSinkController::frame_rate_upper_limit()
+std::optional<double> VideoSourceSinkController::frame_rate_upper_limit()
     const {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   return frame_rate_upper_limit_;
@@ -104,7 +104,7 @@
   return active_;
 }
 
-absl::optional<rtc::VideoSinkWants::FrameSize>
+std::optional<rtc::VideoSinkWants::FrameSize>
 VideoSourceSinkController::requested_resolution() const {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   return requested_resolution_;
@@ -117,13 +117,13 @@
 }
 
 void VideoSourceSinkController::SetPixelsPerFrameUpperLimit(
-    absl::optional<size_t> pixels_per_frame_upper_limit) {
+    std::optional<size_t> pixels_per_frame_upper_limit) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   pixels_per_frame_upper_limit_ = std::move(pixels_per_frame_upper_limit);
 }
 
 void VideoSourceSinkController::SetFrameRateUpperLimit(
-    absl::optional<double> frame_rate_upper_limit) {
+    std::optional<double> frame_rate_upper_limit) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   frame_rate_upper_limit_ = std::move(frame_rate_upper_limit);
 }
@@ -151,7 +151,7 @@
 }
 
 void VideoSourceSinkController::SetRequestedResolution(
-    absl::optional<rtc::VideoSinkWants::FrameSize> requested_resolution) {
+    std::optional<rtc::VideoSinkWants::FrameSize> requested_resolution) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   requested_resolution_ = std::move(requested_resolution);
 }
@@ -167,9 +167,9 @@
           std::numeric_limits<int>::max()));
   wants.target_pixel_count =
       restrictions_.target_pixels_per_frame().has_value()
-          ? absl::optional<int>(rtc::dchecked_cast<int>(
+          ? std::optional<int>(rtc::dchecked_cast<int>(
                 restrictions_.target_pixels_per_frame().value()))
-          : absl::nullopt;
+          : std::nullopt;
   wants.max_framerate_fps =
       restrictions_.max_frame_rate().has_value()
           ? static_cast<int>(restrictions_.max_frame_rate().value())
diff --git a/video/video_source_sink_controller.h b/video/video_source_sink_controller.h
index 1bb6ef6..9ce0fb5 100644
--- a/video/video_source_sink_controller.h
+++ b/video/video_source_sink_controller.h
@@ -11,10 +11,10 @@
 #ifndef VIDEO_VIDEO_SOURCE_SINK_CONTROLLER_H_
 #define VIDEO_VIDEO_SOURCE_SINK_CONTROLLER_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/sequence_checker.h"
 #include "api/video/video_frame.h"
 #include "api/video/video_sink_interface.h"
@@ -46,26 +46,26 @@
   void PushSourceSinkSettings();
 
   VideoSourceRestrictions restrictions() const;
-  absl::optional<size_t> pixels_per_frame_upper_limit() const;
-  absl::optional<double> frame_rate_upper_limit() const;
+  std::optional<size_t> pixels_per_frame_upper_limit() const;
+  std::optional<double> frame_rate_upper_limit() const;
   bool rotation_applied() const;
   int resolution_alignment() const;
   const std::vector<rtc::VideoSinkWants::FrameSize>& resolutions() const;
   bool active() const;
-  absl::optional<rtc::VideoSinkWants::FrameSize> requested_resolution() const;
+  std::optional<rtc::VideoSinkWants::FrameSize> requested_resolution() const;
 
   // Updates the settings stored internally. In order for these settings to be
   // applied to the sink, PushSourceSinkSettings() must subsequently be called.
   void SetRestrictions(VideoSourceRestrictions restrictions);
   void SetPixelsPerFrameUpperLimit(
-      absl::optional<size_t> pixels_per_frame_upper_limit);
-  void SetFrameRateUpperLimit(absl::optional<double> frame_rate_upper_limit);
+      std::optional<size_t> pixels_per_frame_upper_limit);
+  void SetFrameRateUpperLimit(std::optional<double> frame_rate_upper_limit);
   void SetRotationApplied(bool rotation_applied);
   void SetResolutionAlignment(int resolution_alignment);
   void SetResolutions(std::vector<rtc::VideoSinkWants::FrameSize> resolutions);
   void SetActive(bool active);
   void SetRequestedResolution(
-      absl::optional<rtc::VideoSinkWants::FrameSize> requested_resolution);
+      std::optional<rtc::VideoSinkWants::FrameSize> requested_resolution);
 
  private:
   rtc::VideoSinkWants CurrentSettingsToSinkWants() const
@@ -84,16 +84,16 @@
   // Ensures that even if we are not restricted, the sink is never configured
   // above this limit. Example: We are not CPU limited (no `restrictions_`) but
   // our encoder is capped at 30 fps (= `frame_rate_upper_limit_`).
-  absl::optional<size_t> pixels_per_frame_upper_limit_
+  std::optional<size_t> pixels_per_frame_upper_limit_
       RTC_GUARDED_BY(&sequence_checker_);
-  absl::optional<double> frame_rate_upper_limit_
+  std::optional<double> frame_rate_upper_limit_
       RTC_GUARDED_BY(&sequence_checker_);
   bool rotation_applied_ RTC_GUARDED_BY(&sequence_checker_) = false;
   int resolution_alignment_ RTC_GUARDED_BY(&sequence_checker_) = 1;
   std::vector<rtc::VideoSinkWants::FrameSize> resolutions_
       RTC_GUARDED_BY(&sequence_checker_);
   bool active_ RTC_GUARDED_BY(&sequence_checker_) = true;
-  absl::optional<rtc::VideoSinkWants::FrameSize> requested_resolution_
+  std::optional<rtc::VideoSinkWants::FrameSize> requested_resolution_
       RTC_GUARDED_BY(&sequence_checker_);
 };
 
diff --git a/video/video_source_sink_controller_unittest.cc b/video/video_source_sink_controller_unittest.cc
index 75cc52b..bddfc0d 100644
--- a/video/video_source_sink_controller_unittest.cc
+++ b/video/video_source_sink_controller_unittest.cc
@@ -70,7 +70,7 @@
                    const rtc::VideoSinkWants& wants) {
         EXPECT_FALSE(wants.rotation_applied);
         EXPECT_EQ(wants.max_pixel_count, kIntUnconstrained);
-        EXPECT_EQ(wants.target_pixel_count, absl::nullopt);
+        EXPECT_EQ(wants.target_pixel_count, std::nullopt);
         EXPECT_EQ(wants.max_framerate_fps, kIntUnconstrained);
         EXPECT_EQ(wants.resolution_alignment, 1);
         EXPECT_FALSE(wants.requested_resolution.has_value());
diff --git a/video/video_stream_buffer_controller.cc b/video/video_stream_buffer_controller.cc
index b7ed896..83de75a 100644
--- a/video/video_stream_buffer_controller.cc
+++ b/video/video_stream_buffer_controller.cc
@@ -12,11 +12,11 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "absl/base/attributes.h"
 #include "absl/functional/bind_front.h"
-#include "absl/types/optional.h"
 #include "api/sequence_checker.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/units/data_size.h"
@@ -65,7 +65,7 @@
   const VideoContentType contentType;
   const bool delayed_by_retransmission;
   const uint32_t rtp_timestamp;
-  const absl::optional<Timestamp> receive_time;
+  const std::optional<Timestamp> receive_time;
 };
 
 Timestamp MinReceiveTime(const EncodedFrame& frame) {
@@ -79,7 +79,7 @@
 }
 
 Timestamp ReceiveTime(const EncodedFrame& frame) {
-  absl::optional<Timestamp> ts = frame.ReceivedTimestamp();
+  std::optional<Timestamp> ts = frame.ReceivedTimestamp();
   RTC_DCHECK(ts.has_value()) << "Received frame must have a timestamp set!";
   return *ts;
 }
@@ -148,7 +148,7 @@
   frame_decode_scheduler_->CancelOutstanding();
 }
 
-absl::optional<int64_t> VideoStreamBufferController::InsertFrame(
+std::optional<int64_t> VideoStreamBufferController::InsertFrame(
     std::unique_ptr<EncodedFrame> frame) {
   RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
   FrameMetadata metadata(*frame);
@@ -240,7 +240,7 @@
   }
 
   if (!superframe_delayed_by_retransmission) {
-    absl::optional<TimeDelta> inter_frame_delay_variation =
+    std::optional<TimeDelta> inter_frame_delay_variation =
         ifdv_calculator_.Calculate(first_frame.RtpTimestamp(),
                                    max_receive_time);
     if (inter_frame_delay_variation) {
@@ -352,7 +352,7 @@
 }
 
 void VideoStreamBufferController::UpdateTimingFrameInfo() {
-  absl::optional<TimingFrameInfo> info = timing_->GetTimingFrameInfo();
+  std::optional<TimingFrameInfo> info = timing_->GetTimingFrameInfo();
   if (info)
     stats_proxy_->OnTimingFrameInfoUpdated(*info);
 }
@@ -405,7 +405,7 @@
   // Ensures the frame is scheduled for decode before the stream times out.
   // This is otherwise a race condition.
   max_wait = std::max(max_wait - TimeDelta::Millis(1), TimeDelta::Zero());
-  absl::optional<FrameDecodeTiming::FrameSchedule> schedule;
+  std::optional<FrameDecodeTiming::FrameSchedule> schedule;
   while (decodable_tu_info) {
     schedule = decode_timing_.OnFrameBufferUpdated(
         decodable_tu_info->next_rtp_timestamp,
diff --git a/video/video_stream_buffer_controller.h b/video/video_stream_buffer_controller.h
index f07b3eb..43d4544 100644
--- a/video/video_stream_buffer_controller.h
+++ b/video/video_stream_buffer_controller.h
@@ -80,7 +80,7 @@
   void Stop();
   void SetProtectionMode(VCMVideoProtection protection_mode);
   void Clear();
-  absl::optional<int64_t> InsertFrame(std::unique_ptr<EncodedFrame> frame);
+  std::optional<int64_t> InsertFrame(std::unique_ptr<EncodedFrame> frame);
   void UpdateRtt(int64_t max_rtt_ms);
   void SetMaxWaits(TimeDelta max_wait_for_keyframe,
                    TimeDelta max_wait_for_frame);
diff --git a/video/video_stream_buffer_controller_unittest.cc b/video/video_stream_buffer_controller_unittest.cc
index d2f2f73..c97601b 100644
--- a/video/video_stream_buffer_controller_unittest.cc
+++ b/video/video_stream_buffer_controller_unittest.cc
@@ -14,12 +14,12 @@
 
 #include <limits>
 #include <memory>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <utility>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/metronome/test/fake_metronome.h"
 #include "api/units/frequency.h"
@@ -183,7 +183,7 @@
   using WaitResult =
       absl::variant<std::unique_ptr<EncodedFrame>, TimeDelta /*wait_time*/>;
 
-  absl::optional<WaitResult> WaitForFrameOrTimeout(TimeDelta wait) {
+  std::optional<WaitResult> WaitForFrameOrTimeout(TimeDelta wait) {
     if (wait_result_) {
       return std::move(wait_result_);
     }
@@ -245,7 +245,7 @@
   }
 
   uint32_t dropped_frames_ = 0;
-  absl::optional<WaitResult> wait_result_;
+  std::optional<WaitResult> wait_result_;
 };
 
 class VideoStreamBufferControllerTest
@@ -260,7 +260,7 @@
 
   // No new timeout set since receiver has not started new decode.
   ResetLastResult();
-  EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForKeyframe), Eq(absl::nullopt));
+  EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForKeyframe), Eq(std::nullopt));
 
   // Now that receiver has asked for new frame, a new timeout can occur.
   StartNextDecodeForceKeyframe();
@@ -362,7 +362,7 @@
   buffer_->Stop();
   // Wait for 2x max wait time. Since we stopped, this should cause no timeouts
   // or frame-ready callbacks.
-  EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForFrame * 2), Eq(absl::nullopt));
+  EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForFrame * 2), Eq(std::nullopt));
 }
 
 TEST_P(VideoStreamBufferControllerTest, FramesWaitForDecoderToComplete) {
@@ -383,7 +383,7 @@
 
   // Advancing time should not result in a frame since the scheduler has not
   // been signalled that we are ready.
-  EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Eq(absl::nullopt));
+  EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Eq(std::nullopt));
   // Signal ready.
   StartNextDecode();
   EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(1)));
@@ -566,7 +566,7 @@
                                                            .AsLast()
                                                            .Build()));
   StartNextDecode();
-  EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Eq(absl::nullopt));
+  EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Eq(std::nullopt));
 
   // Scheduler is waiting to deliver Frame 1 now. Insert Frame 2. Frame 1 should
   // be delivered still.
@@ -747,7 +747,7 @@
   // Avoid timeout being set while waiting for the frame and before the receiver
   // is ready.
   ResetLastResult();
-  EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForFrame), Eq(absl::nullopt));
+  EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForFrame), Eq(std::nullopt));
   time_controller_.AdvanceTime(kRolloverDelay - kMaxWaitForFrame);
   StartNextDecode();
   buffer_->InsertFrame(test::FakeFrameBuilder()
@@ -844,7 +844,7 @@
               .Build();
   buffer_->InsertFrame(std::move(frame));
   // Pacing is set to 16ms in the field trial so we should not decode yet.
-  EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Eq(absl::nullopt));
+  EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Eq(std::nullopt));
   time_controller_.AdvanceTime(TimeDelta::Millis(16));
   EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(1)));
 }
diff --git a/video/video_stream_decoder2.cc b/video/video_stream_decoder2.cc
index 5640835..df4f3530 100644
--- a/video/video_stream_decoder2.cc
+++ b/video/video_stream_decoder2.cc
@@ -44,7 +44,7 @@
 // thread may have held the lock when calling VideoDecoder::Decode, Reset, or
 // Release. Acquiring the same lock in the path of decode callback can deadlock.
 int32_t VideoStreamDecoder::FrameToRender(VideoFrame& video_frame,
-                                          absl::optional<uint8_t> qp,
+                                          std::optional<uint8_t> qp,
                                           TimeDelta decode_time,
                                           VideoContentType content_type,
                                           VideoFrameType frame_type) {
diff --git a/video/video_stream_decoder2.h b/video/video_stream_decoder2.h
index 19db810..7847025 100644
--- a/video/video_stream_decoder2.h
+++ b/video/video_stream_decoder2.h
@@ -41,7 +41,7 @@
 
   // Implements VCMReceiveCallback.
   int32_t FrameToRender(VideoFrame& video_frame,
-                        absl::optional<uint8_t> qp,
+                        std::optional<uint8_t> qp,
                         TimeDelta decode_time,
                         VideoContentType content_type,
                         VideoFrameType frame_type) override;
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index 4579702..821a1db 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -15,11 +15,11 @@
 #include <limits>
 #include <memory>
 #include <numeric>
+#include <optional>
 #include <utility>
 
 #include "absl/algorithm/container.h"
 #include "absl/cleanup/cleanup.h"
-#include "absl/types/optional.h"
 #include "api/field_trials_view.h"
 #include "api/sequence_checker.h"
 #include "api/task_queue/task_queue_base.h"
@@ -91,7 +91,7 @@
   }
 }
 
-absl::optional<EncodedImageCallback::DropReason> MaybeConvertDropReason(
+std::optional<EncodedImageCallback::DropReason> MaybeConvertDropReason(
     VideoStreamEncoderObserver::DropReason reason) {
   switch (reason) {
     case VideoStreamEncoderObserver::DropReason::kMediaOptimization:
@@ -99,7 +99,7 @@
     case VideoStreamEncoderObserver::DropReason::kEncoder:
       return EncodedImageCallback::DropReason::kDroppedByEncoder;
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
@@ -403,18 +403,18 @@
   }
 
   // Get bitrate limits for active stream.
-  absl::optional<uint32_t> pixels =
+  std::optional<uint32_t> pixels =
       VideoStreamAdapter::GetSingleActiveLayerPixels(*codec);
   if (!pixels.has_value()) {
     return;
   }
-  absl::optional<VideoEncoder::ResolutionBitrateLimits> bitrate_limits =
+  std::optional<VideoEncoder::ResolutionBitrateLimits> bitrate_limits =
       encoder_info.GetEncoderBitrateLimitsForResolution(*pixels);
   if (!bitrate_limits.has_value()) {
     return;
   }
   // Index for the active stream.
-  absl::optional<size_t> index;
+  std::optional<size_t> index;
   for (size_t i = 0; i < encoder_config.simulcast_layers.size(); ++i) {
     if (encoder_config.simulcast_layers[i].active)
       index = i;
@@ -478,7 +478,7 @@
   }
 
   // Get bitrate limits for active stream.
-  absl::optional<VideoEncoder::ResolutionBitrateLimits> encoder_bitrate_limits =
+  std::optional<VideoEncoder::ResolutionBitrateLimits> encoder_bitrate_limits =
       encoder_info.GetEncoderBitrateLimitsForResolution(
           (*streams)[index].width * (*streams)[index].height);
   if (!encoder_bitrate_limits) {
@@ -516,19 +516,19 @@
                encoder_bitrate_limits->max_bitrate_bps);
 }
 
-absl::optional<int> ParseVp9LowTierCoreCountThreshold(
+std::optional<int> ParseVp9LowTierCoreCountThreshold(
     const FieldTrialsView& trials) {
   FieldTrialFlag disable_low_tier("Disabled");
   FieldTrialParameter<int> max_core_count("max_core_count", 2);
   ParseFieldTrial({&disable_low_tier, &max_core_count},
                   trials.Lookup("WebRTC-VP9-LowTierOptimizations"));
   if (disable_low_tier.Get()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return max_core_count.Get();
 }
 
-absl::optional<int> ParseEncoderThreadLimit(const FieldTrialsView& trials) {
+std::optional<int> ParseEncoderThreadLimit(const FieldTrialsView& trials) {
   FieldTrialOptional<int> encoder_thread_limit("encoder_thread_limit");
   ParseFieldTrial({&encoder_thread_limit},
                   trials.Lookup("WebRTC-VideoEncoderSettings"));
@@ -847,8 +847,8 @@
     RTC_DCHECK_RUN_ON(encoder_queue_.get());
     RTC_LOG(LS_INFO) << "SetStartBitrate " << start_bitrate_bps;
     encoder_target_bitrate_bps_ =
-        start_bitrate_bps != 0 ? absl::optional<uint32_t>(start_bitrate_bps)
-                               : absl::nullopt;
+        start_bitrate_bps != 0 ? std::optional<uint32_t>(start_bitrate_bps)
+                               : std::nullopt;
     stream_resource_manager_.SetStartBitrate(
         DataRate::BitsPerSec(start_bitrate_bps));
   });
@@ -870,7 +870,7 @@
   // Is any layer active.
   bool active = false;
   // The max requested_resolution.
-  absl::optional<rtc::VideoSinkWants::FrameSize> requested_resolution;
+  std::optional<rtc::VideoSinkWants::FrameSize> requested_resolution;
   for (const auto& stream : config.simulcast_layers) {
     active |= stream.active;
     if (stream.active) {
@@ -900,7 +900,7 @@
     if (max_framerate >= 0) {
       video_source_sink_controller_.SetFrameRateUpperLimit(max_framerate);
     } else {
-      video_source_sink_controller_.SetFrameRateUpperLimit(absl::nullopt);
+      video_source_sink_controller_.SetFrameRateUpperLimit(std::nullopt);
     }
     video_source_sink_controller_.SetActive(active);
     video_source_sink_controller_.PushSourceSinkSettings();
@@ -924,7 +924,7 @@
       frame_cadence_adapter_->SetZeroHertzModeEnabled(
           FrameCadenceAdapterInterface::ZeroHertzModeParams{});
     } else {
-      frame_cadence_adapter_->SetZeroHertzModeEnabled(absl::nullopt);
+      frame_cadence_adapter_->SetZeroHertzModeEnabled(std::nullopt);
     }
 
     pending_encoder_creation_ =
@@ -989,7 +989,7 @@
   // Possibly adjusts scale_resolution_down_by in `encoder_config_` to limit the
   // alignment value.
   AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
-      encoder_->GetEncoderInfo(), &encoder_config_, absl::nullopt);
+      encoder_->GetEncoderInfo(), &encoder_config_, std::nullopt);
 
   std::vector<VideoStream> streams;
   if (encoder_config_.video_stream_factory) {
@@ -1059,7 +1059,7 @@
     // to get a certain bitrate for certain pixel_count. It also doesn't work
     // for 960*540 and 640*520, we will nerver be stable at 640*520 due to their
     // |target_bitrate_bps| are both 2000Kbps.
-    absl::optional<VideoEncoder::ResolutionBitrateLimits>
+    std::optional<VideoEncoder::ResolutionBitrateLimits>
         qp_untrusted_bitrate_limit = EncoderInfoSettings::
             GetSinglecastBitrateLimitForResolutionWhenQpIsUntrusted(
                 last_frame_info_->width * last_frame_info_->height,
@@ -1086,7 +1086,7 @@
       }
     }
   } else {
-    absl::optional<VideoEncoder::ResolutionBitrateLimits>
+    std::optional<VideoEncoder::ResolutionBitrateLimits>
         encoder_bitrate_limits =
             encoder_->GetEncoderInfo().GetEncoderBitrateLimitsForResolution(
                 last_frame_info_->width * last_frame_info_->height);
@@ -1107,7 +1107,7 @@
         int max_bitrate_bps;
         // The API max bitrate comes from both `encoder_config_.max_bitrate_bps`
         // and `encoder_config_.simulcast_layers[0].max_bitrate_bps`.
-        absl::optional<int> api_max_bitrate_bps;
+        std::optional<int> api_max_bitrate_bps;
         if (encoder_config_.simulcast_layers[0].max_bitrate_bps > 0) {
           api_max_bitrate_bps =
               encoder_config_.simulcast_layers[0].max_bitrate_bps;
@@ -1172,7 +1172,7 @@
   rtc::SimpleStringBuilder log_stream(log_stream_buf);
   log_stream << "ReconfigureEncoder: simulcast streams: ";
   for (size_t i = 0; i < codec.numberOfSimulcastStreams; ++i) {
-    absl::optional<ScalabilityMode> scalability_mode =
+    std::optional<ScalabilityMode> scalability_mode =
         codec.simulcastStream[i].GetScalabilityMode();
     if (scalability_mode) {
       log_stream << "{" << i << ": " << codec.simulcastStream[i].width << "x"
@@ -1294,7 +1294,7 @@
     }
 
     frame_encode_metadata_writer_.Reset();
-    last_encode_info_ms_ = absl::nullopt;
+    last_encode_info_ms_ = std::nullopt;
     was_encode_called_since_last_initialization_ = false;
   }
 
@@ -1446,7 +1446,7 @@
 
   // If encoder selector is available, switch to the encoder it prefers.
   // Otherwise try switching to VP8 (default WebRTC codec).
-  absl::optional<SdpVideoFormat> preferred_fallback_encoder;
+  std::optional<SdpVideoFormat> preferred_fallback_encoder;
   if (is_encoder_selector_available) {
     preferred_fallback_encoder = encoder_selector_->OnEncoderBroken();
   }
@@ -1644,9 +1644,9 @@
   // This method may be called after we cleared out the frame_cadence_adapter_
   // reference in Stop(). In such a situation it's probably not important with a
   // decent estimate.
-  absl::optional<uint32_t> input_fps =
+  std::optional<uint32_t> input_fps =
       frame_cadence_adapter_ ? frame_cadence_adapter_->GetInputFrameRateFps()
-                             : absl::nullopt;
+                             : std::nullopt;
   if (!input_fps || *input_fps == 0) {
     return default_fps;
   }
@@ -2337,7 +2337,7 @@
       stream_resource_manager_.UseBandwidthAllocationBps().value_or(
           encoder_target_bitrate_bps_.value());
 
-  absl::optional<VideoEncoder::ResolutionBitrateLimits> encoder_bitrate_limits =
+  std::optional<VideoEncoder::ResolutionBitrateLimits> encoder_bitrate_limits =
       GetEncoderInfoWithBitrateLimitUpdate(
           encoder_->GetEncoderInfo(), encoder_config_, default_limits_allowed_)
           .GetEncoderBitrateLimitsForResolution(pixel_count);
@@ -2374,7 +2374,7 @@
   bool max_pixels_updated =
       (latest_restrictions_.has_value()
            ? latest_restrictions_->max_pixels_per_frame()
-           : absl::nullopt) != restrictions.max_pixels_per_frame();
+           : std::nullopt) != restrictions.max_pixels_per_frame();
 
   // TODO(webrtc:14451) Split video_source_sink_controller_
   // so that ownership on restrictions/wants is kept on &encoder_queue_
@@ -2412,7 +2412,7 @@
 
   RTC_DCHECK_RUN_ON(encoder_queue_.get());
 
-  absl::optional<int> encode_duration_us;
+  std::optional<int> encode_duration_us;
   if (encoded_image.timing_.flags != VideoSendTiming::kInvalid) {
     encode_duration_us =
         TimeDelta::Millis(encoded_image.timing_.encode_finish_ms -
diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h
index e593f91..dd423c3 100644
--- a/video/video_stream_encoder.h
+++ b/video/video_stream_encoder.h
@@ -309,14 +309,13 @@
   absl::InlinedVector<SetParametersCallback, 2> encoder_configuration_callbacks_
       RTC_GUARDED_BY(encoder_queue_);
 
-  absl::optional<VideoFrameInfo> last_frame_info_
-      RTC_GUARDED_BY(encoder_queue_);
+  std::optional<VideoFrameInfo> last_frame_info_ RTC_GUARDED_BY(encoder_queue_);
   int crop_width_ RTC_GUARDED_BY(encoder_queue_) = 0;
   int crop_height_ RTC_GUARDED_BY(encoder_queue_) = 0;
-  absl::optional<uint32_t> encoder_target_bitrate_bps_
+  std::optional<uint32_t> encoder_target_bitrate_bps_
       RTC_GUARDED_BY(encoder_queue_);
   size_t max_data_payload_length_ RTC_GUARDED_BY(encoder_queue_) = 0;
-  absl::optional<EncoderRateSettings> last_encoder_rate_settings_
+  std::optional<EncoderRateSettings> last_encoder_rate_settings_
       RTC_GUARDED_BY(encoder_queue_);
   bool encoder_paused_and_dropped_frame_ RTC_GUARDED_BY(encoder_queue_) = false;
 
@@ -336,7 +335,7 @@
   int captured_frame_count_ RTC_GUARDED_BY(encoder_queue_) = 0;
   int dropped_frame_cwnd_pushback_count_ RTC_GUARDED_BY(encoder_queue_) = 0;
   int dropped_frame_encoder_block_count_ RTC_GUARDED_BY(encoder_queue_) = 0;
-  absl::optional<VideoFrame> pending_frame_ RTC_GUARDED_BY(encoder_queue_);
+  std::optional<VideoFrame> pending_frame_ RTC_GUARDED_BY(encoder_queue_);
   int64_t pending_frame_post_time_us_ RTC_GUARDED_BY(encoder_queue_) = 0;
 
   VideoFrame::UpdateRect accumulated_update_rect_
@@ -345,9 +344,9 @@
 
   FecControllerOverride* fec_controller_override_
       RTC_GUARDED_BY(encoder_queue_) = nullptr;
-  absl::optional<int64_t> last_parameters_update_ms_
+  std::optional<int64_t> last_parameters_update_ms_
       RTC_GUARDED_BY(encoder_queue_);
-  absl::optional<int64_t> last_encode_info_ms_ RTC_GUARDED_BY(encoder_queue_);
+  std::optional<int64_t> last_encode_info_ms_ RTC_GUARDED_BY(encoder_queue_);
 
   VideoEncoder::EncoderInfo encoder_info_ RTC_GUARDED_BY(encoder_queue_);
   VideoCodec send_codec_ RTC_GUARDED_BY(encoder_queue_);
@@ -366,7 +365,7 @@
 
   // Congestion window frame drop ratio (drop 1 in every
   // cwnd_frame_drop_interval_ frames).
-  absl::optional<int> cwnd_frame_drop_interval_ RTC_GUARDED_BY(encoder_queue_);
+  std::optional<int> cwnd_frame_drop_interval_ RTC_GUARDED_BY(encoder_queue_);
   // Frame counter for congestion window frame drop.
   int cwnd_frame_counter_ RTC_GUARDED_BY(encoder_queue_) = 0;
 
@@ -428,8 +427,8 @@
   // Enables encoder switching on initialization failures.
   bool switch_encoder_on_init_failures_;
 
-  const absl::optional<int> vp9_low_tier_core_threshold_;
-  const absl::optional<int> experimental_encoder_thread_limit_;
+  const std::optional<int> vp9_low_tier_core_threshold_;
+  const std::optional<int> experimental_encoder_thread_limit_;
 
   // This is a copy of restrictions (glorified max_pixel_count) set by
   // OnVideoSourceRestrictionsUpdated. It is used to scale down encoding
@@ -438,7 +437,7 @@
   // TODO(webrtc:14451) Split video_source_sink_controller_
   // so that ownership on restrictions/wants is kept on &encoder_queue_, that
   // these extra copies would not be needed.
-  absl::optional<VideoSourceRestrictions> latest_restrictions_
+  std::optional<VideoSourceRestrictions> latest_restrictions_
       RTC_GUARDED_BY(encoder_queue_);
 
   // Used to cancel any potentially pending tasks to the worker thread.
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index e208501..46df928 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -300,7 +300,7 @@
   return AllOf(
       WantsMaxPixels(Eq(std::numeric_limits<int>::max())),
       Field("target_pixel_count", &rtc::VideoSinkWants::target_pixel_count,
-            Eq(absl::nullopt)));
+            Eq(std::nullopt)));
 }
 
 auto FpsMax() {
@@ -553,8 +553,8 @@
     return last_wants_;
   }
 
-  absl::optional<int> last_sent_width() const { return last_width_; }
-  absl::optional<int> last_sent_height() const { return last_height_; }
+  std::optional<int> last_sent_width() const { return last_width_; }
+  std::optional<int> last_sent_height() const { return last_height_; }
 
   void IncomingCapturedFrame(const VideoFrame& video_frame) override {
     RTC_DCHECK(time_controller_->GetMainThread()->IsCurrent());
@@ -591,8 +591,8 @@
         last_width_.emplace(adapted_frame.width());
         last_height_.emplace(adapted_frame.height());
       } else {
-        last_width_ = absl::nullopt;
-        last_height_ = absl::nullopt;
+        last_width_ = std::nullopt;
+        last_height_ = std::nullopt;
       }
     } else {
       RTC_DLOG(LS_INFO) << "IncomingCapturedFrame: adaptation not enabled";
@@ -603,10 +603,10 @@
   }
 
   void OnOutputFormatRequest(int width, int height) {
-    absl::optional<std::pair<int, int>> target_aspect_ratio =
+    std::optional<std::pair<int, int>> target_aspect_ratio =
         std::make_pair(width, height);
-    absl::optional<int> max_pixel_count = width * height;
-    absl::optional<int> max_fps;
+    std::optional<int> max_pixel_count = width * height;
+    std::optional<int> max_fps;
     adapter_.OnOutputFormatRequest(target_aspect_ratio, max_pixel_count,
                                    max_fps);
   }
@@ -632,8 +632,8 @@
   cricket::VideoAdapter adapter_;
   bool adaptation_enabled_ RTC_GUARDED_BY(mutex_);
   rtc::VideoSinkWants last_wants_ RTC_GUARDED_BY(mutex_);
-  absl::optional<int> last_width_;
-  absl::optional<int> last_height_;
+  std::optional<int> last_width_;
+  std::optional<int> last_height_;
   int refresh_frames_requested_{0};
 };
 
@@ -681,7 +681,7 @@
   }
 
   mutable Mutex lock_;
-  absl::optional<VideoSendStream::Stats> mock_stats_ RTC_GUARDED_BY(lock_);
+  std::optional<VideoSendStream::Stats> mock_stats_ RTC_GUARDED_BY(lock_);
   std::function<void(DropReason)> on_frame_dropped_;
 };
 
@@ -797,10 +797,10 @@
   MOCK_METHOD(void, Initialize, (Callback * callback), (override));
   MOCK_METHOD(void,
               SetZeroHertzModeEnabled,
-              (absl::optional<ZeroHertzModeParams>),
+              (std::optional<ZeroHertzModeParams>),
               (override));
   MOCK_METHOD(void, OnFrame, (const VideoFrame&), (override));
-  MOCK_METHOD(absl::optional<uint32_t>, GetInputFrameRateFps, (), (override));
+  MOCK_METHOD(std::optional<uint32_t>, GetInputFrameRateFps, (), (override));
   MOCK_METHOD(void,
               UpdateLayerQualityConvergence,
               (size_t spatial_index, bool converged),
@@ -811,7 +811,7 @@
               (override));
   MOCK_METHOD(void,
               UpdateVideoSourceRestrictions,
-              (absl::optional<double>),
+              (std::optional<double>),
               (override));
   MOCK_METHOD(void, ProcessKeyFrameRequest, (), (override));
 };
@@ -823,15 +823,15 @@
               OnCurrentEncoder,
               (const SdpVideoFormat& format),
               (override));
-  MOCK_METHOD(absl::optional<SdpVideoFormat>,
+  MOCK_METHOD(std::optional<SdpVideoFormat>,
               OnAvailableBitrate,
               (const DataRate& rate),
               (override));
-  MOCK_METHOD(absl::optional<SdpVideoFormat>,
+  MOCK_METHOD(std::optional<SdpVideoFormat>,
               OnResolutionChange,
               (const RenderResolution& resolution),
               (override));
-  MOCK_METHOD(absl::optional<SdpVideoFormat>, OnEncoderBroken, (), (override));
+  MOCK_METHOD(std::optional<SdpVideoFormat>, OnEncoderBroken, (), (override));
 };
 
 class MockVideoSourceInterface : public rtc::VideoSourceInterface<VideoFrame> {
@@ -922,7 +922,7 @@
                     size_t num_temporal_layers,
                     unsigned char num_spatial_layers,
                     bool screenshare,
-                    absl::optional<int> max_frame_rate = kDefaultFramerate,
+                    std::optional<int> max_frame_rate = kDefaultFramerate,
                     VideoStreamEncoder::BitrateAllocationCallbackType
                         allocation_callback_type =
                             VideoStreamEncoder::BitrateAllocationCallbackType::
@@ -1205,7 +1205,7 @@
       expect_null_frame_ = true;
     }
 
-    absl::optional<VideoEncoder::RateControlParameters>
+    std::optional<VideoEncoder::RateControlParameters>
     GetAndResetLastRateControlSettings() {
       auto settings = last_rate_control_settings_;
       last_rate_control_settings_.reset();
@@ -1222,7 +1222,7 @@
       return last_input_height_;
     }
 
-    absl::optional<VideoFrameBuffer::Type> GetLastInputPixelFormat() {
+    std::optional<VideoFrameBuffer::Type> GetLastInputPixelFormat() {
       MutexLock lock(&local_mutex_);
       return last_input_pixel_format_;
     }
@@ -1239,7 +1239,7 @@
       preferred_pixel_formats_ = std::move(pixel_formats);
     }
 
-    void SetIsQpTrusted(absl::optional<bool> trusted) {
+    void SetIsQpTrusted(std::optional<bool> trusted) {
       MutexLock lock(&local_mutex_);
       is_qp_trusted_ = trusted;
     }
@@ -1367,13 +1367,13 @@
         RTC_GUARDED_BY(local_mutex_);
     std::unique_ptr<Vp8FrameBufferController> frame_buffer_controller_
         RTC_GUARDED_BY(local_mutex_);
-    absl::optional<bool>
+    std::optional<bool>
         temporal_layers_supported_[kMaxSpatialLayers] RTC_GUARDED_BY(
             local_mutex_);
     bool force_init_encode_failed_ RTC_GUARDED_BY(local_mutex_) = false;
     double rate_factor_ RTC_GUARDED_BY(local_mutex_) = 1.0;
     uint32_t last_framerate_ RTC_GUARDED_BY(local_mutex_) = 0;
-    absl::optional<VideoEncoder::RateControlParameters>
+    std::optional<VideoEncoder::RateControlParameters>
         last_rate_control_settings_;
     VideoFrame::UpdateRect last_update_rect_ RTC_GUARDED_BY(local_mutex_) = {
         0, 0, 0, 0};
@@ -1385,11 +1385,11 @@
     std::vector<ResolutionBitrateLimits> resolution_bitrate_limits_
         RTC_GUARDED_BY(local_mutex_);
     int num_set_rates_ RTC_GUARDED_BY(local_mutex_) = 0;
-    absl::optional<VideoFrameBuffer::Type> last_input_pixel_format_
+    std::optional<VideoFrameBuffer::Type> last_input_pixel_format_
         RTC_GUARDED_BY(local_mutex_);
     absl::InlinedVector<VideoFrameBuffer::Type, kMaxPreferredPixelFormats>
         preferred_pixel_formats_ RTC_GUARDED_BY(local_mutex_);
-    absl::optional<bool> is_qp_trusted_ RTC_GUARDED_BY(local_mutex_);
+    std::optional<bool> is_qp_trusted_ RTC_GUARDED_BY(local_mutex_);
     VideoCodecComplexity last_encoder_complexity_ RTC_GUARDED_BY(local_mutex_){
         VideoCodecComplexity::kComplexityNormal};
   };
@@ -2300,7 +2300,7 @@
   video_stream_encoder_->ConfigureEncoder(config.Copy(), kMaxPayloadLength);
 
   // Default bitrate limits for 270p should be used.
-  const absl::optional<VideoEncoder::ResolutionBitrateLimits>
+  const std::optional<VideoEncoder::ResolutionBitrateLimits>
       kDefaultLimits270p =
           EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
               kVideoCodecVP8, 480 * 270);
@@ -2313,7 +2313,7 @@
             fake_encoder_.config().simulcastStream[1].maxBitrate * 1000);
 
   // Default bitrate limits for 360p should be used.
-  const absl::optional<VideoEncoder::ResolutionBitrateLimits>
+  const std::optional<VideoEncoder::ResolutionBitrateLimits>
       kDefaultLimits360p =
           EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
               kVideoCodecVP8, 640 * 360);
@@ -2334,7 +2334,7 @@
             fake_encoder_.config().simulcastStream[1].maxBitrate * 1000);
 
   // Default bitrate limits for 540p should be used.
-  const absl::optional<VideoEncoder::ResolutionBitrateLimits>
+  const std::optional<VideoEncoder::ResolutionBitrateLimits>
       kDefaultLimits540p =
           EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
               kVideoCodecVP8, 960 * 540);
@@ -6066,7 +6066,7 @@
                                           kMaxPayloadLength);
 
   // The default bitrate limits for 360p should be used.
-  const absl::optional<VideoEncoder::ResolutionBitrateLimits> kLimits360p =
+  const std::optional<VideoEncoder::ResolutionBitrateLimits> kLimits360p =
       EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
           kVideoCodecVP9, 640 * 360);
   video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
@@ -6083,7 +6083,7 @@
             fake_encoder_.config().spatialLayers[0].maxBitrate * 1000);
 
   // The default bitrate limits for 270p should be used.
-  const absl::optional<VideoEncoder::ResolutionBitrateLimits> kLimits270p =
+  const std::optional<VideoEncoder::ResolutionBitrateLimits> kLimits270p =
       EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
           kVideoCodecVP9, 480 * 270);
   video_source_.IncomingCapturedFrame(CreateFrame(2, 960, 540));
@@ -6131,7 +6131,7 @@
                                           kMaxPayloadLength);
 
   // The default bitrate limits for 360p should not be used.
-  const absl::optional<VideoEncoder::ResolutionBitrateLimits> kLimits360p =
+  const std::optional<VideoEncoder::ResolutionBitrateLimits> kLimits360p =
       EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
           kVideoCodecVP9, 640 * 360);
   video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
@@ -6153,7 +6153,7 @@
                /*num_spatial_layers=*/1, /*screenshare=*/false);
 
   // The default singlecast bitrate limits for 720p should not be used.
-  const absl::optional<VideoEncoder::ResolutionBitrateLimits> kLimits720p =
+  const std::optional<VideoEncoder::ResolutionBitrateLimits> kLimits720p =
       EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
           kVideoCodecVP9, 1280 * 720);
   video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
@@ -7820,7 +7820,7 @@
   ConfigureEncoder(video_encoder_config_.Copy());
 
   EXPECT_CALL(encoder_selector, OnResolutionChange(RenderResolution(640, 480)))
-      .WillOnce(Return(absl::nullopt));
+      .WillOnce(Return(std::nullopt));
   EXPECT_CALL(encoder_selector, OnResolutionChange(RenderResolution(320, 240)))
       .WillOnce(Return(SdpVideoFormat("AV1")));
   EXPECT_CALL(switch_callback,
@@ -8542,7 +8542,7 @@
   // Set QP not trusted in encoder info.
   fake_encoder_.SetIsQpTrusted(false);
 
-  absl::optional<VideoEncoder::ResolutionBitrateLimits> suitable_bitrate_limit =
+  std::optional<VideoEncoder::ResolutionBitrateLimits> suitable_bitrate_limit =
       EncoderInfoSettings::
           GetSinglecastBitrateLimitForResolutionWhenQpIsUntrusted(
               codec_width_ * codec_height_,
@@ -8583,7 +8583,7 @@
   // Set QP not trusted in encoder info.
   fake_encoder_.SetIsQpTrusted(false);
 
-  absl::optional<VideoEncoder::ResolutionBitrateLimits> suitable_bitrate_limit =
+  std::optional<VideoEncoder::ResolutionBitrateLimits> suitable_bitrate_limit =
       EncoderInfoSettings::
           GetSinglecastBitrateLimitForResolutionWhenQpIsUntrusted(
               codec_width_ * codec_height_,
@@ -9243,7 +9243,7 @@
     stream.scale_resolution_down_by = 1.0;
     stream.num_temporal_layers = 1;
     stream.bitrate_priority = 1.0;
-    stream.scalability_mode = absl::nullopt;
+    stream.scalability_mode = std::nullopt;
     return stream;
   }
 
@@ -9418,7 +9418,7 @@
   Mock::VerifyAndClearExpectations(adapter_ptr);
 
   // Expect a disabled zero-hertz mode after passing realtime video.
-  EXPECT_CALL(*adapter_ptr, SetZeroHertzModeEnabled(Eq(absl::nullopt)));
+  EXPECT_CALL(*adapter_ptr, SetZeroHertzModeEnabled(Eq(std::nullopt)));
   VideoEncoderConfig config2;
   test::FillEncoderConfiguration(kVideoCodecVP8, 1, &config2);
   config2.content_type = VideoEncoderConfig::ContentType::kRealtimeVideo;
@@ -9715,7 +9715,7 @@
 
 TEST_F(VideoStreamEncoderFrameCadenceRestrictionTest,
        UpdatesVideoSourceRestrictionsUnRestricted) {
-  EXPECT_CALL(*adapter_ptr_, UpdateVideoSourceRestrictions(Eq(absl::nullopt)));
+  EXPECT_CALL(*adapter_ptr_, UpdateVideoSourceRestrictions(Eq(std::nullopt)));
   UpdateVideoSourceRestrictions(VideoSourceRestrictions());
 }
 
@@ -9732,7 +9732,7 @@
   // FPS is unlimited.
   restrictions_.set_max_pixels_per_frame(99);
   restrictions_.set_target_pixels_per_frame(101);
-  EXPECT_CALL(*adapter_ptr_, UpdateVideoSourceRestrictions(Eq(absl::nullopt)));
+  EXPECT_CALL(*adapter_ptr_, UpdateVideoSourceRestrictions(Eq(std::nullopt)));
   UpdateVideoSourceRestrictions(restrictions_);
 }