Add powerEfficientDecoder and powerEfficientEncoder stats

The spec for these are at https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-powerefficientdecoder and https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-powerefficientdecoder

These stats are based on the is_hardware_accelerated boolean in both the
DecoderInfo and EncoderInfo structs.

Bug: webrtc:14483
Change-Id: I4610da3c6ae977f5853a3b3424d91d864fe72592
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/274409
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Evan Shrubsole <eshr@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38441}
This commit is contained in:
Evan Shrubsole
2022-10-14 14:38:31 +00:00
committed by WebRTC LUCI CQ
parent 6253a4ff9a
commit 09da10e24f
27 changed files with 111 additions and 51 deletions

View File

@ -20,6 +20,7 @@
#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"
#include "modules/video_coding/include/video_error_codes.h"
#include "rtc_base/checks.h"
@ -202,9 +203,9 @@ void VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage,
frame_info->content_type);
}
void VCMDecodedFrameCallback::OnDecoderImplementationName(
const char* implementation_name) {
_receiveCallback->OnDecoderImplementationName(implementation_name);
void VCMDecodedFrameCallback::OnDecoderInfoChanged(
const VideoDecoder::DecoderInfo& decoder_info) {
_receiveCallback->OnDecoderInfoChanged(decoder_info);
}
void VCMDecodedFrameCallback::Map(FrameInfo frameInfo) {
@ -254,8 +255,7 @@ bool VCMGenericDecoder::Configure(const VideoDecoder::Settings& settings) {
decoder_info_ = decoder_->GetDecoderInfo();
RTC_LOG(LS_INFO) << "Decoder implementation: " << decoder_info_.ToString();
if (_callback) {
_callback->OnDecoderImplementationName(
decoder_info_.implementation_name.c_str());
_callback->OnDecoderInfoChanged(decoder_info_);
}
return ok;
}
@ -293,10 +293,10 @@ int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame, Timestamp now) {
RTC_LOG(LS_INFO) << "Changed decoder implementation to: "
<< decoder_info.ToString();
decoder_info_ = decoder_info;
_callback->OnDecoderImplementationName(
decoder_info.implementation_name.empty()
? "unknown"
: decoder_info.implementation_name.c_str());
if (decoder_info.implementation_name.empty()) {
decoder_info.implementation_name = "unknown";
}
_callback->OnDecoderInfoChanged(std::move(decoder_info));
}
if (ret < WEBRTC_VIDEO_CODEC_OK) {
RTC_LOG(LS_WARNING) << "Failed to decode frame with timestamp "
@ -314,8 +314,7 @@ int32_t VCMGenericDecoder::RegisterDecodeCompleteCallback(
_callback = callback;
int32_t ret = decoder_->RegisterDecodeCompleteCallback(callback);
if (callback && !decoder_info_.implementation_name.empty()) {
callback->OnDecoderImplementationName(
decoder_info_.implementation_name.c_str());
callback->OnDecoderInfoChanged(decoder_info_);
}
return ret;
}

View File

@ -63,7 +63,7 @@ class VCMDecodedFrameCallback : public DecodedImageCallback {
absl::optional<int32_t> decode_time_ms,
absl::optional<uint8_t> qp) override;
void OnDecoderImplementationName(const char* implementation_name);
void OnDecoderInfoChanged(const VideoDecoder::DecoderInfo& decoder_info);
void Map(FrameInfo frameInfo);
void ClearTimestampMap();

View File

@ -18,6 +18,7 @@
#include "api/video/video_content_type.h"
#include "api/video/video_frame.h"
#include "api/video/video_timing.h"
#include "api/video_codecs/video_decoder.h"
namespace webrtc {
@ -58,7 +59,8 @@ class VCMReceiveCallback {
// Called when the current receive codec changes.
virtual void OnIncomingPayloadType(int payload_type);
virtual void OnDecoderImplementationName(const char* implementation_name);
virtual void OnDecoderInfoChanged(
const VideoDecoder::DecoderInfo& decoder_info);
protected:
virtual ~VCMReceiveCallback() {}

View File

@ -14,7 +14,7 @@ namespace webrtc {
void VCMReceiveCallback::OnDroppedFrames(uint32_t frames_dropped) {}
void VCMReceiveCallback::OnIncomingPayloadType(int payload_type) {}
void VCMReceiveCallback::OnDecoderImplementationName(
const char* implementation_name) {}
void VCMReceiveCallback::OnDecoderInfoChanged(
const VideoDecoder::DecoderInfo&) {}
} // namespace webrtc

View File

@ -41,7 +41,10 @@ class MockVCMReceiveCallback : public VCMReceiveCallback {
(VideoFrame&, absl::optional<uint8_t>, TimeDelta, VideoContentType),
(override));
MOCK_METHOD(void, OnIncomingPayloadType, (int), (override));
MOCK_METHOD(void, OnDecoderImplementationName, (const char*), (override));
MOCK_METHOD(void,
OnDecoderInfoChanged,
(const VideoDecoder::DecoderInfo&),
(override));
};
class TestEncodedFrame : public EncodedFrame {
@ -126,7 +129,7 @@ TEST_F(VideoReceiver2Test, RegisterReceiveCodecs) {
EXPECT_TRUE(receiver_.IsExternalDecoderRegistered(kPayloadType));
EXPECT_CALL(receive_callback_, OnIncomingPayloadType(kPayloadType));
EXPECT_CALL(receive_callback_, OnDecoderImplementationName);
EXPECT_CALL(receive_callback_, OnDecoderInfoChanged);
// Call `Decode`. This triggers the above call expectations.
EXPECT_EQ(receiver_.Decode(&frame), VCM_OK);

View File

@ -44,7 +44,10 @@ class MockVCMReceiveCallback : public VCMReceiveCallback {
(VideoFrame&, absl::optional<uint8_t>, TimeDelta, VideoContentType),
(override));
MOCK_METHOD(void, OnIncomingPayloadType, (int), (override));
MOCK_METHOD(void, OnDecoderImplementationName, (const char*), (override));
MOCK_METHOD(void,
OnDecoderInfoChanged,
(const VideoDecoder::DecoderInfo&),
(override));
};
class TestVideoReceiver : public ::testing::Test {
@ -74,8 +77,7 @@ class TestVideoReceiver : public ::testing::Test {
// Since we call Decode, we need to provide a valid receive callback.
// However, for the purposes of these tests, we ignore the callbacks.
EXPECT_CALL(receive_callback_, OnIncomingPayloadType(_)).Times(AnyNumber());
EXPECT_CALL(receive_callback_, OnDecoderImplementationName(_))
.Times(AnyNumber());
EXPECT_CALL(receive_callback_, OnDecoderInfoChanged).Times(AnyNumber());
receiver_.RegisterReceiveCallback(&receive_callback_);
}