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}
This commit is contained in:
parent
a0bb2ef2dc
commit
c12f625938
@ -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 @@ void DecodedImageCallback::Decoded(VideoFrame& decodedImage,
|
||||
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 @@ const char* VideoDecoder::ImplementationName() const {
|
||||
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
|
||||
|
||||
@ -42,6 +42,18 @@ class RTC_EXPORT DecodedImageCallback {
|
||||
|
||||
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 @@ class RTC_EXPORT VideoDecoder {
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@ -51,6 +51,7 @@ class VideoDecoderSoftwareFallbackWrapper final : public VideoDecoder {
|
||||
|
||||
int32_t Release() override;
|
||||
|
||||
DecoderInfo GetDecoderInfo() const override;
|
||||
const char* ImplementationName() const override;
|
||||
|
||||
private:
|
||||
@ -261,10 +262,23 @@ int32_t VideoDecoderSoftwareFallbackWrapper::Release() {
|
||||
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 {
|
||||
|
||||
@ -53,6 +53,7 @@ class LibaomAv1Decoder final : public VideoDecoder {
|
||||
|
||||
int32_t Release() override;
|
||||
|
||||
DecoderInfo GetDecoderInfo() const override;
|
||||
const char* ImplementationName() const override;
|
||||
|
||||
private:
|
||||
@ -182,6 +183,13 @@ int32_t LibaomAv1Decoder::Release() {
|
||||
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";
|
||||
}
|
||||
|
||||
@ -748,7 +748,7 @@ void VideoCodecTestFixtureImpl::PrintSettings(
|
||||
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;
|
||||
|
||||
@ -397,6 +397,13 @@ int LibvpxVp8Decoder::Release() {
|
||||
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";
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@ class LibvpxVp8Decoder : public VideoDecoder {
|
||||
int RegisterDecodeCompleteCallback(DecodedImageCallback* callback) override;
|
||||
int Release() override;
|
||||
|
||||
DecoderInfo GetDecoderInfo() const override;
|
||||
const char* ImplementationName() const override;
|
||||
|
||||
struct DeblockParams {
|
||||
|
||||
@ -391,6 +391,13 @@ int LibvpxVp9Decoder::Release() {
|
||||
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";
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ class LibvpxVp9Decoder : public VP9Decoder {
|
||||
|
||||
int Release() override;
|
||||
|
||||
DecoderInfo GetDecoderInfo() const override;
|
||||
const char* ImplementationName() const override;
|
||||
|
||||
private:
|
||||
|
||||
@ -238,8 +238,12 @@ int32_t VCMGenericDecoder::InitDecode(const VideoCodec* settings,
|
||||
_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 @@ int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame, Timestamp now) {
|
||||
_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::Decode(const VCMEncodedFrame& frame, Timestamp now) {
|
||||
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
|
||||
|
||||
@ -123,7 +123,7 @@ class VCMGenericDecoder {
|
||||
VideoCodecType _codecType;
|
||||
const bool _isExternal;
|
||||
VideoContentType _last_keyframe_content_type;
|
||||
std::string implementation_name_;
|
||||
VideoDecoder::DecoderInfo decoder_info_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -99,6 +99,12 @@ int32_t FakeDecoder::Release() {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ class FakeDecoder : public VideoDecoder {
|
||||
|
||||
int32_t Release() override;
|
||||
|
||||
DecoderInfo GetDecoderInfo() const override;
|
||||
const char* ImplementationName() const override;
|
||||
|
||||
static const char* kImplementationName;
|
||||
|
||||
@ -79,6 +79,13 @@ int32_t FakeVp8Decoder::Release() {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -38,8 +38,8 @@ class FakeVp8Decoder : public VideoDecoder {
|
||||
|
||||
int32_t Release() override;
|
||||
|
||||
DecoderInfo GetDecoderInfo() const override;
|
||||
const char* ImplementationName() const override;
|
||||
|
||||
static const char* kImplementationName;
|
||||
|
||||
private:
|
||||
|
||||
@ -123,6 +123,12 @@ int32_t QualityAnalyzingVideoDecoder::Release() {
|
||||
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();
|
||||
}
|
||||
|
||||
@ -69,6 +69,7 @@ class QualityAnalyzingVideoDecoder : public VideoDecoder {
|
||||
int32_t RegisterDecodeCompleteCallback(
|
||||
DecodedImageCallback* callback) override;
|
||||
int32_t Release() override;
|
||||
DecoderInfo GetDecoderInfo() const override;
|
||||
const char* ImplementationName() const override;
|
||||
|
||||
private:
|
||||
|
||||
@ -61,6 +61,9 @@ class VideoDecoderProxyFactory final : public VideoDecoderFactory {
|
||||
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();
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ class FrameDumpingDecoder : public VideoDecoder {
|
||||
int32_t RegisterDecodeCompleteCallback(
|
||||
DecodedImageCallback* callback) override;
|
||||
int32_t Release() override;
|
||||
DecoderInfo GetDecoderInfo() const override;
|
||||
const char* ImplementationName() const override;
|
||||
|
||||
private:
|
||||
@ -72,6 +73,10 @@ int32_t FrameDumpingDecoder::Release() {
|
||||
return decoder_->Release();
|
||||
}
|
||||
|
||||
VideoDecoder::DecoderInfo FrameDumpingDecoder::GetDecoderInfo() const {
|
||||
return decoder_->GetDecoderInfo();
|
||||
}
|
||||
|
||||
const char* FrameDumpingDecoder::ImplementationName() const {
|
||||
return decoder_->ImplementationName();
|
||||
}
|
||||
|
||||
@ -167,6 +167,11 @@ class NullVideoDecoder : public webrtc::VideoDecoder {
|
||||
|
||||
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"; }
|
||||
};
|
||||
|
||||
|
||||
@ -72,6 +72,7 @@ class MockVideoDecoder : public VideoDecoder {
|
||||
(DecodedImageCallback*),
|
||||
(override));
|
||||
MOCK_METHOD(int32_t, Release, (), (override));
|
||||
MOCK_METHOD(VideoDecoder::DecoderInfo, GetDetcoderInfo, (), (const override));
|
||||
const char* ImplementationName() const { return "MockVideoDecoder"; }
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user