Adds VideoDecoder::GetDecoderInfo()
This adds a new way to poll decoder metadata.
A default implementation still delegates to the old methods.
Root call site is updates to not use the olds methods.
Follow-ups will dismantle usage of the olds methods in wrappers.
Bug: webrtc:12271
Change-Id: Id0fa6863c96ff9e3b849da452d6540e7c5da4512
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/196520
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32976}
diff --git a/api/video_codecs/video_decoder.cc b/api/video_codecs/video_decoder.cc
index b181323..fee3ec6 100644
--- a/api/video_codecs/video_decoder.cc
+++ b/api/video_codecs/video_decoder.cc
@@ -10,6 +10,8 @@
#include "api/video_codecs/video_decoder.h"
+#include "rtc_base/strings/string_builder.h"
+
namespace webrtc {
int32_t DecodedImageCallback::Decoded(VideoFrame& decodedImage,
@@ -24,6 +26,12 @@
Decoded(decodedImage, decode_time_ms.value_or(-1));
}
+VideoDecoder::DecoderInfo VideoDecoder::GetDecoderInfo() const {
+ DecoderInfo info;
+ info.implementation_name = ImplementationName();
+ return info;
+}
+
bool VideoDecoder::PrefersLateDecoding() const {
return true;
}
@@ -32,4 +40,21 @@
return "unknown";
}
+std::string VideoDecoder::DecoderInfo::ToString() const {
+ char string_buf[2048];
+ rtc::SimpleStringBuilder oss(string_buf);
+
+ oss << "DecoderInfo { "
+ << "prefers_late_decoding = "
+ << "implementation_name = '" << implementation_name << "', "
+ << "is_hardware_accelerated = "
+ << (is_hardware_accelerated ? "true" : "false") << " }";
+ return oss.str();
+}
+
+bool VideoDecoder::DecoderInfo::operator==(const DecoderInfo& rhs) const {
+ return is_hardware_accelerated == rhs.is_hardware_accelerated &&
+ implementation_name == rhs.implementation_name;
+}
+
} // namespace webrtc
diff --git a/api/video_codecs/video_decoder.h b/api/video_codecs/video_decoder.h
index 155e76c..a6af3f2 100644
--- a/api/video_codecs/video_decoder.h
+++ b/api/video_codecs/video_decoder.h
@@ -42,6 +42,18 @@
class RTC_EXPORT VideoDecoder {
public:
+ struct DecoderInfo {
+ // Descriptive name of the decoder implementation.
+ std::string implementation_name;
+
+ // True if the decoder is backed by hardware acceleration.
+ bool is_hardware_accelerated = false;
+
+ std::string ToString() const;
+ bool operator==(const DecoderInfo& rhs) const;
+ bool operator!=(const DecoderInfo& rhs) const { return !(*this == rhs); }
+ };
+
virtual ~VideoDecoder() {}
virtual int32_t InitDecode(const VideoCodec* codec_settings,
@@ -56,12 +68,15 @@
virtual int32_t Release() = 0;
+ virtual DecoderInfo GetDecoderInfo() const;
+
+ // Deprecated, use GetDecoderInfo().prefers_late_decoding instead.
// Returns true if the decoder prefer to decode frames late.
// That is, it can not decode infinite number of frames before the decoded
// frame is consumed.
// TODO(bugs.webrtc.org/12271): Remove when downstream has been updated.
virtual bool PrefersLateDecoding() const;
-
+ // Deprecated, use GetDecoderInfo().implementation_name instead.
virtual const char* ImplementationName() const;
};
diff --git a/api/video_codecs/video_decoder_software_fallback_wrapper.cc b/api/video_codecs/video_decoder_software_fallback_wrapper.cc
index 32941d2..e5743b3 100644
--- a/api/video_codecs/video_decoder_software_fallback_wrapper.cc
+++ b/api/video_codecs/video_decoder_software_fallback_wrapper.cc
@@ -51,6 +51,7 @@
int32_t Release() override;
+ DecoderInfo GetDecoderInfo() const override;
const char* ImplementationName() const override;
private:
@@ -261,10 +262,23 @@
return status;
}
+VideoDecoder::DecoderInfo VideoDecoderSoftwareFallbackWrapper::GetDecoderInfo()
+ const {
+ DecoderInfo info = active_decoder().GetDecoderInfo();
+ if (decoder_type_ == DecoderType::kFallback) {
+ // Cached "A (fallback from B)" string.
+ info.implementation_name = fallback_implementation_name_;
+ }
+ return info;
+}
+
const char* VideoDecoderSoftwareFallbackWrapper::ImplementationName() const {
- return decoder_type_ == DecoderType::kFallback
- ? fallback_implementation_name_.c_str()
- : hw_decoder_->ImplementationName();
+ if (decoder_type_ == DecoderType::kFallback) {
+ // Cached "A (fallback from B)" string.
+ return fallback_implementation_name_.c_str();
+ } else {
+ return hw_decoder_->ImplementationName();
+ }
}
VideoDecoder& VideoDecoderSoftwareFallbackWrapper::active_decoder() const {
diff --git a/modules/video_coding/codecs/av1/libaom_av1_decoder.cc b/modules/video_coding/codecs/av1/libaom_av1_decoder.cc
index bedb519..c187c72 100644
--- a/modules/video_coding/codecs/av1/libaom_av1_decoder.cc
+++ b/modules/video_coding/codecs/av1/libaom_av1_decoder.cc
@@ -53,6 +53,7 @@
int32_t Release() override;
+ DecoderInfo GetDecoderInfo() const override;
const char* ImplementationName() const override;
private:
@@ -182,6 +183,13 @@
return WEBRTC_VIDEO_CODEC_OK;
}
+VideoDecoder::DecoderInfo LibaomAv1Decoder::GetDecoderInfo() const {
+ DecoderInfo info;
+ info.implementation_name = "libaom";
+ info.is_hardware_accelerated = false;
+ return info;
+}
+
const char* LibaomAv1Decoder::ImplementationName() const {
return "libaom";
}
diff --git a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
index f6770d6..7bd1ba3 100644
--- a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
@@ -748,7 +748,7 @@
task_queue->SendTask(
[this, &encoder_name, &decoder_name] {
encoder_name = encoder_->GetEncoderInfo().implementation_name;
- decoder_name = decoders_.at(0)->ImplementationName();
+ decoder_name = decoders_.at(0)->GetDecoderInfo().implementation_name;
},
RTC_FROM_HERE);
RTC_LOG(LS_INFO) << "enc_impl_name: " << encoder_name;
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc
index af48c92..979ded9 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc
@@ -397,6 +397,13 @@
return ret_val;
}
+VideoDecoder::DecoderInfo LibvpxVp8Decoder::GetDecoderInfo() const {
+ DecoderInfo info;
+ info.implementation_name = "libvpx";
+ info.is_hardware_accelerated = false;
+ return info;
+}
+
const char* LibvpxVp8Decoder::ImplementationName() const {
return "libvpx";
}
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h
index cf699f1..8d84b67 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h
@@ -38,6 +38,7 @@
int RegisterDecodeCompleteCallback(DecodedImageCallback* callback) override;
int Release() override;
+ DecoderInfo GetDecoderInfo() const override;
const char* ImplementationName() const override;
struct DeblockParams {
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.cc
index 45e0a0b..0a99c6a 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.cc
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.cc
@@ -391,6 +391,13 @@
return ret_val;
}
+VideoDecoder::DecoderInfo LibvpxVp9Decoder::GetDecoderInfo() const {
+ DecoderInfo info;
+ info.implementation_name = "libvpx";
+ info.is_hardware_accelerated = false;
+ return info;
+}
+
const char* LibvpxVp9Decoder::ImplementationName() const {
return "libvpx";
}
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.h b/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.h
index 59d207a..f26f427 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.h
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.h
@@ -40,6 +40,7 @@
int Release() override;
+ DecoderInfo GetDecoderInfo() const override;
const char* ImplementationName() const override;
private:
diff --git a/modules/video_coding/generic_decoder.cc b/modules/video_coding/generic_decoder.cc
index d237d0c..28c97f0 100644
--- a/modules/video_coding/generic_decoder.cc
+++ b/modules/video_coding/generic_decoder.cc
@@ -238,8 +238,12 @@
_codecType = settings->codecType;
int err = decoder_->InitDecode(settings, numberOfCores);
- implementation_name_ = decoder_->ImplementationName();
- RTC_LOG(LS_INFO) << "Decoder implementation: " << implementation_name_;
+ decoder_info_ = decoder_->GetDecoderInfo();
+ RTC_LOG(LS_INFO) << "Decoder implementation: " << decoder_info_.ToString();
+ if (_callback) {
+ _callback->OnDecoderImplementationName(
+ decoder_info_.implementation_name.c_str());
+ }
return err;
}
@@ -269,13 +273,16 @@
_nextFrameInfoIdx = (_nextFrameInfoIdx + 1) % kDecoderFrameMemoryLength;
int32_t ret = decoder_->Decode(frame.EncodedImage(), frame.MissingFrame(),
frame.RenderTimeMs());
- const char* new_implementation_name = decoder_->ImplementationName();
- if (new_implementation_name != implementation_name_) {
- implementation_name_ = new_implementation_name;
+ VideoDecoder::DecoderInfo decoder_info = decoder_->GetDecoderInfo();
+ if (decoder_info != decoder_info_) {
RTC_LOG(LS_INFO) << "Changed decoder implementation to: "
- << new_implementation_name;
+ << decoder_info.ToString();
+
+ _callback->OnDecoderImplementationName(
+ decoder_info.implementation_name.empty()
+ ? "unknown"
+ : decoder_info.implementation_name.c_str());
}
- _callback->OnDecoderImplementationName(implementation_name_.c_str());
if (ret < WEBRTC_VIDEO_CODEC_OK) {
RTC_LOG(LS_WARNING) << "Failed to decode frame with timestamp "
<< frame.Timestamp() << ", error code: " << ret;
@@ -291,7 +298,12 @@
int32_t VCMGenericDecoder::RegisterDecodeCompleteCallback(
VCMDecodedFrameCallback* callback) {
_callback = callback;
- return decoder_->RegisterDecodeCompleteCallback(callback);
+ int32_t ret = decoder_->RegisterDecodeCompleteCallback(callback);
+ if (callback && !decoder_info_.implementation_name.empty()) {
+ callback->OnDecoderImplementationName(
+ decoder_info_.implementation_name.c_str());
+ }
+ return ret;
}
} // namespace webrtc
diff --git a/modules/video_coding/generic_decoder.h b/modules/video_coding/generic_decoder.h
index bd3620d..9524bab 100644
--- a/modules/video_coding/generic_decoder.h
+++ b/modules/video_coding/generic_decoder.h
@@ -123,7 +123,7 @@
VideoCodecType _codecType;
const bool _isExternal;
VideoContentType _last_keyframe_content_type;
- std::string implementation_name_;
+ VideoDecoder::DecoderInfo decoder_info_;
};
} // namespace webrtc
diff --git a/test/fake_decoder.cc b/test/fake_decoder.cc
index e80c31c..e229bbb 100644
--- a/test/fake_decoder.cc
+++ b/test/fake_decoder.cc
@@ -99,6 +99,12 @@
}
const char* FakeDecoder::kImplementationName = "fake_decoder";
+VideoDecoder::DecoderInfo FakeDecoder::GetDecoderInfo() const {
+ DecoderInfo info;
+ info.implementation_name = kImplementationName;
+ info.is_hardware_accelerated = false;
+ return info;
+}
const char* FakeDecoder::ImplementationName() const {
return kImplementationName;
}
diff --git a/test/fake_decoder.h b/test/fake_decoder.h
index 055c55b..2ac2045 100644
--- a/test/fake_decoder.h
+++ b/test/fake_decoder.h
@@ -41,6 +41,7 @@
int32_t Release() override;
+ DecoderInfo GetDecoderInfo() const override;
const char* ImplementationName() const override;
static const char* kImplementationName;
diff --git a/test/fake_vp8_decoder.cc b/test/fake_vp8_decoder.cc
index faaa554..ec636dc 100644
--- a/test/fake_vp8_decoder.cc
+++ b/test/fake_vp8_decoder.cc
@@ -79,6 +79,13 @@
}
const char* FakeVp8Decoder::kImplementationName = "fake_vp8_decoder";
+VideoDecoder::DecoderInfo FakeVp8Decoder::GetDecoderInfo() const {
+ DecoderInfo info;
+ info.implementation_name = kImplementationName;
+ info.is_hardware_accelerated = false;
+ return info;
+}
+
const char* FakeVp8Decoder::ImplementationName() const {
return kImplementationName;
}
diff --git a/test/fake_vp8_decoder.h b/test/fake_vp8_decoder.h
index 4f0fa3d..2e469a1 100644
--- a/test/fake_vp8_decoder.h
+++ b/test/fake_vp8_decoder.h
@@ -38,8 +38,8 @@
int32_t Release() override;
+ DecoderInfo GetDecoderInfo() const override;
const char* ImplementationName() const override;
-
static const char* kImplementationName;
private:
diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc
index 5cd961e..27b9af5 100644
--- a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc
+++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc
@@ -123,6 +123,12 @@
return result;
}
+VideoDecoder::DecoderInfo QualityAnalyzingVideoDecoder::GetDecoderInfo() const {
+ DecoderInfo info = delegate_->GetDecoderInfo();
+ info.implementation_name = implementation_name_;
+ return info;
+}
+
const char* QualityAnalyzingVideoDecoder::ImplementationName() const {
return implementation_name_.c_str();
}
diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h
index 79ca68d..a26ccbe 100644
--- a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h
+++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h
@@ -69,6 +69,7 @@
int32_t RegisterDecodeCompleteCallback(
DecodedImageCallback* callback) override;
int32_t Release() override;
+ DecoderInfo GetDecoderInfo() const override;
const char* ImplementationName() const override;
private:
diff --git a/test/video_decoder_proxy_factory.h b/test/video_decoder_proxy_factory.h
index 2027f71..303d209 100644
--- a/test/video_decoder_proxy_factory.h
+++ b/test/video_decoder_proxy_factory.h
@@ -61,6 +61,9 @@
return decoder_->RegisterDecodeCompleteCallback(callback);
}
int32_t Release() override { return decoder_->Release(); }
+ DecoderInfo GetDecoderInfo() const override {
+ return decoder_->GetDecoderInfo();
+ }
const char* ImplementationName() const override {
return decoder_->ImplementationName();
}
diff --git a/video/frame_dumping_decoder.cc b/video/frame_dumping_decoder.cc
index c27a653..59202dd 100644
--- a/video/frame_dumping_decoder.cc
+++ b/video/frame_dumping_decoder.cc
@@ -32,6 +32,7 @@
int32_t RegisterDecodeCompleteCallback(
DecodedImageCallback* callback) override;
int32_t Release() override;
+ DecoderInfo GetDecoderInfo() const override;
const char* ImplementationName() const override;
private:
@@ -72,6 +73,10 @@
return decoder_->Release();
}
+VideoDecoder::DecoderInfo FrameDumpingDecoder::GetDecoderInfo() const {
+ return decoder_->GetDecoderInfo();
+}
+
const char* FrameDumpingDecoder::ImplementationName() const {
return decoder_->ImplementationName();
}
diff --git a/video/video_receive_stream.cc b/video/video_receive_stream.cc
index fbe994f..c46868d 100644
--- a/video/video_receive_stream.cc
+++ b/video/video_receive_stream.cc
@@ -167,6 +167,11 @@
int32_t Release() override { return WEBRTC_VIDEO_CODEC_OK; }
+ DecoderInfo GetDecoderInfo() const override {
+ DecoderInfo info;
+ info.implementation_name = "NullVideoDecoder";
+ return info;
+ }
const char* ImplementationName() const override { return "NullVideoDecoder"; }
};
diff --git a/video/video_receive_stream_unittest.cc b/video/video_receive_stream_unittest.cc
index 503c96c..9ac640b 100644
--- a/video/video_receive_stream_unittest.cc
+++ b/video/video_receive_stream_unittest.cc
@@ -72,6 +72,7 @@
(DecodedImageCallback*),
(override));
MOCK_METHOD(int32_t, Release, (), (override));
+ MOCK_METHOD(VideoDecoder::DecoderInfo, GetDetcoderInfo, (), (const override));
const char* ImplementationName() const { return "MockVideoDecoder"; }
};