blob: 94b63c0d5b47b0ebc62612ca0bbe17af394c23a2 [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/mojo/services/gpu_mojo_media_client.h"
#include "base/win/windows_version.h"
#include "media/base/audio_decoder.h"
#include "media/base/media_switches.h"
#include "media/gpu/ipc/service/vda_video_decoder.h"
#include "media/gpu/windows/d3d11_video_decoder.h"
#include "ui/gl/direct_composition_surface_win.h"
#include "ui/gl/gl_angle_util_win.h"
namespace media {
namespace {
D3D11VideoDecoder::GetD3D11DeviceCB GetD3D11DeviceCallback() {
return base::BindRepeating(
[]() { return gl::QueryD3D11DeviceObjectFromANGLE(); });
}
bool ShouldUseD3D11VideoDecoder(
const gpu::GpuDriverBugWorkarounds& gpu_workarounds) {
if (!base::FeatureList::IsEnabled(kD3D11VideoDecoder))
return false;
if (gpu_workarounds.disable_d3d11_video_decoder)
return false;
if (base::win::GetVersion() == base::win::Version::WIN7)
return false;
return true;
}
class WinPlatformDelegate : public GpuMojoMediaClient::PlatformDelegate {
public:
explicit WinPlatformDelegate(GpuMojoMediaClient* client) : client_(client) {}
~WinPlatformDelegate() override = default;
WinPlatformDelegate(const WinPlatformDelegate&) = delete;
void operator=(const WinPlatformDelegate&) = delete;
// GpuMojoMediaClient::PlatformDelegate implementation.
SupportedVideoDecoderConfigs GetSupportedVideoDecoderConfigsSync() {
SupportedVideoDecoderConfigs supported_configs;
if (ShouldUseD3D11VideoDecoder(client_->gpu_workarounds())) {
return D3D11VideoDecoder::GetSupportedVideoDecoderConfigs(
client_->gpu_preferences(), client_->gpu_workarounds(),
GetD3D11DeviceCallback());
} else if (!client_->gpu_workarounds().disable_dxva_video_decoder) {
return client_->GetVDAVideoDecoderConfigs();
} else {
return {};
}
}
// GpuMojoMediaClient::PlatformDelegate implementation.
std::unique_ptr<VideoDecoder> CreateVideoDecoder(
const VideoDecoderTraits& traits) override {
if (!ShouldUseD3D11VideoDecoder(client_->gpu_workarounds())) {
if (client_->gpu_workarounds().disable_dxva_video_decoder)
return nullptr;
return VdaVideoDecoder::Create(
traits.task_runner, traits.gpu_task_runner, traits.media_log->Clone(),
*traits.target_color_space, client_->gpu_preferences(),
client_->gpu_workarounds(), traits.get_command_buffer_stub_cb);
}
DCHECK(base::FeatureList::IsEnabled(kD3D11VideoDecoder));
return D3D11VideoDecoder::Create(
traits.gpu_task_runner, traits.media_log->Clone(),
client_->gpu_preferences(), client_->gpu_workarounds(),
traits.get_command_buffer_stub_cb, GetD3D11DeviceCallback(),
GetSupportedVideoDecoderConfigsSync(),
gl::DirectCompositionSurfaceWin::IsHDRSupported());
}
void GetSupportedVideoDecoderConfigs(
MojoMediaClient::SupportedVideoDecoderConfigsCallback callback) override {
std::move(callback).Run(GetSupportedVideoDecoderConfigsSync());
}
VideoDecoderType GetDecoderImplementationType() override {
if (!ShouldUseD3D11VideoDecoder(client_->gpu_workarounds()))
return VideoDecoderType::kVda;
return VideoDecoderType::kD3D11;
}
private:
GpuMojoMediaClient* client_;
};
} // namespace
std::unique_ptr<GpuMojoMediaClient::PlatformDelegate>
GpuMojoMediaClient::PlatformDelegate::Create(GpuMojoMediaClient* client) {
return std::make_unique<WinPlatformDelegate>(client);
}
} // namespace media