Commit b2925a91 authored by Sergey Silkin's avatar Sergey Silkin Committed by Commit Bot

Wait for GPU initialization completion

In RTC video decoder factory, wait until initialization of GPU is
finished before querying supported formats and creating a decoder.
Timeout is configurable via RtcDecoderSupportTimeout field trial.
The feature is enabled by default. The default timeout is 10 seconds.

Bug: 1047994
Change-Id: I9d827507664228f903e4ce46e2949785b13192ba
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2411935Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Commit-Queue: Sergey Silkin <ssilkin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811143}
parent a8c2ed38
...@@ -264,10 +264,8 @@ IN_PROC_BROWSER_TEST_F( ...@@ -264,10 +264,8 @@ IN_PROC_BROWSER_TEST_F(
#if defined(OS_ANDROID) && BUILDFLAG(USE_PROPRIETARY_CODECS) #if defined(OS_ANDROID) && BUILDFLAG(USE_PROPRIETARY_CODECS)
// This test is to make sure HW H264 work normally on supported devices, since // This test is to make sure HW H264 work normally on supported devices, since
// there is no SW H264 fallback available on Android. // there is no SW H264 fallback available on Android.
// TODO(crbug.com/1047994): Disabled due to flakiness caused by timing issue
// in blink HW codec factories.
IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
DISABLED_CanSetupH264VideoCallOnSupportedDevice) { CanSetupH264VideoCallOnSupportedDevice) {
MakeTypicalPeerConnectionCall("CanSetupH264VideoCallOnSupportedDevice();"); MakeTypicalPeerConnectionCall("CanSetupH264VideoCallOnSupportedDevice();");
} }
#endif #endif
......
...@@ -12,6 +12,7 @@ include_rules = [ ...@@ -12,6 +12,7 @@ include_rules = [
# Dependencies. # Dependencies.
"+base/strings/string_number_conversions.h", "+base/strings/string_number_conversions.h",
"+base/strings/string_split.h", "+base/strings/string_split.h",
"+base/task/task_traits.h",
"+base/threading/thread_restrictions.h", "+base/threading/thread_restrictions.h",
"+media/base", "+media/base",
"+media/capture/capture_switches.h", "+media/capture/capture_switches.h",
...@@ -30,7 +31,6 @@ include_rules = [ ...@@ -30,7 +31,6 @@ include_rules = [
specific_include_rules = { specific_include_rules = {
".*_test\.cc": [ ".*_test\.cc": [
"+base/task/task_traits.h",
"+base/threading/thread.h", "+base/threading/thread.h",
"+gpu/command_buffer/common/mailbox.h", "+gpu/command_buffer/common/mailbox.h",
"+media/video/mock_gpu_video_accelerator_factories.h", "+media/video/mock_gpu_video_accelerator_factories.h",
......
...@@ -7,8 +7,12 @@ ...@@ -7,8 +7,12 @@
#include <array> #include <array>
#include <memory> #include <memory>
#include "base/feature_list.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/sequenced_task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "media/base/media_util.h" #include "media/base/media_util.h"
#include "media/base/video_codecs.h" #include "media/base/video_codecs.h"
...@@ -27,6 +31,11 @@ const int kDefaultFps = 30; ...@@ -27,6 +31,11 @@ const int kDefaultFps = 30;
// Any reasonable size, will be overridden by the decoder anyway. // Any reasonable size, will be overridden by the decoder anyway.
const gfx::Size kDefaultSize(640, 480); const gfx::Size kDefaultSize(640, 480);
const base::Feature kRtcDecoderSupportTimeout{"RtcDecoderSupportTimeout",
base::FEATURE_ENABLED_BY_DEFAULT};
const uint32_t kDefaultRtcDecoderSupportTimeoutMs = 10000;
struct CodecConfig { struct CodecConfig {
media::VideoCodec codec; media::VideoCodec codec;
media::VideoCodecProfile profile; media::VideoCodecProfile profile;
...@@ -171,16 +180,70 @@ class ScopedVideoDecoder : public webrtc::VideoDecoder { ...@@ -171,16 +180,70 @@ class ScopedVideoDecoder : public webrtc::VideoDecoder {
std::unique_ptr<webrtc::VideoDecoder> decoder_; std::unique_ptr<webrtc::VideoDecoder> decoder_;
}; };
base::Optional<base::TimeDelta> GetRtcDecoderSupportTimeoutMs() {
if (!base::FeatureList::IsEnabled(kRtcDecoderSupportTimeout)) {
return base::nullopt;
}
int timeout_ms = base::GetFieldTrialParamByFeatureAsInt(
kRtcDecoderSupportTimeout, "timeout", kDefaultRtcDecoderSupportTimeoutMs);
return base::TimeDelta::FromMilliseconds(timeout_ms);
}
} // namespace } // namespace
RTCVideoDecoderFactory::RTCVideoDecoderFactory( RTCVideoDecoderFactory::RTCVideoDecoderFactory(
media::GpuVideoAcceleratorFactories* gpu_factories) media::GpuVideoAcceleratorFactories* gpu_factories)
: gpu_factories_(gpu_factories) { : gpu_factories_(gpu_factories),
decoder_support_known_(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED),
decoder_support_timeout_ms_(GetRtcDecoderSupportTimeoutMs()) {
DVLOG(2) << __func__; DVLOG(2) << __func__;
} }
bool RTCVideoDecoderFactory::IsDecoderSupportKnown() const {
if (gpu_factories_->IsDecoderSupportKnown()) {
return true;
}
if (!decoder_support_timeout_ms_) {
return false;
}
// Callback passed to NotifyDecoderSupportKnown is called on caller's
// sequence. To not block the callback while waiting for it, call
// NotifyDecoderSupportKnown on a separate sequence.
scoped_refptr<base::SequencedTaskRunner> task_runner =
base::ThreadPool::CreateSequencedTaskRunner({});
bool is_decoder_support_notification_requested = task_runner->PostTask(
FROM_HERE, base::BindOnce(
[](media::GpuVideoAcceleratorFactories* gpu_factories,
base::WaitableEvent* decoder_support_known) {
gpu_factories->NotifyDecoderSupportKnown(base::BindOnce(
[](base::WaitableEvent* decoder_support_known) {
decoder_support_known->Signal();
},
decoder_support_known));
},
gpu_factories_, &decoder_support_known_));
if (!is_decoder_support_notification_requested) {
DLOG(WARNING) << "Failed to request decoder support notification.";
return false;
}
return decoder_support_known_.TimedWait(*decoder_support_timeout_ms_);
}
std::vector<webrtc::SdpVideoFormat> std::vector<webrtc::SdpVideoFormat>
RTCVideoDecoderFactory::GetSupportedFormats() const { RTCVideoDecoderFactory::GetSupportedFormats() const {
if (!IsDecoderSupportKnown()) {
DLOG(WARNING) << "Decoder support is unknown. Timeout "
<< decoder_support_timeout_ms_.value_or(base::TimeDelta())
.InMilliseconds()
<< "ms. Decoders might not be available.";
}
std::vector<webrtc::SdpVideoFormat> supported_formats; std::vector<webrtc::SdpVideoFormat> supported_formats;
for (auto& codec_config : kCodecConfigs) { for (auto& codec_config : kCodecConfigs) {
media::VideoDecoderConfig config( media::VideoDecoderConfig config(
...@@ -213,6 +276,13 @@ std::unique_ptr<webrtc::VideoDecoder> ...@@ -213,6 +276,13 @@ std::unique_ptr<webrtc::VideoDecoder>
RTCVideoDecoderFactory::CreateVideoDecoder( RTCVideoDecoderFactory::CreateVideoDecoder(
const webrtc::SdpVideoFormat& format) { const webrtc::SdpVideoFormat& format) {
DVLOG(2) << __func__; DVLOG(2) << __func__;
if (!IsDecoderSupportKnown()) {
DLOG(WARNING) << "Decoder support is unknown. Timeout "
<< decoder_support_timeout_ms_.value_or(base::TimeDelta())
.InMilliseconds()
<< "ms. Decoders might not be available.";
}
std::unique_ptr<webrtc::VideoDecoder> decoder = std::unique_ptr<webrtc::VideoDecoder> decoder =
RTCVideoDecoderAdapter::Create(gpu_factories_, format); RTCVideoDecoderAdapter::Create(gpu_factories_, format);
// ScopedVideoDecoder uses the task runner to make sure the decoder is // ScopedVideoDecoder uses the task runner to make sure the decoder is
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_VIDEO_DECODER_FACTORY_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_VIDEO_DECODER_FACTORY_H_
#include "base/macros.h" #include "base/macros.h"
#include "base/optional.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
#include "third_party/webrtc/api/video_codecs/video_decoder_factory.h" #include "third_party/webrtc/api/video_codecs/video_decoder_factory.h"
#include "third_party/webrtc/modules/video_coding/include/video_codec_interface.h" #include "third_party/webrtc/modules/video_coding/include/video_codec_interface.h"
...@@ -34,8 +37,13 @@ class RTCVideoDecoderFactory : public webrtc::VideoDecoderFactory { ...@@ -34,8 +37,13 @@ class RTCVideoDecoderFactory : public webrtc::VideoDecoderFactory {
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override; std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override;
private: private:
bool IsDecoderSupportKnown() const;
media::GpuVideoAcceleratorFactories* gpu_factories_; media::GpuVideoAcceleratorFactories* gpu_factories_;
mutable base::WaitableEvent decoder_support_known_;
const base::Optional<base::TimeDelta> decoder_support_timeout_ms_;
DISALLOW_COPY_AND_ASSIGN(RTCVideoDecoderFactory); DISALLOW_COPY_AND_ASSIGN(RTCVideoDecoderFactory);
}; };
......
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