diff --git a/api/video_codecs/BUILD.gn b/api/video_codecs/BUILD.gn index 5475af97e5..cb5ede02f6 100644 --- a/api/video_codecs/BUILD.gn +++ b/api/video_codecs/BUILD.gn @@ -143,6 +143,7 @@ rtc_library("rtc_software_fallback_wrappers") { "../../rtc_base:rtc_base_approved", "../../rtc_base/system:rtc_export", "../../system_wrappers:field_trial", + "../../system_wrappers:metrics", "../video:encoded_image", "../video:video_bitrate_allocation", "../video:video_frame", diff --git a/api/video_codecs/video_decoder_software_fallback_wrapper.cc b/api/video_codecs/video_decoder_software_fallback_wrapper.cc index 3987db6154..f78d9b885f 100644 --- a/api/video_codecs/video_decoder_software_fallback_wrapper.cc +++ b/api/video_codecs/video_decoder_software_fallback_wrapper.cc @@ -24,6 +24,7 @@ #include "rtc_base/logging.h" #include "rtc_base/trace_event.h" #include "system_wrappers/include/field_trial.h" +#include "system_wrappers/include/metrics.h" namespace webrtc { @@ -53,6 +54,8 @@ class VideoDecoderSoftwareFallbackWrapper final : public VideoDecoder { private: bool InitFallbackDecoder(); + void UpdateFallbackDecoderHistograms(); + int32_t InitHwDecoder(); VideoDecoder& active_decoder() const; @@ -70,6 +73,7 @@ class VideoDecoderSoftwareFallbackWrapper final : public VideoDecoder { const std::unique_ptr fallback_decoder_; const std::string fallback_implementation_name_; DecodedImageCallback* callback_; + int32_t hw_decoded_frames_since_last_fallback_; }; VideoDecoderSoftwareFallbackWrapper::VideoDecoderSoftwareFallbackWrapper( @@ -81,7 +85,8 @@ VideoDecoderSoftwareFallbackWrapper::VideoDecoderSoftwareFallbackWrapper( fallback_implementation_name_( std::string(fallback_decoder_->ImplementationName()) + " (fallback from: " + hw_decoder_->ImplementationName() + ")"), - callback_(nullptr) {} + callback_(nullptr), + hw_decoded_frames_since_last_fallback_(0) {} VideoDecoderSoftwareFallbackWrapper::~VideoDecoderSoftwareFallbackWrapper() = default; @@ -134,6 +139,8 @@ bool VideoDecoderSoftwareFallbackWrapper::InitFallbackDecoder() { return false; } + UpdateFallbackDecoderHistograms(); + if (decoder_type_ == DecoderType::kHardware) { hw_decoder_->Release(); } @@ -144,6 +151,39 @@ bool VideoDecoderSoftwareFallbackWrapper::InitFallbackDecoder() { return true; } +void VideoDecoderSoftwareFallbackWrapper::UpdateFallbackDecoderHistograms() { + const std::string kFallbackHistogramsUmaPrefix = + "WebRTC.Video.HardwareDecodedFramesBetweenSoftwareFallbacks."; + // Each histogram needs its own code path for this to work otherwise the + // histogram names will be mixed up by the optimization that takes place. + switch (codec_settings_.codecType) { + case kVideoCodecGeneric: + RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "Generic", + hw_decoded_frames_since_last_fallback_); + break; + case kVideoCodecVP8: + RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "Vp8", + hw_decoded_frames_since_last_fallback_); + break; + case kVideoCodecVP9: + RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "Vp9", + hw_decoded_frames_since_last_fallback_); + break; + case kVideoCodecAV1: + RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "Av1", + hw_decoded_frames_since_last_fallback_); + break; + case kVideoCodecH264: + RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "H264", + hw_decoded_frames_since_last_fallback_); + break; + case kVideoCodecMultiplex: + RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "Multiplex", + hw_decoded_frames_since_last_fallback_); + break; + } +} + int32_t VideoDecoderSoftwareFallbackWrapper::Decode( const EncodedImage& input_image, bool missing_frames, @@ -156,6 +196,9 @@ int32_t VideoDecoderSoftwareFallbackWrapper::Decode( int32_t ret = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; ret = hw_decoder_->Decode(input_image, missing_frames, render_time_ms); if (ret != WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE) { + if (ret == WEBRTC_VIDEO_CODEC_OK) { + ++hw_decoded_frames_since_last_fallback_; + } return ret; }