Commit fe30d575 authored by Hirokazu Honda's avatar Hirokazu Honda Committed by Commit Bot

RtcVideoEncoderFactory: Create VideoEncoder if it's unknown whether the...

RtcVideoEncoderFactory: Create VideoEncoder if it's unknown whether the configured profile is supported

crrev.com/c/2035481 delays filling VEA supported profiles in
GpuVideoAcceleratorFactoriesImpl because it queries GPU process
the supported profiles, instead of referring cached info of
GpuInfo instance.

Therefore, it can be unknown whether the configured profile
on CreateVideoEncoder is supported. We create VideoEncoder
in the case, relying that the software encoder fallback
happens later if no hw encoder is capable of the profile.

Bug: 2035481
Test: webrtc.RTCPeerConnection.* on soraka and kukui
Change-Id: I04334073769914005b6ec1a82170457d340f4a99
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2035486
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Cr-Commit-Position: refs/heads/master@{#742620}
parent c60ad96f
...@@ -21,6 +21,31 @@ namespace blink { ...@@ -21,6 +21,31 @@ namespace blink {
namespace { namespace {
base::Optional<media::VideoCodecProfile> WebRTCFormatToCodecProfile(
const webrtc::SdpVideoFormat& sdp) {
if (sdp.name == "H264") {
#if !defined(OS_ANDROID)
// Enable H264 HW encode for WebRTC when SW fallback is available, which is
// checked by kWebRtcH264WithOpenH264FFmpeg flag. This check should be
// removed when SW implementation is fully enabled.
bool webrtc_h264_sw_enabled = false;
#if BUILDFLAG(RTC_USE_H264) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
webrtc_h264_sw_enabled = base::FeatureList::IsEnabled(
blink::features::kWebRtcH264WithOpenH264FFmpeg);
#endif // BUILDFLAG(RTC_USE_H264) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
if (!webrtc_h264_sw_enabled)
return base::nullopt;
#endif
return media::VideoCodecProfile::H264PROFILE_MIN;
} else if (sdp.name == "VP8") {
return media::VideoCodecProfile::VP8PROFILE_MIN;
} else if (sdp.name == "VP9") {
return media::VideoCodecProfile::VP9PROFILE_MIN;
}
return base::nullopt;
}
// Translate from media::VideoEncodeAccelerator::SupportedProfile to // Translate from media::VideoEncodeAccelerator::SupportedProfile to
// webrtc::SdpVideoFormat, or return nothing if the profile isn't supported. // webrtc::SdpVideoFormat, or return nothing if the profile isn't supported.
base::Optional<webrtc::SdpVideoFormat> VEAToWebRTCFormat( base::Optional<webrtc::SdpVideoFormat> VEAToWebRTCFormat(
...@@ -101,39 +126,63 @@ bool IsSameFormat(const webrtc::SdpVideoFormat& format1, ...@@ -101,39 +126,63 @@ bool IsSameFormat(const webrtc::SdpVideoFormat& format1,
format2.parameters); format2.parameters);
} }
} // anonymous namespace struct SupportedFormats {
bool unknown = true;
std::vector<media::VideoCodecProfile> profiles;
std::vector<webrtc::SdpVideoFormat> sdp_formats;
};
RTCVideoEncoderFactory::RTCVideoEncoderFactory( SupportedFormats GetSupportedFormatsInternal(
media::GpuVideoAcceleratorFactories* gpu_factories) media::GpuVideoAcceleratorFactories* gpu_factories) {
: gpu_factories_(gpu_factories) { SupportedFormats supported_formats;
auto profiles = gpu_factories_->GetVideoEncodeAcceleratorSupportedProfiles(); auto profiles = gpu_factories->GetVideoEncodeAcceleratorSupportedProfiles();
if (!profiles) if (!profiles)
return; return supported_formats;
// |profiles| are either the info at GpuInfo instance or the info got by
// querying GPU process.
supported_formats.unknown = false;
for (const auto& profile : *profiles) { for (const auto& profile : *profiles) {
base::Optional<webrtc::SdpVideoFormat> format = VEAToWebRTCFormat(profile); base::Optional<webrtc::SdpVideoFormat> format = VEAToWebRTCFormat(profile);
if (format) { if (format) {
supported_formats_.push_back(std::move(*format)); supported_formats.profiles.push_back(profile.profile);
profiles_.push_back(profile.profile); supported_formats.sdp_formats.push_back(std::move(*format));
} }
} }
return supported_formats;
} }
} // anonymous namespace
RTCVideoEncoderFactory::RTCVideoEncoderFactory(
media::GpuVideoAcceleratorFactories* gpu_factories)
: gpu_factories_(gpu_factories) {}
RTCVideoEncoderFactory::~RTCVideoEncoderFactory() {} RTCVideoEncoderFactory::~RTCVideoEncoderFactory() {}
std::unique_ptr<webrtc::VideoEncoder> std::unique_ptr<webrtc::VideoEncoder>
RTCVideoEncoderFactory::CreateVideoEncoder( RTCVideoEncoderFactory::CreateVideoEncoder(
const webrtc::SdpVideoFormat& format) { const webrtc::SdpVideoFormat& format) {
for (size_t i = 0; i < supported_formats_.size(); ++i) { std::unique_ptr<webrtc::VideoEncoder> encoder;
if (IsSameFormat(format, supported_formats_[i])) { auto supported_formats = GetSupportedFormatsInternal(gpu_factories_);
return std::make_unique<RTCVideoEncoder>(profiles_[i], gpu_factories_); if (!supported_formats.unknown) {
for (size_t i = 0; i < supported_formats.sdp_formats.size(); ++i) {
if (IsSameFormat(format, supported_formats.sdp_formats[i])) {
encoder = std::make_unique<RTCVideoEncoder>(
supported_formats.profiles[i], gpu_factories_);
}
} }
} else {
auto profile = WebRTCFormatToCodecProfile(format);
if (profile)
encoder = std::make_unique<RTCVideoEncoder>(*profile, gpu_factories_);
} }
return nullptr; return encoder;
} }
std::vector<webrtc::SdpVideoFormat> std::vector<webrtc::SdpVideoFormat>
RTCVideoEncoderFactory::GetSupportedFormats() const { RTCVideoEncoderFactory::GetSupportedFormats() const {
return supported_formats_; return GetSupportedFormatsInternal(gpu_factories_).sdp_formats;
} }
webrtc::VideoEncoderFactory::CodecInfo webrtc::VideoEncoderFactory::CodecInfo
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "media/base/video_codecs.h" #include "media/base/video_codecs.h"
#include "third_party/webrtc/api/video_codecs/video_encoder_factory.h" #include "third_party/webrtc/api/video_codecs/video_encoder_factory.h"
...@@ -36,12 +37,6 @@ class RTCVideoEncoderFactory : public webrtc::VideoEncoderFactory { ...@@ -36,12 +37,6 @@ class RTCVideoEncoderFactory : public webrtc::VideoEncoderFactory {
private: private:
media::GpuVideoAcceleratorFactories* gpu_factories_; media::GpuVideoAcceleratorFactories* gpu_factories_;
// List of supported webrtc::SdpVideoFormat. |profiles_| and
// |supported_formats_| have the same length and the profile for
// |supported_formats_[i]| is |profiles_[i]|.
std::vector<media::VideoCodecProfile> profiles_;
std::vector<webrtc::SdpVideoFormat> supported_formats_;
DISALLOW_COPY_AND_ASSIGN(RTCVideoEncoderFactory); DISALLOW_COPY_AND_ASSIGN(RTCVideoEncoderFactory);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment