Define default max Qp in media/base/media_constants

kDefaultQpMax=56 was defined in multiple places. Move it to media_constants and split it into two: VPx/AV1 and H26x values. H26x value is set to 51 which is the max bitstream QP value for H264/5.

This CL is expected to be a no-op because:
1. VideoCodec::qpMax value has not changed for VP8/9 and AV1.
2. VideoCodec::qpMax is currently not used by OpenH264 wrapper (wiring it up is out-of-scope of this CL).
3. Previous default qpMax=56 exceeded the max value for H26x (=51). External HW H26x encoders likely clamped it and used 51.

Bug: webrtc:14852
Change-Id: I1d795e695dac5c78e86ed829b24281e61066f668
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/324282
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40997}
diff --git a/media/BUILD.gn b/media/BUILD.gn
index 28822a1..cf7c523 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -350,6 +350,7 @@
     "../api/video_codecs:video_codecs_api",
     "../call:video_stream_api",
     "../common_video",
+    "../media:media_constants",
     "../modules/video_coding:video_codec_interface",
     "../modules/video_coding:video_coding_utility",
     "../rtc_base:checks",
diff --git a/media/base/media_constants.cc b/media/base/media_constants.cc
index 94ce3c7..2af0295 100644
--- a/media/base/media_constants.cc
+++ b/media/base/media_constants.cc
@@ -127,6 +127,11 @@
 const char kVP9ProfileId[] = "profile-id";
 
 const int kDefaultVideoMaxFramerate = 60;
+// Max encode quantizer for VP8/9 and AV1 encoders assuming libvpx/libaom API
+// range [0, 63]
+const int kDefaultVideoMaxQpVpx = 56;
+// Max encode quantizer for H264/5 assuming the bitstream range [0, 51].
+const int kDefaultVideoMaxQpH26x = 51;
 
 const size_t kConferenceMaxNumSpatialLayers = 3;
 const size_t kConferenceMaxNumTemporalLayers = 3;
diff --git a/media/base/media_constants.h b/media/base/media_constants.h
index 3321aac..877cc7a 100644
--- a/media/base/media_constants.h
+++ b/media/base/media_constants.h
@@ -150,6 +150,8 @@
 extern const char kVP9ProfileId[];
 
 extern const int kDefaultVideoMaxFramerate;
+extern const int kDefaultVideoMaxQpVpx;
+extern const int kDefaultVideoMaxQpH26x;
 
 extern const size_t kConferenceMaxNumSpatialLayers;
 extern const size_t kConferenceMaxNumTemporalLayers;
diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc
index f0bc6ae..4853e68 100644
--- a/media/engine/simulcast_encoder_adapter.cc
+++ b/media/engine/simulcast_encoder_adapter.cc
@@ -29,6 +29,7 @@
 #include "api/video_codecs/video_encoder.h"
 #include "api/video_codecs/video_encoder_factory.h"
 #include "api/video_codecs/video_encoder_software_fallback_wrapper.h"
+#include "media/base/media_constants.h"
 #include "media/base/video_common.h"
 #include "modules/video_coding/include/video_error_codes.h"
 #include "modules/video_coding/utility/simulcast_rate_allocator.h"
@@ -38,8 +39,6 @@
 
 namespace {
 
-const unsigned int kDefaultMinQp = 2;
-const unsigned int kDefaultMaxQp = 56;
 // Max qp for lowest spatial resolution when doing simulcast.
 const unsigned int kLowestResMaxQp = 45;
 
@@ -327,11 +326,6 @@
   codec_ = *codec_settings;
   total_streams_count_ = CountAllStreams(*codec_settings);
 
-  // TODO(ronghuawu): Remove once this is handled in LibvpxVp8Encoder.
-  if (codec_.qpMax < kDefaultMinQp) {
-    codec_.qpMax = kDefaultMaxQp;
-  }
-
   bool is_legacy_singlecast = codec_.numberOfSimulcastStreams == 0;
   int lowest_quality_stream_idx = 0;
   int highest_quality_stream_idx = 0;
diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc
index ca07ef5..8a9d6ff 100644
--- a/media/engine/webrtc_video_engine.cc
+++ b/media/engine/webrtc_video_engine.cc
@@ -2228,7 +2228,20 @@
   // Ensure frame dropping is always enabled.
   encoder_config.frame_drop_enabled = true;
 
-  int max_qp = kDefaultQpMax;
+  int max_qp;
+  switch (encoder_config.codec_type) {
+    case webrtc::kVideoCodecH264:
+    case webrtc::kVideoCodecH265:
+      max_qp = kDefaultVideoMaxQpH26x;
+      break;
+    case webrtc::kVideoCodecVP8:
+    case webrtc::kVideoCodecVP9:
+    case webrtc::kVideoCodecAV1:
+    case webrtc::kVideoCodecGeneric:
+    case webrtc::kVideoCodecMultiplex:
+      max_qp = kDefaultVideoMaxQpVpx;
+      break;
+  }
   codec.GetParam(kCodecParamMaxQuantization, &max_qp);
   encoder_config.max_qp = max_qp;
 
diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h
index 2d14312..e4b1b27 100644
--- a/media/engine/webrtc_video_engine.h
+++ b/media/engine/webrtc_video_engine.h
@@ -250,6 +250,8 @@
     ADAPTREASON_BANDWIDTH = 2,
   };
 
+  // TODO(webrtc:14852): Update downstream projects to use
+  // cricket::kDefaultVideoMaxQpVpx/H26x and remove.
   static constexpr int kDefaultQpMax = 56;
 
   // Implements webrtc::EncoderSwitchRequestCallback.
diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc
index d9fcf82..e8b7ee4 100644
--- a/media/engine/webrtc_video_engine_unittest.cc
+++ b/media/engine/webrtc_video_engine_unittest.cc
@@ -37,6 +37,7 @@
 #include "api/video/video_bitrate_allocation.h"
 #include "api/video_codecs/h264_profile_level_id.h"
 #include "api/video_codecs/sdp_video_format.h"
+#include "api/video_codecs/video_codec.h"
 #include "api/video_codecs/video_decoder_factory.h"
 #include "api/video_codecs/video_decoder_factory_template.h"
 #include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h"
@@ -110,7 +111,6 @@
 using ::webrtc::test::RtcpPacketParser;
 
 namespace {
-static const int kDefaultQpMax = 56;
 
 static const uint8_t kRedRtxPayloadType = 125;
 
@@ -4866,7 +4866,7 @@
 TEST_F(WebRtcVideoChannelTest, SetSendCodecsChangesExistingStreams) {
   cricket::VideoSenderParameters parameters;
   cricket::VideoCodec codec = cricket::CreateVideoCodec(100, "VP8");
-  codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax);
+  codec.SetParam(kCodecParamMaxQuantization, kDefaultVideoMaxQpVpx);
   parameters.codecs.push_back(codec);
 
   ASSERT_TRUE(send_channel_->SetSenderParameters(parameters));
@@ -4878,14 +4878,14 @@
       send_channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
 
   std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
-  EXPECT_EQ(kDefaultQpMax, streams[0].max_qp);
+  EXPECT_EQ(kDefaultVideoMaxQpVpx, streams[0].max_qp);
 
   parameters.codecs.clear();
-  codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax + 1);
+  codec.SetParam(kCodecParamMaxQuantization, kDefaultVideoMaxQpVpx + 1);
   parameters.codecs.push_back(codec);
   ASSERT_TRUE(send_channel_->SetSenderParameters(parameters));
   streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
-  EXPECT_EQ(kDefaultQpMax + 1, streams[0].max_qp);
+  EXPECT_EQ(kDefaultVideoMaxQpVpx + 1, streams[0].max_qp);
   EXPECT_TRUE(send_channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
 }
 
@@ -9772,8 +9772,9 @@
     if (num_configured_streams > 1 || conference_mode) {
       expected_streams = GetSimulcastConfig(
           /*min_layers=*/1, num_configured_streams, capture_width,
-          capture_height, webrtc::kDefaultBitratePriority, kDefaultQpMax,
-          screenshare && conference_mode, true, field_trials_);
+          capture_height, webrtc::kDefaultBitratePriority,
+          kDefaultVideoMaxQpVpx, screenshare && conference_mode, true,
+          field_trials_);
       if (screenshare && conference_mode) {
         for (const webrtc::VideoStream& stream : expected_streams) {
           // Never scale screen content.
@@ -9789,7 +9790,7 @@
       stream.min_bitrate_bps = webrtc::kDefaultMinVideoBitrateBps;
       stream.target_bitrate_bps = stream.max_bitrate_bps =
           GetMaxDefaultBitrateBps(capture_width, capture_height);
-      stream.max_qp = kDefaultQpMax;
+      stream.max_qp = kDefaultVideoMaxQpVpx;
       expected_streams.push_back(stream);
     }
 
diff --git a/rtc_tools/BUILD.gn b/rtc_tools/BUILD.gn
index 27a9a9d..13d6df4 100644
--- a/rtc_tools/BUILD.gn
+++ b/rtc_tools/BUILD.gn
@@ -448,6 +448,7 @@
       "//api/video:builtin_video_bitrate_allocator_factory",
       "//api/video_codecs:builtin_video_encoder_factory",
       "//api/video_codecs:video_codecs_api",
+      "//media:media_constants",
       "//modules/video_coding:video_codec_interface",
       "//modules/video_coding:video_coding_utility",
       "//modules/video_coding/codecs/av1:av1_svc_config",
diff --git a/rtc_tools/video_encoder/video_encoder.cc b/rtc_tools/video_encoder/video_encoder.cc
index d2b9b58..9436910 100644
--- a/rtc_tools/video_encoder/video_encoder.cc
+++ b/rtc_tools/video_encoder/video_encoder.cc
@@ -16,6 +16,7 @@
 #include "api/test/frame_generator_interface.h"
 #include "api/video/builtin_video_bitrate_allocator_factory.h"
 #include "api/video_codecs/builtin_video_encoder_factory.h"
+#include "media/base/media_constants.h"
 #include "modules/video_coding/codecs/av1/av1_svc_config.h"
 #include "modules/video_coding/include/video_codec_interface.h"
 #include "modules/video_coding/svc/scalability_mode_util.h"
@@ -72,9 +73,6 @@
 namespace webrtc {
 namespace {
 
-// See `WebRtcVideoSendChannel::kDefaultQpMax`.
-constexpr unsigned int kDefaultQpMax = 56;
-
 [[maybe_unused]] const char* InterLayerPredModeToString(
     const InterLayerPredMode& inter_layer_pred_mode) {
   switch (inter_layer_pred_mode) {
@@ -257,8 +255,6 @@
 
     video_codec.active = true;
 
-    video_codec.qpMax = kDefaultQpMax;
-
     // Simulcast is not implemented at this moment.
     video_codec.numberOfSimulcastStreams = 0;
 
@@ -270,6 +266,7 @@
 
         *(video_codec.VP8()) = VideoEncoder::GetDefaultVp8Settings();
         video_codec.VP8()->numberOfTemporalLayers = temporal_layers;
+        video_codec.qpMax = cricket::kDefaultVideoMaxQpVpx;
         break;
 
       case kVideoCodecVP9:
@@ -277,6 +274,7 @@
         video_codec.VP9()->numberOfSpatialLayers = spatial_layers;
         video_codec.VP9()->numberOfTemporalLayers = temporal_layers;
         video_codec.VP9()->interLayerPred = inter_layer_pred_mode;
+        video_codec.qpMax = cricket::kDefaultVideoMaxQpVpx;
         break;
 
       case kVideoCodecH264:
@@ -284,6 +282,7 @@
 
         *(video_codec.H264()) = VideoEncoder::GetDefaultH264Settings();
         video_codec.H264()->numberOfTemporalLayers = temporal_layers;
+        video_codec.qpMax = cricket::kDefaultVideoMaxQpH26x;
         break;
 
       case kVideoCodecAV1:
@@ -294,9 +293,11 @@
         } else {
           RTC_LOG(LS_WARNING) << "Failed to configure svc bitrates for av1.";
         }
+        video_codec.qpMax = cricket::kDefaultVideoMaxQpVpx;
         break;
       case kVideoCodecH265:
         // TODO(bugs.webrtc.org/13485)
+        video_codec.qpMax = cricket::kDefaultVideoMaxQpH26x;
         break;
       default:
         RTC_CHECK_NOTREACHED();
diff --git a/test/scenario/video_stream.cc b/test/scenario/video_stream.cc
index d376a8f..38e42c8 100644
--- a/test/scenario/video_stream.cc
+++ b/test/scenario/video_stream.cc
@@ -40,7 +40,6 @@
   kVideoRotationRtpExtensionId,
 };
 
-constexpr int kDefaultMaxQp = cricket::WebRtcVideoSendChannel::kDefaultQpMax;
 uint8_t CodecTypeToPayloadType(VideoCodecType codec_type) {
   switch (codec_type) {
     case VideoCodecType::kVideoCodecGeneric:
@@ -234,8 +233,8 @@
                        VideoStreamConfig::Encoder::ContentType::kScreen;
     encoder_config.video_stream_factory =
         rtc::make_ref_counted<cricket::EncoderStreamFactory>(
-            cricket_codec, kDefaultMaxQp, screenshare, screenshare,
-            encoder_info);
+            cricket_codec, cricket::kDefaultVideoMaxQpVpx, screenshare,
+            screenshare, encoder_info);
   } else {
     encoder_config.video_stream_factory =
         rtc::make_ref_counted<DefaultVideoStreamFactory>();
diff --git a/video/video_quality_test.cc b/video/video_quality_test.cc
index 4086cdf..971c129 100644
--- a/video/video_quality_test.cc
+++ b/video/video_quality_test.cc
@@ -77,8 +77,6 @@
 constexpr uint32_t kThumbnailSendSsrcStart = 0xE0000;
 constexpr uint32_t kThumbnailRtxSsrcStart = 0xF0000;
 
-constexpr int kDefaultMaxQp = cricket::WebRtcVideoSendChannel::kDefaultQpMax;
-
 const VideoEncoder::Capabilities kCapabilities(false);
 
 std::pair<uint32_t, uint32_t> GetMinMaxBitratesBps(const VideoCodec& codec,
@@ -579,7 +577,7 @@
   stream.min_bitrate_bps = params.video[video_idx].min_bitrate_bps;
   stream.target_bitrate_bps = params.video[video_idx].target_bitrate_bps;
   stream.max_bitrate_bps = params.video[video_idx].max_bitrate_bps;
-  stream.max_qp = kDefaultMaxQp;
+  stream.max_qp = cricket::kDefaultVideoMaxQpVpx;
   stream.num_temporal_layers = params.video[video_idx].num_temporal_layers;
   stream.active = true;
   return stream;
@@ -594,7 +592,7 @@
   stream.min_bitrate_bps = 7500;
   stream.target_bitrate_bps = 37500;
   stream.max_bitrate_bps = 50000;
-  stream.max_qp = kDefaultMaxQp;
+  stream.max_qp = cricket::kDefaultVideoMaxQpVpx;
   return stream;
 }
 
@@ -627,7 +625,7 @@
     encoder_config.simulcast_layers = std::vector<VideoStream>(num_streams);
     encoder_config.video_stream_factory =
         rtc::make_ref_counted<cricket::EncoderStreamFactory>(
-            params->video[video_idx].codec, kDefaultMaxQp,
+            params->video[video_idx].codec, cricket::kDefaultVideoMaxQpVpx,
             params->screenshare[video_idx].enabled, true, encoder_info);
     params->ss[video_idx].streams =
         encoder_config.video_stream_factory->CreateEncoderStreams(