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 {
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
// webrtc::SdpVideoFormat, or return nothing if the profile isn't supported.
base::Optional<webrtc::SdpVideoFormat> VEAToWebRTCFormat(
......@@ -101,39 +126,63 @@ bool IsSameFormat(const webrtc::SdpVideoFormat& format1,
format2.parameters);
}
} // anonymous namespace
struct SupportedFormats {
bool unknown = true;
std::vector<media::VideoCodecProfile> profiles;
std::vector<webrtc::SdpVideoFormat> sdp_formats;
};
RTCVideoEncoderFactory::RTCVideoEncoderFactory(
media::GpuVideoAcceleratorFactories* gpu_factories)
: gpu_factories_(gpu_factories) {
auto profiles = gpu_factories_->GetVideoEncodeAcceleratorSupportedProfiles();
SupportedFormats GetSupportedFormatsInternal(
media::GpuVideoAcceleratorFactories* gpu_factories) {
SupportedFormats supported_formats;
auto profiles = gpu_factories->GetVideoEncodeAcceleratorSupportedProfiles();
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) {
base::Optional<webrtc::SdpVideoFormat> format = VEAToWebRTCFormat(profile);
if (format) {
supported_formats_.push_back(std::move(*format));
profiles_.push_back(profile.profile);
supported_formats.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() {}
std::unique_ptr<webrtc::VideoEncoder>
RTCVideoEncoderFactory::CreateVideoEncoder(
const webrtc::SdpVideoFormat& format) {
for (size_t i = 0; i < supported_formats_.size(); ++i) {
if (IsSameFormat(format, supported_formats_[i])) {
return std::make_unique<RTCVideoEncoder>(profiles_[i], gpu_factories_);
std::unique_ptr<webrtc::VideoEncoder> encoder;
auto supported_formats = GetSupportedFormatsInternal(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>
RTCVideoEncoderFactory::GetSupportedFormats() const {
return supported_formats_;
return GetSupportedFormatsInternal(gpu_factories_).sdp_formats;
}
webrtc::VideoEncoderFactory::CodecInfo
......
......@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "media/base/video_codecs.h"
#include "third_party/webrtc/api/video_codecs/video_encoder_factory.h"
......@@ -36,12 +37,6 @@ class RTCVideoEncoderFactory : public webrtc::VideoEncoderFactory {
private:
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);
};
......
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