Commit b1603f08 authored by liberato@chromium.org's avatar liberato@chromium.org Committed by Commit Bot

Select video decoder implementations for MojoVideoDecoder

This CL enables the following:

 - SupportedVideoDecoderConfigs are now returned from the GPU
   process as a map [video decoder implementation] => vector of
   SupportedVideoDecoderConfig for that implementation.
 - GpuVideoAcceleratorFactories::IsDecoderConfigSupported takes the
   implementation enum value as an additional argument, and checks
   only against that implementation's supported configs.
 - MojoVideoDecoder accepts an implementation enum during
   construction, which will be provided to the service during
   decoder initialization.
 - GpuMojoMediaClient uses the kAlternate implementation enum value
   to select D3D11VideoDecoder on Windows, if the experiment is
   currently enabled.  It no longer uses FallbackVideoDecoder.
 - MojoDecoderFactory adds a kAlternate decoder, in addition to the
   kDefault decoder, on Windows if the experiment is enabled.
 - RTCVideoDecoderAdapter always selects the default video decoder
   implementation.  This causes RTC on windows to use only DXVA,
   rather than D3D11VideoDecoder.  This will be addressed as follow-
   up work, though likely not immediately.

The main reason for this is that it lets the renderer's decoder
selection algorithm see two MojoVideoDecoder instances: one for DXVA
and one for D3D11VideoDecoder.  This lets decoder selection and
fallback happen normally for them, rather than having the fallback
happen in the GPU process via FallbackVideoDecoder.

Bug: 954422
Change-Id: If6f056723c11ff50327623ac8d554d9f5da9f499
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1534984Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarXing Liu <xingliu@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Commit-Queue: Frank Liberato <liberato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#652479}
parent d88299f9
...@@ -218,8 +218,8 @@ void DownloadMediaParser::DecodeVideoFrame() { ...@@ -218,8 +218,8 @@ void DownloadMediaParser::DecodeVideoFrame() {
DCHECK(gpu_factories_); DCHECK(gpu_factories_);
auto mojo_decoder = std::make_unique<media::MojoVideoDecoder>( auto mojo_decoder = std::make_unique<media::MojoVideoDecoder>(
base::ThreadTaskRunnerHandle::Get(), gpu_factories_.get(), this, base::ThreadTaskRunnerHandle::Get(), gpu_factories_.get(), this,
std::move(video_decoder_ptr), base::BindRepeating(&OnRequestOverlayInfo), std::move(video_decoder_ptr), media::VideoDecoderImplementation::kDefault,
gfx::ColorSpace()); base::BindRepeating(&OnRequestOverlayInfo), gfx::ColorSpace());
decoder_ = std::make_unique<media::VideoThumbnailDecoder>( decoder_ = std::make_unique<media::VideoThumbnailDecoder>(
std::move(mojo_decoder), config_, std::move(mojo_decoder), config_,
......
...@@ -98,6 +98,7 @@ int32_t BrowserGpuVideoAcceleratorFactories::GetCommandBufferRouteId() { ...@@ -98,6 +98,7 @@ int32_t BrowserGpuVideoAcceleratorFactories::GetCommandBufferRouteId() {
} }
bool BrowserGpuVideoAcceleratorFactories::IsDecoderConfigSupported( bool BrowserGpuVideoAcceleratorFactories::IsDecoderConfigSupported(
media::VideoDecoderImplementation implementation,
const media::VideoDecoderConfig& config) { const media::VideoDecoderConfig& config) {
// TODO(sandersd): Add a cache here too? // TODO(sandersd): Add a cache here too?
return true; return true;
...@@ -106,6 +107,7 @@ bool BrowserGpuVideoAcceleratorFactories::IsDecoderConfigSupported( ...@@ -106,6 +107,7 @@ bool BrowserGpuVideoAcceleratorFactories::IsDecoderConfigSupported(
std::unique_ptr<media::VideoDecoder> std::unique_ptr<media::VideoDecoder>
BrowserGpuVideoAcceleratorFactories::CreateVideoDecoder( BrowserGpuVideoAcceleratorFactories::CreateVideoDecoder(
media::MediaLog* media_log, media::MediaLog* media_log,
media::VideoDecoderImplementation implementation,
const media::RequestOverlayInfoCB& request_overlay_info_cb) { const media::RequestOverlayInfoCB& request_overlay_info_cb) {
return nullptr; return nullptr;
} }
......
...@@ -25,9 +25,11 @@ class BrowserGpuVideoAcceleratorFactories ...@@ -25,9 +25,11 @@ class BrowserGpuVideoAcceleratorFactories
base::UnguessableToken GetChannelToken() override; base::UnguessableToken GetChannelToken() override;
int32_t GetCommandBufferRouteId() override; int32_t GetCommandBufferRouteId() override;
bool IsDecoderConfigSupported( bool IsDecoderConfigSupported(
media::VideoDecoderImplementation implementation,
const media::VideoDecoderConfig& config) override; const media::VideoDecoderConfig& config) override;
std::unique_ptr<media::VideoDecoder> CreateVideoDecoder( std::unique_ptr<media::VideoDecoder> CreateVideoDecoder(
media::MediaLog* media_log, media::MediaLog* media_log,
media::VideoDecoderImplementation implementation,
const media::RequestOverlayInfoCB& request_overlay_info_cb) override; const media::RequestOverlayInfoCB& request_overlay_info_cb) override;
std::unique_ptr<media::VideoDecodeAccelerator> CreateVideoDecodeAccelerator() std::unique_ptr<media::VideoDecodeAccelerator> CreateVideoDecodeAccelerator()
override; override;
......
...@@ -127,6 +127,11 @@ void GpuVideoAcceleratorFactoriesImpl::BindOnTaskRunner( ...@@ -127,6 +127,11 @@ void GpuVideoAcceleratorFactoriesImpl::BindOnTaskRunner(
#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) #if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
if (base::FeatureList::IsEnabled(media::kMojoVideoDecoder)) { if (base::FeatureList::IsEnabled(media::kMojoVideoDecoder)) {
// Note: This is a bit of a hack, since we don't specify the implementation
// before asking for the map of supported configs. We do this because it
// (a) saves an ipc call, and (b) makes the return of those configs atomic.
// Otherwise, we might have received configs for kDefault but not yet
// kAlternate, for example.
interface_factory_->CreateVideoDecoder(mojo::MakeRequest(&video_decoder_)); interface_factory_->CreateVideoDecoder(mojo::MakeRequest(&video_decoder_));
video_decoder_->GetSupportedConfigs(base::BindOnce( video_decoder_->GetSupportedConfigs(base::BindOnce(
&GpuVideoAcceleratorFactoriesImpl::OnSupportedDecoderConfigs, &GpuVideoAcceleratorFactoriesImpl::OnSupportedDecoderConfigs,
...@@ -136,7 +141,7 @@ void GpuVideoAcceleratorFactoriesImpl::BindOnTaskRunner( ...@@ -136,7 +141,7 @@ void GpuVideoAcceleratorFactoriesImpl::BindOnTaskRunner(
} }
void GpuVideoAcceleratorFactoriesImpl::OnSupportedDecoderConfigs( void GpuVideoAcceleratorFactoriesImpl::OnSupportedDecoderConfigs(
const std::vector<media::SupportedVideoDecoderConfig>& supported_configs) { const media::SupportedVideoDecoderConfigMap& supported_configs) {
base::AutoLock lock(supported_decoder_configs_lock_); base::AutoLock lock(supported_decoder_configs_lock_);
supported_decoder_configs_ = supported_configs; supported_decoder_configs_ = supported_configs;
video_decoder_.reset(); video_decoder_.reset();
...@@ -190,6 +195,7 @@ int32_t GpuVideoAcceleratorFactoriesImpl::GetCommandBufferRouteId() { ...@@ -190,6 +195,7 @@ int32_t GpuVideoAcceleratorFactoriesImpl::GetCommandBufferRouteId() {
} }
bool GpuVideoAcceleratorFactoriesImpl::IsDecoderConfigSupported( bool GpuVideoAcceleratorFactoriesImpl::IsDecoderConfigSupported(
media::VideoDecoderImplementation implementation,
const media::VideoDecoderConfig& config) { const media::VideoDecoderConfig& config) {
base::AutoLock lock(supported_decoder_configs_lock_); base::AutoLock lock(supported_decoder_configs_lock_);
...@@ -199,7 +205,14 @@ bool GpuVideoAcceleratorFactoriesImpl::IsDecoderConfigSupported( ...@@ -199,7 +205,14 @@ bool GpuVideoAcceleratorFactoriesImpl::IsDecoderConfigSupported(
if (!supported_decoder_configs_) if (!supported_decoder_configs_)
return true; return true;
for (const auto& supported : *supported_decoder_configs_) { auto iter = supported_decoder_configs_->find(implementation);
// If the decoder implementation wasn't listed, then fail. This means that
// there is no such decoder implementation.
if (iter == supported_decoder_configs_->end())
return false;
// Iterate over the supported configs for |impl|.
for (const auto& supported : iter->second) {
if (supported.Matches(config)) if (supported.Matches(config))
return true; return true;
} }
...@@ -209,6 +222,7 @@ bool GpuVideoAcceleratorFactoriesImpl::IsDecoderConfigSupported( ...@@ -209,6 +222,7 @@ bool GpuVideoAcceleratorFactoriesImpl::IsDecoderConfigSupported(
std::unique_ptr<media::VideoDecoder> std::unique_ptr<media::VideoDecoder>
GpuVideoAcceleratorFactoriesImpl::CreateVideoDecoder( GpuVideoAcceleratorFactoriesImpl::CreateVideoDecoder(
media::MediaLog* media_log, media::MediaLog* media_log,
media::VideoDecoderImplementation implementation,
const media::RequestOverlayInfoCB& request_overlay_info_cb) { const media::RequestOverlayInfoCB& request_overlay_info_cb) {
DCHECK(video_accelerator_enabled_); DCHECK(video_accelerator_enabled_);
DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(task_runner_->BelongsToCurrentThread());
...@@ -221,11 +235,15 @@ GpuVideoAcceleratorFactoriesImpl::CreateVideoDecoder( ...@@ -221,11 +235,15 @@ GpuVideoAcceleratorFactoriesImpl::CreateVideoDecoder(
media::mojom::VideoDecoderPtr video_decoder; media::mojom::VideoDecoderPtr video_decoder;
interface_factory_->CreateVideoDecoder(mojo::MakeRequest(&video_decoder)); interface_factory_->CreateVideoDecoder(mojo::MakeRequest(&video_decoder));
return std::make_unique<media::MojoVideoDecoder>( return std::make_unique<media::MojoVideoDecoder>(
task_runner_, this, media_log, std::move(video_decoder), task_runner_, this, media_log, std::move(video_decoder), implementation,
request_overlay_info_cb, rendering_color_space_); request_overlay_info_cb, rendering_color_space_);
} }
#endif // BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) #endif // BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
// GpuVideoDecoder is our default implementation without MVD.
if (implementation != media::VideoDecoderImplementation::kDefault)
return nullptr;
return std::make_unique<media::GpuVideoDecoder>( return std::make_unique<media::GpuVideoDecoder>(
this, request_overlay_info_cb, rendering_color_space_, media_log); this, request_overlay_info_cb, rendering_color_space_, media_log);
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "media/mojo/interfaces/video_decoder.mojom.h" #include "media/mojo/interfaces/video_decoder.mojom.h"
#include "media/mojo/interfaces/video_encode_accelerator.mojom.h" #include "media/mojo/interfaces/video_encode_accelerator.mojom.h"
#include "media/video/gpu_video_accelerator_factories.h" #include "media/video/gpu_video_accelerator_factories.h"
#include "media/video/supported_video_decoder_config.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
namespace gpu { namespace gpu {
...@@ -71,8 +72,10 @@ class CONTENT_EXPORT GpuVideoAcceleratorFactoriesImpl ...@@ -71,8 +72,10 @@ class CONTENT_EXPORT GpuVideoAcceleratorFactoriesImpl
int32_t GetCommandBufferRouteId() override; int32_t GetCommandBufferRouteId() override;
std::unique_ptr<media::VideoDecoder> CreateVideoDecoder( std::unique_ptr<media::VideoDecoder> CreateVideoDecoder(
media::MediaLog* media_log, media::MediaLog* media_log,
media::VideoDecoderImplementation implementation,
const media::RequestOverlayInfoCB& request_overlay_info_cb) override; const media::RequestOverlayInfoCB& request_overlay_info_cb) override;
bool IsDecoderConfigSupported( bool IsDecoderConfigSupported(
media::VideoDecoderImplementation implementation,
const media::VideoDecoderConfig& config) override; const media::VideoDecoderConfig& config) override;
std::unique_ptr<media::VideoDecodeAccelerator> CreateVideoDecodeAccelerator() std::unique_ptr<media::VideoDecodeAccelerator> CreateVideoDecodeAccelerator()
override; override;
...@@ -161,7 +164,7 @@ class CONTENT_EXPORT GpuVideoAcceleratorFactoriesImpl ...@@ -161,7 +164,7 @@ class CONTENT_EXPORT GpuVideoAcceleratorFactoriesImpl
void SetContextProviderLostOnMainThread(); void SetContextProviderLostOnMainThread();
void OnSupportedDecoderConfigs( void OnSupportedDecoderConfigs(
const std::vector<media::SupportedVideoDecoderConfig>& supported_configs); const media::SupportedVideoDecoderConfigMap& supported_configs);
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; const scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
...@@ -198,7 +201,7 @@ class CONTENT_EXPORT GpuVideoAcceleratorFactoriesImpl ...@@ -198,7 +201,7 @@ class CONTENT_EXPORT GpuVideoAcceleratorFactoriesImpl
// If the Optional is empty, then we have not yet gotten the configs. If the // If the Optional is empty, then we have not yet gotten the configs. If the
// Optional contains an empty vector, then we have gotten the result and there // Optional contains an empty vector, then we have gotten the result and there
// are no supported configs. // are no supported configs.
base::Optional<std::vector<media::SupportedVideoDecoderConfig>> base::Optional<media::SupportedVideoDecoderConfigMap>
supported_decoder_configs_ GUARDED_BY(supported_decoder_configs_lock_); supported_decoder_configs_ GUARDED_BY(supported_decoder_configs_lock_);
// For sending requests to allocate shared memory in the Browser process. // For sending requests to allocate shared memory in the Browser process.
......
...@@ -67,6 +67,12 @@ const int32_t kMaxDecodeHistory = 32; ...@@ -67,6 +67,12 @@ const int32_t kMaxDecodeHistory = 32;
// requesting fallback to software decode. // requesting fallback to software decode.
const int32_t kMaxConsecutiveErrors = 5; const int32_t kMaxConsecutiveErrors = 5;
// Currently, RTCVideoDecoderAdapter only tries one VideoDecoderImplementation.
// Since we use it in multiple places, memorize it here to make it clear that
// they must be changed together.
constexpr media::VideoDecoderImplementation kImplementation =
media::VideoDecoderImplementation::kDefault;
// Map webrtc::VideoCodecType to media::VideoCodec. // Map webrtc::VideoCodecType to media::VideoCodec.
media::VideoCodec ToVideoCodec(webrtc::VideoCodecType video_codec_type) { media::VideoCodec ToVideoCodec(webrtc::VideoCodecType video_codec_type) {
switch (video_codec_type) { switch (video_codec_type) {
...@@ -156,7 +162,7 @@ std::unique_ptr<RTCVideoDecoderAdapter> RTCVideoDecoderAdapter::Create( ...@@ -156,7 +162,7 @@ std::unique_ptr<RTCVideoDecoderAdapter> RTCVideoDecoderAdapter::Create(
media::VideoColorSpace(), media::VIDEO_ROTATION_0, kDefaultSize, media::VideoColorSpace(), media::VIDEO_ROTATION_0, kDefaultSize,
gfx::Rect(kDefaultSize), kDefaultSize, media::EmptyExtraData(), gfx::Rect(kDefaultSize), kDefaultSize, media::EmptyExtraData(),
media::Unencrypted()); media::Unencrypted());
if (!gpu_factories->IsDecoderConfigSupported(config)) if (!gpu_factories->IsDecoderConfigSupported(kImplementation, config))
return nullptr; return nullptr;
// Synchronously verify that the decoder can be initialized. // Synchronously verify that the decoder can be initialized.
...@@ -342,7 +348,8 @@ void RTCVideoDecoderAdapter::InitializeOnMediaThread( ...@@ -342,7 +348,8 @@ void RTCVideoDecoderAdapter::InitializeOnMediaThread(
media_log_ = std::make_unique<media::NullMediaLog>(); media_log_ = std::make_unique<media::NullMediaLog>();
video_decoder_ = gpu_factories_->CreateVideoDecoder( video_decoder_ = gpu_factories_->CreateVideoDecoder(
media_log_.get(), base::BindRepeating(&OnRequestOverlayInfo)); media_log_.get(), kImplementation,
base::BindRepeating(&OnRequestOverlayInfo));
if (!video_decoder_) { if (!video_decoder_) {
media_task_runner_->PostTask(FROM_HERE, media_task_runner_->PostTask(FROM_HERE,
......
...@@ -105,18 +105,20 @@ class RTCVideoDecoderAdapterTest : public ::testing::Test { ...@@ -105,18 +105,20 @@ class RTCVideoDecoderAdapterTest : public ::testing::Test {
.WillByDefault(Return(media_thread_.task_runner())); .WillByDefault(Return(media_thread_.task_runner()));
EXPECT_CALL(gpu_factories_, GetTaskRunner()).Times(AtLeast(0)); EXPECT_CALL(gpu_factories_, GetTaskRunner()).Times(AtLeast(0));
ON_CALL(gpu_factories_, IsDecoderConfigSupported(_)) ON_CALL(gpu_factories_, IsDecoderConfigSupported(_, _))
.WillByDefault(Return(true)); .WillByDefault(Return(true));
EXPECT_CALL(gpu_factories_, IsDecoderConfigSupported(_)).Times(AtLeast(0)); EXPECT_CALL(gpu_factories_, IsDecoderConfigSupported(_, _))
.Times(AtLeast(0));
ON_CALL(gpu_factories_, CreateVideoDecoder(_, _)) ON_CALL(gpu_factories_, CreateVideoDecoder(_, _, _))
.WillByDefault( .WillByDefault(
[this](media::MediaLog* media_log, [this](media::MediaLog* media_log,
media::VideoDecoderImplementation impl,
const media::RequestOverlayInfoCB& request_overlay_info_cb) { const media::RequestOverlayInfoCB& request_overlay_info_cb) {
DCHECK(this->owned_video_decoder_); DCHECK(this->owned_video_decoder_);
return std::move(this->owned_video_decoder_); return std::move(this->owned_video_decoder_);
}); });
EXPECT_CALL(gpu_factories_, CreateVideoDecoder(_, _)).Times(AtLeast(0)); EXPECT_CALL(gpu_factories_, CreateVideoDecoder(_, _, _)).Times(AtLeast(0));
} }
~RTCVideoDecoderAdapterTest() { ~RTCVideoDecoderAdapterTest() {
...@@ -246,7 +248,7 @@ TEST_F(RTCVideoDecoderAdapterTest, Create_UnknownFormat) { ...@@ -246,7 +248,7 @@ TEST_F(RTCVideoDecoderAdapterTest, Create_UnknownFormat) {
} }
TEST_F(RTCVideoDecoderAdapterTest, Create_UnsupportedFormat) { TEST_F(RTCVideoDecoderAdapterTest, Create_UnsupportedFormat) {
EXPECT_CALL(gpu_factories_, IsDecoderConfigSupported(_)) EXPECT_CALL(gpu_factories_, IsDecoderConfigSupported(_, _))
.WillOnce(Return(false)); .WillOnce(Return(false));
rtc_video_decoder_adapter_ = RTCVideoDecoderAdapter::Create( rtc_video_decoder_adapter_ = RTCVideoDecoderAdapter::Create(
&gpu_factories_, webrtc::SdpVideoFormat(webrtc::CodecTypeToPayloadString( &gpu_factories_, webrtc::SdpVideoFormat(webrtc::CodecTypeToPayloadString(
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
// move CdmProxy related code into #if BUILDFLAG(ENABLE_LIBRARY_CDMS). // move CdmProxy related code into #if BUILDFLAG(ENABLE_LIBRARY_CDMS).
#include "media/cdm/cdm_proxy.h" #include "media/cdm/cdm_proxy.h"
#include "media/media_buildflags.h" #include "media/media_buildflags.h"
#include "media/video/supported_video_decoder_config.h"
#include "ui/gfx/ipc/color/gfx_param_traits_macros.h" #include "ui/gfx/ipc/color/gfx_param_traits_macros.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
...@@ -133,6 +134,9 @@ IPC_ENUM_TRAITS_MIN_MAX_VALUE(media::VideoCodecProfile, ...@@ -133,6 +134,9 @@ IPC_ENUM_TRAITS_MIN_MAX_VALUE(media::VideoCodecProfile,
media::VIDEO_CODEC_PROFILE_MIN, media::VIDEO_CODEC_PROFILE_MIN,
media::VIDEO_CODEC_PROFILE_MAX) media::VIDEO_CODEC_PROFILE_MAX)
IPC_ENUM_TRAITS_MAX_VALUE(media::VideoDecoderImplementation,
media::VideoDecoderImplementation::kMaxValue)
IPC_ENUM_TRAITS_MAX_VALUE(media::VideoPixelFormat, media::PIXEL_FORMAT_MAX) IPC_ENUM_TRAITS_MAX_VALUE(media::VideoPixelFormat, media::PIXEL_FORMAT_MAX)
IPC_ENUM_TRAITS_MAX_VALUE(media::VideoRotation, media::VIDEO_ROTATION_MAX) IPC_ENUM_TRAITS_MAX_VALUE(media::VideoRotation, media::VIDEO_ROTATION_MAX)
......
...@@ -52,11 +52,28 @@ void MojoDecoderFactory::CreateVideoDecoders( ...@@ -52,11 +52,28 @@ void MojoDecoderFactory::CreateVideoDecoders(
if (!base::FeatureList::IsEnabled(media::kMojoVideoDecoder)) if (!base::FeatureList::IsEnabled(media::kMojoVideoDecoder))
return; return;
mojom::VideoDecoderPtr video_decoder_ptr; mojom::VideoDecoderPtr video_decoder_ptr;
#if defined(OS_WIN)
// If the D3D11VideoDecoder is enabled, then push a kAlternate decoder ahead
// of the default one.
if (base::FeatureList::IsEnabled(media::kD3D11VideoDecoder)) {
interface_factory_->CreateVideoDecoder(
mojo::MakeRequest(&video_decoder_ptr));
video_decoders->push_back(std::make_unique<MojoVideoDecoder>(
task_runner, gpu_factories, media_log, std::move(video_decoder_ptr),
VideoDecoderImplementation::kAlternate, request_overlay_info_cb,
target_color_space));
}
#endif // defined(OS_WIN)
interface_factory_->CreateVideoDecoder(mojo::MakeRequest(&video_decoder_ptr)); interface_factory_->CreateVideoDecoder(mojo::MakeRequest(&video_decoder_ptr));
video_decoders->push_back(std::make_unique<MojoVideoDecoder>( video_decoders->push_back(std::make_unique<MojoVideoDecoder>(
task_runner, gpu_factories, media_log, std::move(video_decoder_ptr), task_runner, gpu_factories, media_log, std::move(video_decoder_ptr),
request_overlay_info_cb, target_color_space)); VideoDecoderImplementation::kDefault, request_overlay_info_cb,
target_color_space));
#endif #endif
} }
......
...@@ -112,6 +112,7 @@ MojoVideoDecoder::MojoVideoDecoder( ...@@ -112,6 +112,7 @@ MojoVideoDecoder::MojoVideoDecoder(
GpuVideoAcceleratorFactories* gpu_factories, GpuVideoAcceleratorFactories* gpu_factories,
MediaLog* media_log, MediaLog* media_log,
mojom::VideoDecoderPtr remote_decoder, mojom::VideoDecoderPtr remote_decoder,
VideoDecoderImplementation implementation,
const RequestOverlayInfoCB& request_overlay_info_cb, const RequestOverlayInfoCB& request_overlay_info_cb,
const gfx::ColorSpace& target_color_space) const gfx::ColorSpace& target_color_space)
: task_runner_(task_runner), : task_runner_(task_runner),
...@@ -124,6 +125,7 @@ MojoVideoDecoder::MojoVideoDecoder( ...@@ -124,6 +125,7 @@ MojoVideoDecoder::MojoVideoDecoder(
media_log_binding_(&media_log_service_), media_log_binding_(&media_log_service_),
request_overlay_info_cb_(request_overlay_info_cb), request_overlay_info_cb_(request_overlay_info_cb),
target_color_space_(target_color_space), target_color_space_(target_color_space),
video_decoder_implementation_(implementation),
weak_factory_(this) { weak_factory_(this) {
DVLOG(1) << __func__; DVLOG(1) << __func__;
weak_this_ = weak_factory_.GetWeakPtr(); weak_this_ = weak_factory_.GetWeakPtr();
...@@ -154,9 +156,9 @@ void MojoVideoDecoder::Initialize(const VideoDecoderConfig& config, ...@@ -154,9 +156,9 @@ void MojoVideoDecoder::Initialize(const VideoDecoderConfig& config,
InitCB bound_init_cb = InitCB bound_init_cb =
base::Bind(&ReportMojoVideoDecoderInitializeStatusToUMAAndRunCB, init_cb); base::Bind(&ReportMojoVideoDecoderInitializeStatusToUMAAndRunCB, init_cb);
// Fail immediately if we know that the remote side cannot support |config|. // Fail immediately if we know that the remote side cannot support |config|.
if (gpu_factories_ && !gpu_factories_->IsDecoderConfigSupported(config)) { if (gpu_factories_ && !gpu_factories_->IsDecoderConfigSupported(
video_decoder_implementation_, config)) {
task_runner_->PostTask(FROM_HERE, task_runner_->PostTask(FROM_HERE,
base::BindRepeating(bound_init_cb, false)); base::BindRepeating(bound_init_cb, false));
return; return;
...@@ -356,7 +358,7 @@ void MojoVideoDecoder::BindRemoteDecoder() { ...@@ -356,7 +358,7 @@ void MojoVideoDecoder::BindRemoteDecoder() {
std::move(client_ptr_info), std::move(media_log_ptr_info), std::move(client_ptr_info), std::move(media_log_ptr_info),
std::move(video_frame_handle_releaser_request), std::move(video_frame_handle_releaser_request),
std::move(remote_consumer_handle), std::move(command_buffer_id), std::move(remote_consumer_handle), std::move(command_buffer_id),
target_color_space_, video_decoder_implementation_); video_decoder_implementation_, target_color_space_);
} }
void MojoVideoDecoder::OnWaiting(WaitingReason reason) { void MojoVideoDecoder::OnWaiting(WaitingReason reason) {
......
...@@ -38,6 +38,7 @@ class MojoVideoDecoder final : public VideoDecoder, ...@@ -38,6 +38,7 @@ class MojoVideoDecoder final : public VideoDecoder,
GpuVideoAcceleratorFactories* gpu_factories, GpuVideoAcceleratorFactories* gpu_factories,
MediaLog* media_log, MediaLog* media_log,
mojom::VideoDecoderPtr remote_decoder, mojom::VideoDecoderPtr remote_decoder,
VideoDecoderImplementation implementation,
const RequestOverlayInfoCB& request_overlay_info_cb, const RequestOverlayInfoCB& request_overlay_info_cb,
const gfx::ColorSpace& target_color_space); const gfx::ColorSpace& target_color_space);
~MojoVideoDecoder() final; ~MojoVideoDecoder() final;
...@@ -123,8 +124,7 @@ class MojoVideoDecoder final : public VideoDecoder, ...@@ -123,8 +124,7 @@ class MojoVideoDecoder final : public VideoDecoder,
bool can_read_without_stalling_ = true; bool can_read_without_stalling_ = true;
int32_t max_decode_requests_ = 1; int32_t max_decode_requests_ = 1;
mojom::VideoDecoderImplementation video_decoder_implementation_ = VideoDecoderImplementation video_decoder_implementation_;
mojom::VideoDecoderImplementation::Default;
base::WeakPtr<MojoVideoDecoder> weak_this_; base::WeakPtr<MojoVideoDecoder> weak_this_;
base::WeakPtrFactory<MojoVideoDecoder> weak_factory_; base::WeakPtrFactory<MojoVideoDecoder> weak_factory_;
......
...@@ -55,23 +55,22 @@ interface VideoFrameHandleReleaser { ...@@ -55,23 +55,22 @@ interface VideoFrameHandleReleaser {
// Identifier to select between multiple underlying VideoDecoder implementations // Identifier to select between multiple underlying VideoDecoder implementations
// to back a mojo VideoDecoder service. // to back a mojo VideoDecoder service.
enum VideoDecoderImplementation { [Native]
Default = 0, enum VideoDecoderImplementation;
// For Windows, "Alternate" selects the D3D11VideoDecoder when the experiment
// is enabled. Otherwise, there is no alternate implementation.
Alternate = 1,
};
// A Mojo equivalent of media::VideoDecoder. In practice, this is used for // A Mojo equivalent of media::VideoDecoder. In practice, this is used for
// hardware decode offloading; in this case the client is a <video> tag running // hardware decode offloading; in this case the client is a <video> tag running
// in a renderer, and the implementation is running in the GPU process. // in a renderer, and the implementation is running in the GPU process.
interface VideoDecoder { interface VideoDecoder {
// Returns a list of supported configs. It is expected that Initialize() will // Returns a list of supported configs. It is expected that Initialize() will
// fail for any config that does not match an entry in this list. // fail for any config that does not match an entry in this list. Note that
// this returns a map for all VideoDecoderImplementation types, since it's
// much more convenient; we always want all of them.
// //
// May be called before Construct(). // May be called before Construct().
GetSupportedConfigs() => GetSupportedConfigs() =>
(array<SupportedVideoDecoderConfig> supported_configs); (map<VideoDecoderImplementation,
array<SupportedVideoDecoderConfig>> supported_configs);
// Initialize the decoder. This must be called before any method other than // Initialize the decoder. This must be called before any method other than
// GetSupportedConfigs(). // GetSupportedConfigs().
...@@ -105,8 +104,8 @@ interface VideoDecoder { ...@@ -105,8 +104,8 @@ interface VideoDecoder {
VideoFrameHandleReleaser& video_frame_handle_releaser, VideoFrameHandleReleaser& video_frame_handle_releaser,
handle<data_pipe_consumer> decoder_buffer_pipe, handle<data_pipe_consumer> decoder_buffer_pipe,
CommandBufferId? command_buffer_id, CommandBufferId? command_buffer_id,
gfx.mojom.ColorSpace target_color_space, VideoDecoderImplementation implementation,
VideoDecoderImplementation implementation); gfx.mojom.ColorSpace target_color_space);
// Configure (or reconfigure) the decoder. This must be called before decoding // Configure (or reconfigure) the decoder. This must be called before decoding
// any frames, and must not be called while there are pending Initialize(), // any frames, and must not be called while there are pending Initialize(),
......
...@@ -26,4 +26,5 @@ deps = [ ...@@ -26,4 +26,5 @@ deps = [
type_mappings = [ type_mappings = [
"media.mojom.OverlayInfo=media::OverlayInfo", "media.mojom.OverlayInfo=media::OverlayInfo",
"media.mojom.SupportedVideoDecoderConfig=media::SupportedVideoDecoderConfig", "media.mojom.SupportedVideoDecoderConfig=media::SupportedVideoDecoderConfig",
"media.mojom.VideoDecoderImplementation=media::VideoDecoderImplementation",
] ]
...@@ -121,14 +121,16 @@ std::unique_ptr<AudioDecoder> GpuMojoMediaClient::CreateAudioDecoder( ...@@ -121,14 +121,16 @@ std::unique_ptr<AudioDecoder> GpuMojoMediaClient::CreateAudioDecoder(
#endif // defined(OS_ANDROID) #endif // defined(OS_ANDROID)
} }
std::vector<SupportedVideoDecoderConfig> SupportedVideoDecoderConfigMap
GpuMojoMediaClient::GetSupportedVideoDecoderConfigs() { GpuMojoMediaClient::GetSupportedVideoDecoderConfigs() {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
static std::vector<SupportedVideoDecoderConfig> supported_configs = static SupportedVideoDecoderConfigMap supported_configs{
MediaCodecVideoDecoder::GetSupportedConfigs(); {VideoDecoderImplementation::kDefault,
MediaCodecVideoDecoder::GetSupportedConfigs()},
};
return supported_configs; return supported_configs;
#else #else
std::vector<SupportedVideoDecoderConfig> supported_configs; SupportedVideoDecoderConfigMap supported_config_map;
#if defined(OS_WIN) #if defined(OS_WIN)
// Start with the configurations supported by D3D11VideoDecoder. // Start with the configurations supported by D3D11VideoDecoder.
...@@ -138,9 +140,13 @@ GpuMojoMediaClient::GetSupportedVideoDecoderConfigs() { ...@@ -138,9 +140,13 @@ GpuMojoMediaClient::GetSupportedVideoDecoderConfigs() {
D3D11VideoDecoder::GetSupportedVideoDecoderConfigs( D3D11VideoDecoder::GetSupportedVideoDecoderConfigs(
gpu_preferences_, gpu_workarounds_, GetD3D11DeviceCallback()); gpu_preferences_, gpu_workarounds_, GetD3D11DeviceCallback());
} }
supported_configs = *d3d11_supported_configs_; supported_config_map[VideoDecoderImplementation::kAlternate] =
*d3d11_supported_configs_;
#endif #endif
auto& default_configs =
supported_config_map[VideoDecoderImplementation::kDefault];
// VdaVideoDecoder will be used to wrap a VDA. Add the configs supported // VdaVideoDecoder will be used to wrap a VDA. Add the configs supported
// by the VDA implementation. // by the VDA implementation.
// TODO(sandersd): Move conversion code into VdaVideoDecoder. // TODO(sandersd): Move conversion code into VdaVideoDecoder.
...@@ -152,7 +158,7 @@ GpuMojoMediaClient::GetSupportedVideoDecoderConfigs() { ...@@ -152,7 +158,7 @@ GpuMojoMediaClient::GetSupportedVideoDecoderConfigs() {
capabilities.flags & capabilities.flags &
VideoDecodeAccelerator::Capabilities::SUPPORTS_ENCRYPTED_STREAMS; VideoDecodeAccelerator::Capabilities::SUPPORTS_ENCRYPTED_STREAMS;
for (const auto& supported_profile : capabilities.supported_profiles) { for (const auto& supported_profile : capabilities.supported_profiles) {
supported_configs.push_back(SupportedVideoDecoderConfig( default_configs.push_back(SupportedVideoDecoderConfig(
supported_profile.profile, // profile_min supported_profile.profile, // profile_min
supported_profile.profile, // profile_max supported_profile.profile, // profile_max
supported_profile.min_resolution, // coded_size_min supported_profile.min_resolution, // coded_size_min
...@@ -161,7 +167,7 @@ GpuMojoMediaClient::GetSupportedVideoDecoderConfigs() { ...@@ -161,7 +167,7 @@ GpuMojoMediaClient::GetSupportedVideoDecoderConfigs() {
supported_profile.encrypted_only)); // require_encrypted supported_profile.encrypted_only)); // require_encrypted
} }
return supported_configs; return supported_config_map;
#endif // defined(OS_ANDROID) #endif // defined(OS_ANDROID)
} }
...@@ -169,22 +175,22 @@ std::unique_ptr<VideoDecoder> GpuMojoMediaClient::CreateVideoDecoder( ...@@ -169,22 +175,22 @@ std::unique_ptr<VideoDecoder> GpuMojoMediaClient::CreateVideoDecoder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner, scoped_refptr<base::SingleThreadTaskRunner> task_runner,
MediaLog* media_log, MediaLog* media_log,
mojom::CommandBufferIdPtr command_buffer_id, mojom::CommandBufferIdPtr command_buffer_id,
VideoDecoderImplementation implementation,
RequestOverlayInfoCB request_overlay_info_cb, RequestOverlayInfoCB request_overlay_info_cb,
const gfx::ColorSpace& target_color_space, const gfx::ColorSpace& target_color_space) {
mojom::VideoDecoderImplementation implementation) {
// All implementations require a command buffer. // All implementations require a command buffer.
if (!command_buffer_id) if (!command_buffer_id)
return nullptr; return nullptr;
// TODO(liberato): Support non-default for D3D11VideoDecoder. std::unique_ptr<VideoDecoder> video_decoder;
if (implementation != mojom::VideoDecoderImplementation::Default)
return nullptr;
switch (implementation) {
case VideoDecoderImplementation::kDefault: {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
auto get_stub_cb = auto get_stub_cb =
base::Bind(&GetCommandBufferStub, media_gpu_channel_manager_, base::Bind(&GetCommandBufferStub, media_gpu_channel_manager_,
command_buffer_id->channel_token, command_buffer_id->route_id); command_buffer_id->channel_token, command_buffer_id->route_id);
return std::make_unique<MediaCodecVideoDecoder>( video_decoder = std::make_unique<MediaCodecVideoDecoder>(
gpu_preferences_, gpu_feature_info_, DeviceInfo::GetInstance(), gpu_preferences_, gpu_feature_info_, DeviceInfo::GetInstance(),
CodecAllocator::GetInstance(gpu_task_runner_), CodecAllocator::GetInstance(gpu_task_runner_),
std::make_unique<AndroidVideoSurfaceChooserImpl>( std::make_unique<AndroidVideoSurfaceChooserImpl>(
...@@ -194,34 +200,36 @@ std::unique_ptr<VideoDecoder> GpuMojoMediaClient::CreateVideoDecoder( ...@@ -194,34 +200,36 @@ std::unique_ptr<VideoDecoder> GpuMojoMediaClient::CreateVideoDecoder(
std::move(get_stub_cb))); std::move(get_stub_cb)));
#elif defined(OS_CHROMEOS) || defined(OS_MACOSX) || defined(OS_WIN) || \ #elif defined(OS_CHROMEOS) || defined(OS_MACOSX) || defined(OS_WIN) || \
defined(OS_LINUX) defined(OS_LINUX)
std::unique_ptr<VideoDecoder> vda_video_decoder = VdaVideoDecoder::Create( video_decoder = VdaVideoDecoder::Create(
task_runner, gpu_task_runner_, media_log->Clone(), target_color_space, task_runner, gpu_task_runner_, media_log->Clone(), target_color_space,
gpu_preferences_, gpu_workarounds_, gpu_preferences_, gpu_workarounds_,
base::BindRepeating(&GetCommandBufferStub, media_gpu_channel_manager_, base::BindRepeating(&GetCommandBufferStub, media_gpu_channel_manager_,
command_buffer_id->channel_token, command_buffer_id->channel_token,
command_buffer_id->route_id)); command_buffer_id->route_id));
#endif // defined(OS_ANDROID)
} break;
case VideoDecoderImplementation::kAlternate:
#if defined(OS_WIN) #if defined(OS_WIN)
if (base::FeatureList::IsEnabled(kD3D11VideoDecoder)) { if (base::FeatureList::IsEnabled(kD3D11VideoDecoder)) {
// If nothing has cached the configs yet, then do so now. // If nothing has cached the configs yet, then do so now.
if (!d3d11_supported_configs_) if (!d3d11_supported_configs_)
GetSupportedVideoDecoderConfigs(); GetSupportedVideoDecoderConfigs();
std::unique_ptr<VideoDecoder> d3d11_video_decoder = video_decoder = D3D11VideoDecoder::Create(
D3D11VideoDecoder::Create( gpu_task_runner_, media_log->Clone(), gpu_preferences_,
gpu_task_runner_, media_log->Clone(), gpu_preferences_, gpu_workarounds_,
gpu_workarounds_, base::BindRepeating(&GetCommandBufferStub, media_gpu_channel_manager_,
base::BindRepeating( command_buffer_id->channel_token,
&GetCommandBufferStub, media_gpu_channel_manager_, command_buffer_id->route_id),
command_buffer_id->channel_token, command_buffer_id->route_id), GetD3D11DeviceCallback(), *d3d11_supported_configs_);
GetD3D11DeviceCallback(), *d3d11_supported_configs_);
return base::WrapUnique<VideoDecoder>(new FallbackVideoDecoder(
std::move(d3d11_video_decoder), std::move(vda_video_decoder)));
} }
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
return vda_video_decoder; break;
#else }; // switch
return nullptr;
#endif // defined(OS_ANDROID) // |video_decoder| may be null if we don't support |implementation|.
return video_decoder;
} }
std::unique_ptr<CdmFactory> GpuMojoMediaClient::CreateCdmFactory( std::unique_ptr<CdmFactory> GpuMojoMediaClient::CreateCdmFactory(
......
...@@ -41,8 +41,7 @@ class GpuMojoMediaClient : public MojoMediaClient { ...@@ -41,8 +41,7 @@ class GpuMojoMediaClient : public MojoMediaClient {
~GpuMojoMediaClient() final; ~GpuMojoMediaClient() final;
// MojoMediaClient implementation. // MojoMediaClient implementation.
std::vector<SupportedVideoDecoderConfig> GetSupportedVideoDecoderConfigs() SupportedVideoDecoderConfigMap GetSupportedVideoDecoderConfigs() final;
final;
void Initialize(service_manager::Connector* connector) final; void Initialize(service_manager::Connector* connector) final;
std::unique_ptr<AudioDecoder> CreateAudioDecoder( std::unique_ptr<AudioDecoder> CreateAudioDecoder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) final; scoped_refptr<base::SingleThreadTaskRunner> task_runner) final;
...@@ -50,9 +49,9 @@ class GpuMojoMediaClient : public MojoMediaClient { ...@@ -50,9 +49,9 @@ class GpuMojoMediaClient : public MojoMediaClient {
scoped_refptr<base::SingleThreadTaskRunner> task_runner, scoped_refptr<base::SingleThreadTaskRunner> task_runner,
MediaLog* media_log, MediaLog* media_log,
mojom::CommandBufferIdPtr command_buffer_id, mojom::CommandBufferIdPtr command_buffer_id,
VideoDecoderImplementation implementation,
RequestOverlayInfoCB request_overlay_info_cb, RequestOverlayInfoCB request_overlay_info_cb,
const gfx::ColorSpace& target_color_space, const gfx::ColorSpace& target_color_space) final;
mojom::VideoDecoderImplementation implementation) final;
std::unique_ptr<CdmFactory> CreateCdmFactory( std::unique_ptr<CdmFactory> CreateCdmFactory(
service_manager::mojom::InterfaceProvider* interface_provider) final; service_manager::mojom::InterfaceProvider* interface_provider) final;
#if BUILDFLAG(ENABLE_LIBRARY_CDMS) #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
......
...@@ -28,7 +28,7 @@ std::unique_ptr<AudioDecoder> MojoMediaClient::CreateAudioDecoder( ...@@ -28,7 +28,7 @@ std::unique_ptr<AudioDecoder> MojoMediaClient::CreateAudioDecoder(
return nullptr; return nullptr;
} }
std::vector<SupportedVideoDecoderConfig> SupportedVideoDecoderConfigMap
MojoMediaClient::GetSupportedVideoDecoderConfigs() { MojoMediaClient::GetSupportedVideoDecoderConfigs() {
return {}; return {};
} }
...@@ -37,9 +37,9 @@ std::unique_ptr<VideoDecoder> MojoMediaClient::CreateVideoDecoder( ...@@ -37,9 +37,9 @@ std::unique_ptr<VideoDecoder> MojoMediaClient::CreateVideoDecoder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner, scoped_refptr<base::SingleThreadTaskRunner> task_runner,
MediaLog* media_log, MediaLog* media_log,
mojom::CommandBufferIdPtr command_buffer_id, mojom::CommandBufferIdPtr command_buffer_id,
VideoDecoderImplementation implementation,
RequestOverlayInfoCB request_overlay_info_cb, RequestOverlayInfoCB request_overlay_info_cb,
const gfx::ColorSpace& target_color_space, const gfx::ColorSpace& target_color_space) {
mojom::VideoDecoderImplementation implementation) {
return nullptr; return nullptr;
} }
......
...@@ -44,6 +44,12 @@ class MediaLog; ...@@ -44,6 +44,12 @@ class MediaLog;
class Renderer; class Renderer;
class VideoDecoder; class VideoDecoder;
// Map of mojo VideoDecoder implementations to the vector of configs that they
// (probably) support.
using SupportedVideoDecoderConfigMap =
base::flat_map<VideoDecoderImplementation,
std::vector<SupportedVideoDecoderConfig>>;
class MEDIA_MOJO_EXPORT MojoMediaClient { class MEDIA_MOJO_EXPORT MojoMediaClient {
public: public:
// Called before the host application is scheduled to quit. // Called before the host application is scheduled to quit.
...@@ -58,16 +64,15 @@ class MEDIA_MOJO_EXPORT MojoMediaClient { ...@@ -58,16 +64,15 @@ class MEDIA_MOJO_EXPORT MojoMediaClient {
virtual std::unique_ptr<AudioDecoder> CreateAudioDecoder( virtual std::unique_ptr<AudioDecoder> CreateAudioDecoder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner); scoped_refptr<base::SingleThreadTaskRunner> task_runner);
virtual std::vector<SupportedVideoDecoderConfig> virtual SupportedVideoDecoderConfigMap GetSupportedVideoDecoderConfigs();
GetSupportedVideoDecoderConfigs();
virtual std::unique_ptr<VideoDecoder> CreateVideoDecoder( virtual std::unique_ptr<VideoDecoder> CreateVideoDecoder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner, scoped_refptr<base::SingleThreadTaskRunner> task_runner,
MediaLog* media_log, MediaLog* media_log,
mojom::CommandBufferIdPtr command_buffer_id, mojom::CommandBufferIdPtr command_buffer_id,
VideoDecoderImplementation implementation,
RequestOverlayInfoCB request_overlay_info_cb, RequestOverlayInfoCB request_overlay_info_cb,
const gfx::ColorSpace& target_color_space, const gfx::ColorSpace& target_color_space);
mojom::VideoDecoderImplementation implementation);
// Returns the Renderer to be used by MojoRendererService. // Returns the Renderer to be used by MojoRendererService.
// TODO(hubbe): Find out whether we should pass in |target_color_space| here. // TODO(hubbe): Find out whether we should pass in |target_color_space| here.
......
...@@ -124,8 +124,8 @@ void MojoVideoDecoderService::Construct( ...@@ -124,8 +124,8 @@ void MojoVideoDecoderService::Construct(
mojom::VideoFrameHandleReleaserRequest video_frame_handle_releaser, mojom::VideoFrameHandleReleaserRequest video_frame_handle_releaser,
mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe, mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe,
mojom::CommandBufferIdPtr command_buffer_id, mojom::CommandBufferIdPtr command_buffer_id,
const gfx::ColorSpace& target_color_space, VideoDecoderImplementation implementation,
mojom::VideoDecoderImplementation implementation) { const gfx::ColorSpace& target_color_space) {
DVLOG(1) << __func__; DVLOG(1) << __func__;
TRACE_EVENT0("media", "MojoVideoDecoderService::Construct"); TRACE_EVENT0("media", "MojoVideoDecoderService::Construct");
...@@ -151,9 +151,10 @@ void MojoVideoDecoderService::Construct( ...@@ -151,9 +151,10 @@ void MojoVideoDecoderService::Construct(
decoder_ = mojo_media_client_->CreateVideoDecoder( decoder_ = mojo_media_client_->CreateVideoDecoder(
task_runner, media_log_.get(), std::move(command_buffer_id), task_runner, media_log_.get(), std::move(command_buffer_id),
implementation,
base::BindRepeating( base::BindRepeating(
&MojoVideoDecoderService::OnDecoderRequestedOverlayInfo, weak_this_), &MojoVideoDecoderService::OnDecoderRequestedOverlayInfo, weak_this_),
target_color_space, implementation); target_color_space);
} }
void MojoVideoDecoderService::Initialize(const VideoDecoderConfig& config, void MojoVideoDecoderService::Initialize(const VideoDecoderConfig& config,
......
...@@ -48,8 +48,8 @@ class MEDIA_MOJO_EXPORT MojoVideoDecoderService final ...@@ -48,8 +48,8 @@ class MEDIA_MOJO_EXPORT MojoVideoDecoderService final
mojom::VideoFrameHandleReleaserRequest video_frame_handle_releaser, mojom::VideoFrameHandleReleaserRequest video_frame_handle_releaser,
mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe, mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe,
mojom::CommandBufferIdPtr command_buffer_id, mojom::CommandBufferIdPtr command_buffer_id,
const gfx::ColorSpace& target_color_space, VideoDecoderImplementation implementation,
mojom::VideoDecoderImplementation implementation) final; const gfx::ColorSpace& target_color_space) final;
void Initialize(const VideoDecoderConfig& config, void Initialize(const VideoDecoderConfig& config,
bool low_delay, bool low_delay,
int32_t cdm_id, int32_t cdm_id,
......
...@@ -170,9 +170,9 @@ class FakeMojoMediaClient : public MojoMediaClient { ...@@ -170,9 +170,9 @@ class FakeMojoMediaClient : public MojoMediaClient {
scoped_refptr<base::SingleThreadTaskRunner> task_runner, scoped_refptr<base::SingleThreadTaskRunner> task_runner,
MediaLog* media_log, MediaLog* media_log,
mojom::CommandBufferIdPtr command_buffer_id, mojom::CommandBufferIdPtr command_buffer_id,
VideoDecoderImplementation implementation,
RequestOverlayInfoCB request_overlay_info_cb, RequestOverlayInfoCB request_overlay_info_cb,
const gfx::ColorSpace& target_color_space, const gfx::ColorSpace& target_color_space) override {
mojom::VideoDecoderImplementation implementation) override {
return create_video_decoder_cb_.Run(media_log); return create_video_decoder_cb_.Run(media_log);
} }
...@@ -218,7 +218,8 @@ class MojoVideoDecoderIntegrationTest : public ::testing::Test { ...@@ -218,7 +218,8 @@ class MojoVideoDecoderIntegrationTest : public ::testing::Test {
// be tested. // be tested.
client_ = std::make_unique<MojoVideoDecoder>( client_ = std::make_unique<MojoVideoDecoder>(
base::ThreadTaskRunnerHandle::Get(), nullptr, &client_media_log_, base::ThreadTaskRunnerHandle::Get(), nullptr, &client_media_log_,
CreateRemoteVideoDecoder(), RequestOverlayInfoCB(), gfx::ColorSpace()); CreateRemoteVideoDecoder(), VideoDecoderImplementation::kDefault,
RequestOverlayInfoCB(), gfx::ColorSpace());
if (writer_capacity_) if (writer_capacity_)
client_->set_writer_capacity_for_testing(writer_capacity_); client_->set_writer_capacity_for_testing(writer_capacity_);
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "media/base/overlay_info.h" #include "media/base/overlay_info.h"
#include "media/base/video_decoder.h" #include "media/base/video_decoder.h"
#include "media/base/video_types.h" #include "media/base/video_types.h"
#include "media/video/supported_video_decoder_config.h"
#include "media/video/video_decode_accelerator.h" #include "media/video/video_decode_accelerator.h"
#include "media/video/video_encode_accelerator.h" #include "media/video/video_encode_accelerator.h"
#include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/gpu_memory_buffer.h"
...@@ -82,13 +83,16 @@ class MEDIA_EXPORT GpuVideoAcceleratorFactories { ...@@ -82,13 +83,16 @@ class MEDIA_EXPORT GpuVideoAcceleratorFactories {
virtual int32_t GetCommandBufferRouteId() = 0; virtual int32_t GetCommandBufferRouteId() = 0;
// Return true if |config| is potentially supported by a decoder created with // Return true if |config| is potentially supported by a decoder created with
// CreateVideoDecoder(). // CreateVideoDecoder() using |implementation|.
// //
// May be called on any thread. // May be called on any thread.
virtual bool IsDecoderConfigSupported(const VideoDecoderConfig& config) = 0; virtual bool IsDecoderConfigSupported(
VideoDecoderImplementation implementation,
const VideoDecoderConfig& config) = 0;
virtual std::unique_ptr<media::VideoDecoder> CreateVideoDecoder( virtual std::unique_ptr<media::VideoDecoder> CreateVideoDecoder(
MediaLog* media_log, MediaLog* media_log,
VideoDecoderImplementation implementation,
const RequestOverlayInfoCB& request_overlay_info_cb) = 0; const RequestOverlayInfoCB& request_overlay_info_cb) = 0;
// Caller owns returned pointer, but should call Destroy() on it (instead of // Caller owns returned pointer, but should call Destroy() on it (instead of
......
...@@ -36,10 +36,12 @@ class MockGpuVideoAcceleratorFactories : public GpuVideoAcceleratorFactories { ...@@ -36,10 +36,12 @@ class MockGpuVideoAcceleratorFactories : public GpuVideoAcceleratorFactories {
MOCK_METHOD0(GetChannelToken, base::UnguessableToken()); MOCK_METHOD0(GetChannelToken, base::UnguessableToken());
MOCK_METHOD0(GetCommandBufferRouteId, int32_t()); MOCK_METHOD0(GetCommandBufferRouteId, int32_t());
MOCK_METHOD1(IsDecoderConfigSupported, bool(const VideoDecoderConfig&)); MOCK_METHOD2(IsDecoderConfigSupported,
MOCK_METHOD2( bool(VideoDecoderImplementation, const VideoDecoderConfig&));
MOCK_METHOD3(
CreateVideoDecoder, CreateVideoDecoder,
std::unique_ptr<media::VideoDecoder>(MediaLog*, std::unique_ptr<media::VideoDecoder>(MediaLog*,
VideoDecoderImplementation,
const RequestOverlayInfoCB&)); const RequestOverlayInfoCB&));
// CreateVideo{Decode,Encode}Accelerator returns scoped_ptr, which the mocking // CreateVideo{Decode,Encode}Accelerator returns scoped_ptr, which the mocking
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef MEDIA_VIDEO_SUPPORTED_VIDEO_DECODER_CONFIG_H_ #ifndef MEDIA_VIDEO_SUPPORTED_VIDEO_DECODER_CONFIG_H_
#define MEDIA_VIDEO_SUPPORTED_VIDEO_DECODER_CONFIG_H_ #define MEDIA_VIDEO_SUPPORTED_VIDEO_DECODER_CONFIG_H_
#include "base/containers/flat_map.h"
#include "base/macros.h" #include "base/macros.h"
#include "media/base/media_export.h" #include "media/base/media_export.h"
#include "media/base/video_codecs.h" #include "media/base/video_codecs.h"
...@@ -49,6 +50,19 @@ struct MEDIA_EXPORT SupportedVideoDecoderConfig { ...@@ -49,6 +50,19 @@ struct MEDIA_EXPORT SupportedVideoDecoderConfig {
// Allow copy and assignment. // Allow copy and assignment.
}; };
// Enumeration of possible implementations for (Mojo)VideoDecoders.
enum class VideoDecoderImplementation {
kDefault = 0,
kAlternate = 1,
kMaxValue = kAlternate
};
// Map of mojo VideoDecoder implementations to the vector of configs that they
// (probably) support.
using SupportedVideoDecoderConfigMap =
base::flat_map<VideoDecoderImplementation,
std::vector<SupportedVideoDecoderConfig>>;
} // namespace media } // namespace media
#endif // MEDIA_VIDEO_SUPPORTED_VIDEO_DECODER_CONFIG_H_ #endif // MEDIA_VIDEO_SUPPORTED_VIDEO_DECODER_CONFIG_H_
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