Reland "Extends WebRTC logs for software encoder fallback"

This is a reland of commit 050ffefd854f8a57071992238723259e9ae0d85a

Original change's description:
> Extends WebRTC logs for software encoder fallback
>
> This CL extends logging related to HW->SW fallbacks on the encoder
> side in WebRTC. The goal is to make it easier to track down the
> different steps taken when setting up the video encoder and why/when
> HW encoding fails.
>
> Current logs are added on several lines which makes regexp searching
> difficult. This CL adds all related information on one line instead.
>
> Three new search tags are also added VSE (VideoStreamEncoder), VESFW
> (VideoEncoderSoftwareFallbackWrapper) and SEA (SimulcastEncoderAdapter). The idea is to allow searching for the tags to see correlated logs.
>
> It has been verified that these added logs also show up in WebRTC
> logs in Meet.
>
> Logs from the GPU process are not included due to the sandboxed
> nature which makes it much more complex to add to the native
> WebRTC log. I think that these simple logs will provide value as is.
>
> Example: https://gist.github.com/henrik-and/41946f7f0b10774241bd14d7687f770b
>
> Bug: b/322132132
> Change-Id: Iec58c9741a9dd6bab3236a88e9a6e45440f5d980
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339260
> Commit-Queue: Henrik Andreassson <henrika@webrtc.org>
> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#41733}

NOTRY=true

Bug: b/322132132
Change-Id: I25dd34b9ba59ea8502e47b4c89cd111430636e08
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339680
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Henrik Andreassson <henrika@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41736}
diff --git a/api/video_codecs/video_codec.cc b/api/video_codecs/video_codec.cc
index 39a345d..82c9bfc 100644
--- a/api/video_codecs/video_codec.cc
+++ b/api/video_codecs/video_codec.cc
@@ -16,6 +16,7 @@
 
 #include "absl/strings/match.h"
 #include "rtc_base/checks.h"
+#include "rtc_base/strings/string_builder.h"
 
 namespace webrtc {
 namespace {
@@ -73,6 +74,35 @@
       codec_specific_(),
       complexity_(VideoCodecComplexity::kComplexityNormal) {}
 
+std::string VideoCodec::ToString() const {
+  char string_buf[2048];
+  rtc::SimpleStringBuilder ss(string_buf);
+
+  ss << "VideoCodec {" << "type: " << CodecTypeToPayloadString(codecType)
+     << ", mode: "
+     << (mode == VideoCodecMode::kRealtimeVideo ? "RealtimeVideo"
+                                                : "Screensharing");
+  if (IsSinglecast()) {
+    absl::optional<ScalabilityMode> scalability_mode = GetScalabilityMode();
+    if (scalability_mode.has_value()) {
+      ss << ", Singlecast: {" << width << "x" << height << " "
+         << ScalabilityModeToString(*scalability_mode)
+         << (active ? ", active" : ", inactive") << "}";
+    }
+  } else {
+    ss << ", Simulcast: {";
+    for (size_t i = 0; i < numberOfSimulcastStreams; ++i) {
+      const SimulcastStream stream = simulcastStream[i];
+      ss << "[" << stream.width << "x" << stream.height << " "
+         << ScalabilityModeToString(stream.GetScalabilityMode())
+         << (stream.active ? ", active" : ", inactive") << "]";
+    }
+    ss << "}";
+  }
+  ss << "}";
+  return ss.str();
+}
+
 VideoCodecVP8* VideoCodec::VP8() {
   RTC_DCHECK_EQ(codecType, kVideoCodecVP8);
   return &codec_specific_.VP8;
diff --git a/api/video_codecs/video_codec.h b/api/video_codecs/video_codec.h
index a596af1..e48ffd4 100644
--- a/api/video_codecs/video_codec.h
+++ b/api/video_codecs/video_codec.h
@@ -141,6 +141,9 @@
   bool GetFrameDropEnabled() const;
   void SetFrameDropEnabled(bool enabled);
 
+  bool IsSinglecast() const { return numberOfSimulcastStreams <= 1; }
+  bool IsSimulcast() const { return !IsSinglecast(); }
+
   // Public variables. TODO(hta): Make them private with accessors.
   VideoCodecType codecType;
 
@@ -193,6 +196,7 @@
 
   bool operator==(const VideoCodec& other) const = delete;
   bool operator!=(const VideoCodec& other) const = delete;
+  std::string ToString() const;
 
   // Accessors for codec specific information.
   // There is a const version of each that returns a reference,
diff --git a/api/video_codecs/video_encoder_software_fallback_wrapper.cc b/api/video_codecs/video_encoder_software_fallback_wrapper.cc
index d35c9f9..e50b508 100644
--- a/api/video_codecs/video_encoder_software_fallback_wrapper.cc
+++ b/api/video_codecs/video_encoder_software_fallback_wrapper.cc
@@ -28,6 +28,7 @@
 #include "api/video_codecs/video_encoder.h"
 #include "media/base/video_common.h"
 #include "modules/video_coding/include/video_error_codes.h"
+#include "modules/video_coding/include/video_error_codes_utils.h"
 #include "modules/video_coding/utility/simulcast_utility.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/experiments/field_trial_parser.h"
@@ -264,14 +265,17 @@
 }
 
 bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder(bool is_forced) {
-  RTC_LOG(LS_WARNING) << "Encoder falling back to software encoding.";
+  RTC_LOG(LS_WARNING) << "[VESFW] " << __func__
+                      << "(is_forced=" << (is_forced ? "true" : "false") << ")";
 
   RTC_DCHECK(encoder_settings_.has_value());
   const int ret = fallback_encoder_->InitEncode(&codec_settings_,
                                                 encoder_settings_.value());
 
   if (ret != WEBRTC_VIDEO_CODEC_OK) {
-    RTC_LOG(LS_ERROR) << "Failed to initialize software-encoder fallback.";
+    RTC_LOG(LS_ERROR)
+        << "[VESFW] software-encoder fallback initialization failed with"
+        << " error code: " << WebRtcVideoCodecErrorToString(ret);
     fallback_encoder_->Release();
     return false;
   }
@@ -305,6 +309,12 @@
 int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode(
     const VideoCodec* codec_settings,
     const VideoEncoder::Settings& settings) {
+  RTC_LOG(LS_INFO) << "[VESFW] " << __func__
+                   << "(codec=" << codec_settings->ToString()
+                   << ", settings={number_of_cores: "
+                   << settings.number_of_cores
+                   << ", max_payload_size: " << settings.max_payload_size
+                   << "})";
   // Store settings, in case we need to dynamically switch to the fallback
   // encoder after a failed Encode call.
   codec_settings_ = *codec_settings;
@@ -327,6 +337,8 @@
     PrimeEncoder(current_encoder());
     return ret;
   }
+  RTC_LOG(LS_WARNING) << "[VESFW] Hardware encoder initialization failed with"
+                      << " error code: " << WebRtcVideoCodecErrorToString(ret);
 
   // Try to instantiate software codec.
   if (InitFallbackEncoder(/*is_forced=*/false)) {
@@ -335,6 +347,8 @@
   }
 
   // Software encoder failed too, use original return code.
+  RTC_LOG(LS_WARNING)
+      << "[VESFW] Software fallback encoder initialization also failed.";
   encoder_state_ = EncoderState::kUninitialized;
   return ret;
 }
diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc
index 4853e68..642fe31 100644
--- a/media/engine/simulcast_encoder_adapter.cc
+++ b/media/engine/simulcast_encoder_adapter.cc
@@ -32,6 +32,7 @@
 #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/include/video_error_codes_utils.h"
 #include "modules/video_coding/utility/simulcast_rate_allocator.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/experiments/rate_control_settings.h"
@@ -360,8 +361,14 @@
   bool separate_encoders_needed =
       !encoder_context->encoder().GetEncoderInfo().supports_simulcast ||
       active_streams_count == 1;
+  RTC_LOG(LS_INFO) << "[SEA] InitEncode: total_streams_count: "
+                   << total_streams_count_
+                   << ", active_streams_count: " << active_streams_count
+                   << ", separate_encoders_needed: "
+                   << (separate_encoders_needed ? "true" : "false");
   // Singlecast or simulcast with simulcast-capable underlaying encoder.
   if (total_streams_count_ == 1 || !separate_encoders_needed) {
+    RTC_LOG(LS_INFO) << "[SEA] InitEncode: Single-encoder mode";
     int ret = encoder_context->encoder().InitEncode(&codec_, settings);
     if (ret >= 0) {
       stream_contexts_.emplace_back(
@@ -377,7 +384,8 @@
 
     encoder_context->Release();
     if (total_streams_count_ == 1) {
-      // Failed to initialize singlecast encoder.
+      RTC_LOG(LS_ERROR) << "[SEA] InitEncode: failed with error code: "
+                        << WebRtcVideoCodecErrorToString(ret);
       return ret;
     }
   }
@@ -405,10 +413,16 @@
         /*is_lowest_quality_stream=*/stream_idx == lowest_quality_stream_idx,
         /*is_highest_quality_stream=*/stream_idx == highest_quality_stream_idx);
 
+    RTC_LOG(LS_INFO) << "[SEA] Multi-encoder mode: initializing stream: "
+                     << stream_idx << ", active: "
+                     << (codec_.simulcastStream[stream_idx].active ? "true"
+                                                                   : "false");
     int ret = encoder_context->encoder().InitEncode(&stream_codec, settings);
     if (ret < 0) {
       encoder_context.reset();
       Release();
+      RTC_LOG(LS_ERROR) << "[SEA] InitEncode: failed with error code: "
+                        << WebRtcVideoCodecErrorToString(ret);
       return ret;
     }
 
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index ce0a9f1..31de295 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -287,6 +287,8 @@
     "include/video_codec_interface.h",
     "include/video_coding_defines.h",
     "include/video_error_codes.h",
+    "include/video_error_codes_utils.cc",
+    "include/video_error_codes_utils.h",
     "video_coding_defines.cc",
   ]
   deps = [
diff --git a/modules/video_coding/include/video_error_codes.h b/modules/video_coding/include/video_error_codes.h
index 17146ce..d7d54f39 100644
--- a/modules/video_coding/include/video_error_codes.h
+++ b/modules/video_coding/include/video_error_codes.h
@@ -11,10 +11,6 @@
 #ifndef MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_H_
 #define MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_H_
 
-// NOTE: in sync with video_coding_module_defines.h
-
-// Define return values
-
 #define WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT 5
 #define WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME 4
 #define WEBRTC_VIDEO_CODEC_NO_OUTPUT 1
diff --git a/modules/video_coding/include/video_error_codes_utils.cc b/modules/video_coding/include/video_error_codes_utils.cc
new file mode 100644
index 0000000..7e2c08d
--- /dev/null
+++ b/modules/video_coding/include/video_error_codes_utils.cc
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (c) 2024 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "modules/video_coding/include/video_error_codes_utils.h"
+
+#include "modules/video_coding/include/video_error_codes.h"
+
+namespace webrtc {
+
+const char* WebRtcVideoCodecErrorToString(int32_t error_code) {
+  switch (error_code) {
+    case WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT:
+      return "WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT";
+    case WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME:
+      return "WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME";
+    case WEBRTC_VIDEO_CODEC_NO_OUTPUT:
+      return "WEBRTC_VIDEO_CODEC_NO_OUTPUT";
+    case WEBRTC_VIDEO_CODEC_ERROR:
+      return "WEBRTC_VIDEO_CODEC_ERROR";
+    case WEBRTC_VIDEO_CODEC_MEMORY:
+      return "WEBRTC_VIDEO_CODEC_MEMORY";
+    case WEBRTC_VIDEO_CODEC_ERR_PARAMETER:
+      return "WEBRTC_VIDEO_CODEC_ERR_PARAMETER";
+    case WEBRTC_VIDEO_CODEC_TIMEOUT:
+      return "WEBRTC_VIDEO_CODEC_TIMEOUT";
+    case WEBRTC_VIDEO_CODEC_UNINITIALIZED:
+      return "WEBRTC_VIDEO_CODEC_UNINITIALIZED";
+    case WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE:
+      return "WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE";
+    case WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED:
+      return "WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED";
+    case WEBRTC_VIDEO_CODEC_ENCODER_FAILURE:
+      return "WEBRTC_VIDEO_CODEC_ENCODER_FAILURE";
+    default:
+      return "WEBRTC_VIDEO_CODEC_UNKNOWN";
+  }
+}
+
+}  // namespace webrtc
diff --git a/modules/video_coding/include/video_error_codes_utils.h b/modules/video_coding/include/video_error_codes_utils.h
new file mode 100644
index 0000000..ae17e29
--- /dev/null
+++ b/modules/video_coding/include/video_error_codes_utils.h
@@ -0,0 +1,22 @@
+/*
+ *  Copyright (c) 2024 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_UTILS_H_
+#define MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_UTILS_H_
+
+#include <stdint.h>
+
+namespace webrtc {
+
+const char* WebRtcVideoCodecErrorToString(int32_t error_code);
+
+}  // namespace webrtc
+
+#endif  // MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_UTILS_H_
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index ae55bfd..73cd782 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -937,6 +937,8 @@
 void VideoStreamEncoder::ReconfigureEncoder() {
   // Running on the encoder queue.
   RTC_DCHECK(pending_encoder_reconfiguration_);
+  RTC_LOG(LS_INFO) << "[VSE] " << __func__
+                   << " [encoder_config=" << encoder_config_.ToString() << "]";
 
   bool encoder_reset_required = false;
   if (pending_encoder_creation_) {
@@ -1154,37 +1156,38 @@
 
   char log_stream_buf[4 * 1024];
   rtc::SimpleStringBuilder log_stream(log_stream_buf);
-  log_stream << "ReconfigureEncoder:\n";
-  log_stream << "Simulcast streams:\n";
+  log_stream << "ReconfigureEncoder: simulcast streams: ";
   for (size_t i = 0; i < codec.numberOfSimulcastStreams; ++i) {
-    log_stream << i << ": " << codec.simulcastStream[i].width << "x"
-               << codec.simulcastStream[i].height
-               << " min_kbps: " << codec.simulcastStream[i].minBitrate
-               << " target_kbps: " << codec.simulcastStream[i].targetBitrate
-               << " max_kbps: " << codec.simulcastStream[i].maxBitrate
-               << " max_fps: " << codec.simulcastStream[i].maxFramerate
-               << " max_qp: " << codec.simulcastStream[i].qpMax
-               << " num_tl: " << codec.simulcastStream[i].numberOfTemporalLayers
-               << " active: "
-               << (codec.simulcastStream[i].active ? "true" : "false") << "\n";
+    log_stream << "{" << i << ": " << codec.simulcastStream[i].width << "x"
+               << codec.simulcastStream[i].height << " "
+               << ScalabilityModeToString(
+                      codec.simulcastStream[i].GetScalabilityMode())
+               << ", min_kbps: " << codec.simulcastStream[i].minBitrate
+               << ", target_kbps: " << codec.simulcastStream[i].targetBitrate
+               << ", max_kbps: " << codec.simulcastStream[i].maxBitrate
+               << ", max_fps: " << codec.simulcastStream[i].maxFramerate
+               << ", max_qp: " << codec.simulcastStream[i].qpMax << ", num_tl: "
+               << codec.simulcastStream[i].numberOfTemporalLayers
+               << ", active: "
+               << (codec.simulcastStream[i].active ? "true" : "false") << "}";
   }
   if (encoder_config_.codec_type == kVideoCodecVP9 ||
       encoder_config_.codec_type == kVideoCodecAV1) {
-    log_stream << "Spatial layers:\n";
+    log_stream << ", spatial layers: ";
     for (int i = 0; i < GetNumSpatialLayers(codec); ++i) {
-      log_stream << i << ": " << codec.spatialLayers[i].width << "x"
+      log_stream << "{" << i << ": " << codec.spatialLayers[i].width << "x"
                  << codec.spatialLayers[i].height
-                 << " min_kbps: " << codec.spatialLayers[i].minBitrate
-                 << " target_kbps: " << codec.spatialLayers[i].targetBitrate
-                 << " max_kbps: " << codec.spatialLayers[i].maxBitrate
-                 << " max_fps: " << codec.spatialLayers[i].maxFramerate
-                 << " max_qp: " << codec.spatialLayers[i].qpMax
-                 << " num_tl: " << codec.spatialLayers[i].numberOfTemporalLayers
-                 << " active: "
-                 << (codec.spatialLayers[i].active ? "true" : "false") << "\n";
+                 << ", min_kbps: " << codec.spatialLayers[i].minBitrate
+                 << ", target_kbps: " << codec.spatialLayers[i].targetBitrate
+                 << ", max_kbps: " << codec.spatialLayers[i].maxBitrate
+                 << ", max_fps: " << codec.spatialLayers[i].maxFramerate
+                 << ", max_qp: " << codec.spatialLayers[i].qpMax << ", num_tl: "
+                 << codec.spatialLayers[i].numberOfTemporalLayers
+                 << ", active: "
+                 << (codec.spatialLayers[i].active ? "true" : "false") << "}";
     }
   }
-  RTC_LOG(LS_INFO) << log_stream.str();
+  RTC_LOG(LS_INFO) << "[VSE] " << log_stream.str();
 
   codec.startBitrate = std::max(encoder_target_bitrate_bps_.value_or(0) / 1000,
                                 codec.minBitrate);
@@ -1319,7 +1322,7 @@
                         << " max frame rate " << codec.maxFramerate
                         << " max payload size " << max_data_payload_length_;
   } else {
-    RTC_LOG(LS_ERROR) << "Failed to configure encoder.";
+    RTC_LOG(LS_ERROR) << "[VSE] Failed to configure encoder.";
     rate_allocator_ = nullptr;
   }
 
@@ -1917,7 +1920,7 @@
     stream_resource_manager_.ConfigureQualityScaler(info);
     stream_resource_manager_.ConfigureBandwidthQualityScaler(info);
 
-    RTC_LOG(LS_INFO) << "Encoder info changed to " << info.ToString();
+    RTC_LOG(LS_INFO) << "[VSE] Encoder info changed to " << info.ToString();
   }
 
   if (bitrate_adjuster_) {