Put current send codec to front of codecs list in RTP sender parameters

WebRTC can switch encoder on-fly when encoder fails or by request from
encoder selector. Putting the current send codec to the front of the
codecs list provides a simple way for apps to know what is actually
used without retrieving stats.

Bug: webrtc:13572
Change-Id: Iaaa5f7ad8667f59016dc92bff9e9a57a7425ef44
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/246500
Reviewed-by: Mirta Dvornicic <mirtad@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35723}
diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc
index 8dd75c2..b67f4df 100644
--- a/media/engine/webrtc_video_engine.cc
+++ b/media/engine/webrtc_video_engine.cc
@@ -1069,8 +1069,16 @@
   // Need to add the common list of codecs to the send stream-specific
   // RTP parameters.
   for (const VideoCodec& codec : send_params_.codecs) {
-    rtp_params.codecs.push_back(codec.ToCodecParameters());
+    if (send_codec_ && send_codec_->codec.id == codec.id) {
+      // Put the current send codec to the front of the codecs list.
+      RTC_DCHECK_EQ(codec.name, send_codec_->codec.name);
+      rtp_params.codecs.insert(rtp_params.codecs.begin(),
+                               codec.ToCodecParameters());
+    } else {
+      rtp_params.codecs.push_back(codec.ToCodecParameters());
+    }
   }
+
   return rtp_params;
 }
 
diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc
index 7c89c19..91329e6 100644
--- a/media/engine/webrtc_video_engine_unittest.cc
+++ b/media/engine/webrtc_video_engine_unittest.cc
@@ -2517,6 +2517,27 @@
   EXPECT_THAT(codec.params, Contains(Pair(kParam, kPing)));
 }
 
+TEST_F(WebRtcVideoChannelBaseTest, SendCodecIsMovedToFrontInRtpParameters) {
+  cricket::VideoSendParameters parameters;
+  parameters.codecs.push_back(GetEngineCodec("VP9"));
+  parameters.codecs.push_back(GetEngineCodec("VP8"));
+  EXPECT_TRUE(channel_->SetSendParameters(parameters));
+  channel_->SetVideoCodecSwitchingEnabled(true);
+
+  auto send_codecs = channel_->GetRtpSendParameters(kSsrc).codecs;
+  ASSERT_EQ(send_codecs.size(), 2u);
+  EXPECT_THAT("VP9", send_codecs[0].name);
+
+  // RequestEncoderFallback will post a task to the worker thread (which is also
+  // the current thread), hence the ProcessMessages call.
+  channel_->RequestEncoderFallback();
+  rtc::Thread::Current()->ProcessMessages(30);
+
+  send_codecs = channel_->GetRtpSendParameters(kSsrc).codecs;
+  ASSERT_EQ(send_codecs.size(), 2u);
+  EXPECT_THAT("VP8", send_codecs[0].name);
+}
+
 #endif  // defined(RTC_ENABLE_VP9)
 
 class WebRtcVideoChannelTest : public WebRtcVideoEngineTest {