From c2956da85b684e9cfb22784af8be52b4cdb36efc Mon Sep 17 00:00:00 2001 From: Sergey Ulanov Date: Mon, 9 May 2022 21:21:23 +0000 Subject: [PATCH] [Fuchsia] Stop using mediacodec.CodecFactory in renderer process Added CreateVideoDecoder method to the FuchsiaMediaResourceProvider interface. The renderer process uses it to connect StreamProcessor for hardware decoder. This allows to avoid exposing fuchsia.mediacodec.CodecFactory to the renderer process. Bug: 1293605 Change-Id: Iefbeb63ecd11d28edca919a151c37a415164841d Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3556806 Reviewed-by: Dan Sanders Reviewed-by: Tom Sepez Reviewed-by: David Dorwin Reviewed-by: Daniel Cheng Reviewed-by: Peng Huang Commit-Queue: David Dorwin Cr-Commit-Position: refs/heads/main@{#1001190} --- chrome/app/chrome.cml | 6 +- content/browser/BUILD.gn | 1 + .../media/media_resource_provider_fuchsia.cc | 81 +++++++++++++++++++ .../media/media_resource_provider_fuchsia.h | 5 ++ content/renderer/BUILD.gn | 1 + content/renderer/media/media_factory.cc | 4 + .../web_engine_content_browser_client.cc | 1 - media/BUILD.gn | 1 + media/filters/BUILD.gn | 32 -------- media/filters/fuchsia/DIR_METADATA | 9 --- media/fuchsia/mojom/BUILD.gn | 7 ++ .../fuchsia_media_resource_provider.mojom | 16 +++- ...sia_media_resource_provider_mojom_traits.h | 8 ++ media/fuchsia/video/BUILD.gn | 52 ++++++++++++ media/{filters/fuchsia => fuchsia/video}/DEPS | 2 + .../{filters/fuchsia => fuchsia/video}/OWNERS | 1 + .../fuchsia/video/fuchsia_decoder_factory.cc | 65 +++++++++++++++ media/fuchsia/video/fuchsia_decoder_factory.h | 47 +++++++++++ .../video}/fuchsia_video_decoder.cc | 81 +++---------------- .../video}/fuchsia_video_decoder.h | 27 +++---- .../video}/fuchsia_video_decoder_unittest.cc | 58 ++++++++++++- media/renderers/default_decoder_factory.cc | 25 ------ sandbox/policy/BUILD.gn | 4 +- .../policy/fuchsia/sandbox_policy_fuchsia.cc | 2 - 24 files changed, 367 insertions(+), 169 deletions(-) delete mode 100644 media/filters/fuchsia/DIR_METADATA create mode 100644 media/fuchsia/video/BUILD.gn rename media/{filters/fuchsia => fuchsia/video}/DEPS (61%) rename media/{filters/fuchsia => fuchsia/video}/OWNERS (57%) create mode 100644 media/fuchsia/video/fuchsia_decoder_factory.cc create mode 100644 media/fuchsia/video/fuchsia_decoder_factory.h rename media/{filters/fuchsia => fuchsia/video}/fuchsia_video_decoder.cc (88%) rename media/{filters/fuchsia => fuchsia/video}/fuchsia_video_decoder.h (86%) rename media/{filters/fuchsia => fuchsia/video}/fuchsia_video_decoder_unittest.cc (89%) diff --git a/chrome/app/chrome.cml b/chrome/app/chrome.cml index b6cc8b5743273f..7d2b289613e8c6 100644 --- a/chrome/app/chrome.cml +++ b/chrome/app/chrome.cml @@ -60,11 +60,7 @@ "fuchsia.media.Audio", "fuchsia.media.AudioDeviceEnumerator", "fuchsia.media.ProfileProvider", - - // TODO(crbug.com/1293605): Do not provide this until the - // delegation issue is resolved. - // "fuchsia.mediacodec.CodecFactory", - + "fuchsia.mediacodec.CodecFactory", "fuchsia.memorypressure.Provider", "fuchsia.net.interfaces.State", "fuchsia.net.name.Lookup", diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 9327226913de38..74bbab946f1ac9 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn @@ -2486,6 +2486,7 @@ source_set("browser") { "//media/fuchsia/mojom:fuchsia_media_resource_provider", "//third_party/abseil-cpp:absl", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mediacodec", "//third_party/fuchsia-sdk/sdk/pkg/inspect", "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp", "//third_party/fuchsia-sdk/sdk/pkg/sys_inspect_cpp", diff --git a/content/browser/renderer_host/media/media_resource_provider_fuchsia.cc b/content/browser/renderer_host/media/media_resource_provider_fuchsia.cc index 546981ebc00f74..a2e785f78ddb22 100644 --- a/content/browser/renderer_host/media/media_resource_provider_fuchsia.cc +++ b/content/browser/renderer_host/media/media_resource_provider_fuchsia.cc @@ -4,18 +4,55 @@ #include "content/browser/renderer_host/media/media_resource_provider_fuchsia.h" +#include +#include + #include "base/bind.h" +#include "base/command_line.h" #include "base/fuchsia/process_context.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/provision_fetcher_factory.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/storage_partition.h" +#include "media/base/media_switches.h" #include "media/base/provision_fetcher.h" #include "media/fuchsia/cdm/service/fuchsia_cdm_manager.h" namespace content { +namespace { + +absl::optional GetMimeTypeForVideoCodec(media::VideoCodec codec) { + switch (codec) { + case media::VideoCodec::kH264: + return "video/h264"; + case media::VideoCodec::kVP8: + return "video/vp8"; + case media::VideoCodec::kVP9: + return "video/vp9"; + case media::VideoCodec::kHEVC: + return "video/hevc"; + case media::VideoCodec::kAV1: + return "video/av1"; + + case media::VideoCodec::kVC1: + case media::VideoCodec::kMPEG2: + case media::VideoCodec::kMPEG4: + case media::VideoCodec::kTheora: + case media::VideoCodec::kDolbyVision: + return absl::nullopt; + + case media::VideoCodec::kUnknown: + break; + } + + NOTREACHED(); + return absl::nullopt; +} + +} // namespace + // static void MediaResourceProviderFuchsia::Bind( content::RenderFrameHost* frame_host, @@ -53,4 +90,48 @@ void MediaResourceProviderFuchsia::CreateCdm( key_system, origin(), std::move(create_fetcher_cb), std::move(request)); } +void MediaResourceProviderFuchsia::CreateVideoDecoder( + media::VideoCodec codec, + bool secure_mode, + fidl::InterfaceRequest + stream_processor_request) { + fuchsia::mediacodec::CreateDecoder_Params decoder_params; + + // Set format details ordinal to 0. Decoder doesn't change the format, so + // the value doesn't matter. + decoder_params.mutable_input_details()->set_format_details_version_ordinal(0); + + auto mime_type = GetMimeTypeForVideoCodec(codec); + if (!mime_type) { + // Drop `stream_processor_request` if the codec is not supported. + return; + } + decoder_params.mutable_input_details()->set_mime_type(mime_type.value()); + + if (secure_mode) { + decoder_params.set_secure_input_mode( + fuchsia::mediacodec::SecureMemoryMode::ON); + } + + if (secure_mode || base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kForceProtectedVideoOutputBuffers)) { + decoder_params.set_secure_output_mode( + fuchsia::mediacodec::SecureMemoryMode::ON); + } + + // Video demuxers return each video frame in a separate packet. This field + // must be set to get frame timestamps on the decoder output. + decoder_params.set_promise_separate_access_units_on_input(true); + + // We use `fuchsia.mediacodec` only for hardware decoders. Renderer will + // handle software decoding if hardware decoder is not available. + decoder_params.set_require_hw(true); + + auto decoder_factory = base::ComponentContextForProcess() + ->svc() + ->Connect(); + decoder_factory->CreateDecoder(std::move(decoder_params), + std::move(stream_processor_request)); +} + } // namespace content diff --git a/content/browser/renderer_host/media/media_resource_provider_fuchsia.h b/content/browser/renderer_host/media/media_resource_provider_fuchsia.h index dfcfe5e0baa2a5..da18db27beb83a 100644 --- a/content/browser/renderer_host/media/media_resource_provider_fuchsia.h +++ b/content/browser/renderer_host/media/media_resource_provider_fuchsia.h @@ -36,6 +36,11 @@ class MediaResourceProviderFuchsia final const std::string& key_system, fidl::InterfaceRequest request) final; + void CreateVideoDecoder( + media::VideoCodec codec, + bool secure_memory, + fidl::InterfaceRequest + stream_processor_request) final; }; } // namespace content diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 2cfb99f96203b8..7d046dad40391a 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn @@ -356,6 +356,7 @@ target(link_target_type, "renderer") { deps += [ "//media/fuchsia/cdm/client", + "//media/fuchsia/video", "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp", ] } diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc index 654246af14a87a..dcbd04f0cc00b9 100644 --- a/content/renderer/media/media_factory.cc +++ b/content/renderer/media/media_factory.cc @@ -85,6 +85,7 @@ #if BUILDFLAG(IS_FUCHSIA) #include "media/fuchsia/cdm/client/fuchsia_cdm_util.h" +#include "media/fuchsia/video/fuchsia_decoder_factory.h" #elif BUILDFLAG(ENABLE_MOJO_CDM) #include "media/mojo/clients/mojo_cdm_factory.h" // nogncheck #else @@ -788,6 +789,9 @@ base::WeakPtr MediaFactory::GetDecoderFactory() { GetMediaInterfaceFactory(); external_decoder_factory = std::make_unique(interface_factory); +#elif BUILDFLAG(IS_FUCHSIA) + external_decoder_factory = + std::make_unique(interface_broker_); #endif decoder_factory_ = std::make_unique( std::move(external_decoder_factory)); diff --git a/fuchsia/engine/browser/web_engine_content_browser_client.cc b/fuchsia/engine/browser/web_engine_content_browser_client.cc index 0aab28c9752705..3e70d54c6e29a7 100644 --- a/fuchsia/engine/browser/web_engine_content_browser_client.cc +++ b/fuchsia/engine/browser/web_engine_content_browser_client.cc @@ -195,7 +195,6 @@ void WebEngineContentBrowserClient::AppendExtraCommandLineSwitches( switches::kEnableContentDirectories, switches::kEnableProtectedVideoBuffers, switches::kEnableWidevine, - switches::kForceProtectedVideoOutputBuffers, switches::kMaxDecodedImageSizeMb, switches::kPlayreadyKeySystem, network::switches::kUnsafelyTreatInsecureOriginAsSecure, diff --git a/media/BUILD.gn b/media/BUILD.gn index ee9a7dd4c48eed..a4b4143def2392 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -209,6 +209,7 @@ test("media_unittests") { deps += [ "//media/fuchsia/audio:unittests", "//media/fuchsia/cdm/service:unittests", + "//media/fuchsia/video:unittests", ] use_cfv2 = false diff --git a/media/filters/BUILD.gn b/media/filters/BUILD.gn index 21984a18353a68..a4cd06a76985f5 100644 --- a/media/filters/BUILD.gn +++ b/media/filters/BUILD.gn @@ -237,26 +237,6 @@ source_set("filters") { "h264_bitstream_buffer.h", ] } - - if (is_fuchsia) { - sources += [ - "fuchsia/fuchsia_video_decoder.cc", - "fuchsia/fuchsia_video_decoder.h", - ] - public_deps = [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.media" ] - deps += [ - "//components/viz/common", - "//gpu/command_buffer/client", - "//gpu/command_buffer/common", - "//gpu/ipc/common", - "//media/fuchsia/cdm", - "//media/fuchsia/common", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mediacodec", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sysmem", - "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp", - "//ui/ozone", - ] - } } source_set("perftests") { @@ -345,18 +325,6 @@ source_set("unit_tests") { deps += [ "//ui/gl" ] } - if (is_fuchsia) { - sources += [ "fuchsia/fuchsia_video_decoder_unittest.cc" ] - deps += [ - "//components/viz/common", - "//components/viz/test:test_support", - "//gpu/command_buffer/client", - "//gpu/config", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sysmem", - "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp", - ] - } - # libvpx for running vpx test on chromecast doesn't support high bit depth. # This may cause some unit tests failure. if (is_chromecast) { diff --git a/media/filters/fuchsia/DIR_METADATA b/media/filters/fuchsia/DIR_METADATA deleted file mode 100644 index 7bba048979f42b..00000000000000 --- a/media/filters/fuchsia/DIR_METADATA +++ /dev/null @@ -1,9 +0,0 @@ -# Metadata information for this directory. -# -# For more information on DIR_METADATA files, see: -# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md -# -# For the schema of this file, see Metadata message: -# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto - -mixins: "//build/fuchsia/COMMON_METADATA" diff --git a/media/fuchsia/mojom/BUILD.gn b/media/fuchsia/mojom/BUILD.gn index 8e68e46ada63f3..b6f180913528e3 100644 --- a/media/fuchsia/mojom/BUILD.gn +++ b/media/fuchsia/mojom/BUILD.gn @@ -6,6 +6,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("fuchsia_media_resource_provider") { sources = [ "fuchsia_media_resource_provider.mojom" ] + deps = [ "//media/mojo/mojom" ] export_class_attribute_blink = "BLINK_PLATFORM_EXPORT" export_define_blink = "BLINK_PLATFORM_IMPLEMENTATION=1" @@ -18,10 +19,16 @@ mojom("fuchsia_media_resource_provider") { cpp = "::fidl::InterfaceRequest<::fuchsia::media::drm::ContentDecryptionModule>" move_only = true }, + { + mojom = "media.mojom.StreamProcessorRequest" + cpp = "::fidl::InterfaceRequest<::fuchsia::media::StreamProcessor>" + move_only = true + }, ] traits_headers = [ "fuchsia_media_resource_provider_mojom_traits.h" ] traits_public_deps = [ "//mojo/public/cpp/base/fuchsia:traits", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.media", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.media.drm", ] } diff --git a/media/fuchsia/mojom/fuchsia_media_resource_provider.mojom b/media/fuchsia/mojom/fuchsia_media_resource_provider.mojom index a91ba32b77b97c..6544c66df53cc6 100644 --- a/media/fuchsia/mojom/fuchsia_media_resource_provider.mojom +++ b/media/fuchsia/mojom/fuchsia_media_resource_provider.mojom @@ -4,17 +4,29 @@ module media.mojom; +import "media/mojo/mojom/media_types.mojom"; + // Mojo struct for -// fidl::InterfaceRequest. +// `fidl::InterfaceRequest`. struct CdmRequest { handle request; }; +// Mojo struct for `fidl::InterfaceRequest`. +struct StreamProcessorRequest { + handle request; +}; + // Interface used by the renderer to connect to CDM and mediacodec resources. // Instances are document-scoped. interface FuchsiaMediaResourceProvider { // Create connection to fuchsia::media::drm::ContentDecryptionModule for - // |key_system|. Implementation should make sure the persistent storage is + // `key_system`. Implementation should make sure the persistent storage is // isolated per web origin. CreateCdm(string key_system, CdmRequest cdm_request); + + // Create connection to fuchsia::media::StreamProcessor for the specified + // `codec`. + CreateVideoDecoder(VideoCodec codec, bool secure_memory, + StreamProcessorRequest stream_processor_request); }; diff --git a/media/fuchsia/mojom/fuchsia_media_resource_provider_mojom_traits.h b/media/fuchsia/mojom/fuchsia_media_resource_provider_mojom_traits.h index 18bfe1e66b4763..49475a5ccb3d35 100644 --- a/media/fuchsia/mojom/fuchsia_media_resource_provider_mojom_traits.h +++ b/media/fuchsia/mojom/fuchsia_media_resource_provider_mojom_traits.h @@ -5,6 +5,7 @@ #ifndef MEDIA_FUCHSIA_MOJOM_FUCHSIA_MEDIA_RESOURCE_PROVIDER_MOJOM_TRAITS_H_ #define MEDIA_FUCHSIA_MOJOM_FUCHSIA_MEDIA_RESOURCE_PROVIDER_MOJOM_TRAITS_H_ +#include #include #include "mojo/public/cpp/base/fuchsia/fidl_interface_request_mojom_traits.h" @@ -19,6 +20,13 @@ struct StructTraits< media::mojom::CdmRequestDataView, fuchsia::media::drm::ContentDecryptionModule> {}; +template <> +struct StructTraits> + : public FidlInterfaceRequestStructTraits< + media::mojom::StreamProcessorRequestDataView, + fuchsia::media::StreamProcessor> {}; + } // namespace mojo #endif // MEDIA_FUCHSIA_MOJOM_FUCHSIA_MEDIA_RESOURCE_PROVIDER_MOJOM_TRAITS_H_ diff --git a/media/fuchsia/video/BUILD.gn b/media/fuchsia/video/BUILD.gn new file mode 100644 index 00000000000000..addeb301c993be --- /dev/null +++ b/media/fuchsia/video/BUILD.gn @@ -0,0 +1,52 @@ +# Copyright 2022 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. + +source_set("video") { + visibility = [ + ":unittests", + "//content/renderer/*", + ] + sources = [ + "fuchsia_decoder_factory.cc", + "fuchsia_decoder_factory.h", + "fuchsia_video_decoder.cc", + "fuchsia_video_decoder.h", + ] + public_deps = [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.media" ] + deps = [ + "//components/viz/common", + "//gpu/command_buffer/client", + "//gpu/command_buffer/common", + "//gpu/ipc/common", + "//media/fuchsia/cdm", + "//media/fuchsia/common", + "//media/fuchsia/mojom:fuchsia_media_resource_provider", + "//third_party/blink/public/common", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mediacodec", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sysmem", + "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp", + "//ui/ozone", + ] +} + +source_set("unittests") { + testonly = true + sources = [ "fuchsia_video_decoder_unittest.cc" ] + deps = [ + ":video", + "//base/test:test_support", + "//components/viz/common", + "//components/viz/test:test_support", + "//gpu/command_buffer/client", + "//gpu/config", + "//media:test_support", + "//media/fuchsia/mojom:fuchsia_media_resource_provider", + "//testing/gmock", + "//testing/gtest", + "//third_party/blink/public/common", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mediacodec", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sysmem", + "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp", + ] +} diff --git a/media/filters/fuchsia/DEPS b/media/fuchsia/video/DEPS similarity index 61% rename from media/filters/fuchsia/DEPS rename to media/fuchsia/video/DEPS index 03a54a2749f728..505bcdb71cdc37 100644 --- a/media/filters/fuchsia/DEPS +++ b/media/fuchsia/video/DEPS @@ -1,3 +1,5 @@ include_rules = [ "+components/viz/common/gpu/raster_context_provider.h", + "+mojo/public", + "+third_party/blink/public", ] \ No newline at end of file diff --git a/media/filters/fuchsia/OWNERS b/media/fuchsia/video/OWNERS similarity index 57% rename from media/filters/fuchsia/OWNERS rename to media/fuchsia/video/OWNERS index e7034eabb1e958..fca2c201c25270 100644 --- a/media/filters/fuchsia/OWNERS +++ b/media/fuchsia/video/OWNERS @@ -1 +1,2 @@ +sergeyu@chromium.org file://build/fuchsia/OWNERS diff --git a/media/fuchsia/video/fuchsia_decoder_factory.cc b/media/fuchsia/video/fuchsia_decoder_factory.cc new file mode 100644 index 00000000000000..190081766274a2 --- /dev/null +++ b/media/fuchsia/video/fuchsia_decoder_factory.cc @@ -0,0 +1,65 @@ +// Copyright 2022 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/fuchsia/video/fuchsia_decoder_factory.h" + +#include "components/viz/common/gpu/raster_context_provider.h" +#include "media/fuchsia/video/fuchsia_video_decoder.h" +#include "media/video/gpu_video_accelerator_factories.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" + +namespace media { + +FuchsiaDecoderFactory::FuchsiaDecoderFactory( + blink::BrowserInterfaceBrokerProxy* interface_broker) { + interface_broker->GetInterface( + media_resource_provider_handle_.InitWithNewPipeAndPassReceiver()); +} + +FuchsiaDecoderFactory::~FuchsiaDecoderFactory() = default; + +void FuchsiaDecoderFactory::CreateAudioDecoders( + scoped_refptr task_runner, + MediaLog* media_log, + std::vector>* audio_decoders) { + // There are no Fuchsia-specific audio decoders. +} + +SupportedVideoDecoderConfigs +FuchsiaDecoderFactory::GetSupportedVideoDecoderConfigsForWebRTC() { + // TODO(crbug.com/1207991) Enable HW decoder support for WebRTC. + return {}; +} + +void FuchsiaDecoderFactory::CreateVideoDecoders( + scoped_refptr task_runner, + GpuVideoAcceleratorFactories* gpu_factories, + MediaLog* media_log, + RequestOverlayInfoCB request_overlay_info_cb, + const gfx::ColorSpace& target_color_space, + std::vector>* video_decoders) { + // Bind `media_resource_provider_` the first time this function is called. + if (media_resource_provider_handle_) + media_resource_provider_.Bind(std::move(media_resource_provider_handle_)); + + if (gpu_factories && gpu_factories->IsGpuVideoDecodeAcceleratorEnabled()) { + auto* context_provider = gpu_factories->GetMediaContextProvider(); + + // GetMediaContextProvider() may return nullptr when the context was lost + // (e.g. after GPU process crash). To handle this case, RenderThreadImpl + // creates a new GpuVideoAcceleratorFactories with a new ContextProvider + // instance, but there is no way to get it here. For now just don't add + // FuchsiaVideoDecoder in that scenario. + // + // TODO(crbug.com/995902) Handle lost context. + if (context_provider) { + video_decoders->push_back(std::make_unique( + context_provider, media_resource_provider_.get())); + } else { + LOG(ERROR) << "Can't create FuchsiaVideoDecoder due to GPU context loss."; + } + } +} + +} // namespace media diff --git a/media/fuchsia/video/fuchsia_decoder_factory.h b/media/fuchsia/video/fuchsia_decoder_factory.h new file mode 100644 index 00000000000000..5d99a3e21ab096 --- /dev/null +++ b/media/fuchsia/video/fuchsia_decoder_factory.h @@ -0,0 +1,47 @@ +// Copyright 2022 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. + +#ifndef MEDIA_FUCHSIA_VIDEO_FUCHSIA_DECODER_FACTORY_H_ +#define MEDIA_FUCHSIA_VIDEO_FUCHSIA_DECODER_FACTORY_H_ + +#include "media/base/decoder_factory.h" +#include "media/fuchsia/mojom/fuchsia_media_resource_provider.mojom.h" +#include "mojo/public/cpp/bindings/remote.h" + +namespace blink { +class BrowserInterfaceBrokerProxy; +} // namespace blink + +namespace media { + +class FuchsiaDecoderFactory final : public DecoderFactory { + public: + explicit FuchsiaDecoderFactory( + blink::BrowserInterfaceBrokerProxy* interface_broker); + ~FuchsiaDecoderFactory() final; + + // DecoderFactory implementation. + void CreateAudioDecoders( + scoped_refptr task_runner, + MediaLog* media_log, + std::vector>* audio_decoders) final; + SupportedVideoDecoderConfigs GetSupportedVideoDecoderConfigsForWebRTC() final; + void CreateVideoDecoders( + scoped_refptr task_runner, + GpuVideoAcceleratorFactories* gpu_factories, + MediaLog* media_log, + RequestOverlayInfoCB request_overlay_info_cb, + const gfx::ColorSpace& target_color_space, + std::vector>* video_decoders) final; + + private: + mojo::PendingRemote + media_resource_provider_handle_; + mojo::Remote + media_resource_provider_; +}; + +} // namespace media + +#endif // MEDIA_FUCHSIA_VIDEO_FUCHSIA_DECODER_FACTORY_H_ \ No newline at end of file diff --git a/media/filters/fuchsia/fuchsia_video_decoder.cc b/media/fuchsia/video/fuchsia_video_decoder.cc similarity index 88% rename from media/filters/fuchsia/fuchsia_video_decoder.cc rename to media/fuchsia/video/fuchsia_video_decoder.cc index f7fabf268cc790..28e71308053d86 100644 --- a/media/filters/fuchsia/fuchsia_video_decoder.cc +++ b/media/fuchsia/video/fuchsia_video_decoder.cc @@ -2,10 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "media/filters/fuchsia/fuchsia_video_decoder.h" +#include "media/fuchsia/video/fuchsia_video_decoder.h" -#include -#include #include #include "base/bind.h" @@ -37,7 +35,8 @@ #include "media/fuchsia/common/decrypting_sysmem_buffer_stream.h" #include "media/fuchsia/common/passthrough_sysmem_buffer_stream.h" #include "media/fuchsia/common/stream_processor_helper.h" -#include "third_party/libyuv/include/libyuv/video_common.h" +#include "media/fuchsia/mojom/fuchsia_media_resource_provider.mojom.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "ui/gfx/buffer_types.h" #include "ui/gfx/client_native_pixmap_factory.h" #include "ui/ozone/public/client_native_pixmap_factory_ozone.h" @@ -176,27 +175,11 @@ class FuchsiaVideoDecoder::OutputMailbox { base::WeakPtrFactory weak_factory_; }; -// static -std::unique_ptr FuchsiaVideoDecoder::Create( - scoped_refptr raster_context_provider) { - return std::make_unique( - std::move(raster_context_provider), - /*enable_sw_decoding=*/false); -} - -// static -std::unique_ptr FuchsiaVideoDecoder::CreateForTests( - scoped_refptr raster_context_provider, - bool enable_sw_decoding) { - return std::make_unique( - std::move(raster_context_provider), enable_sw_decoding); -} - FuchsiaVideoDecoder::FuchsiaVideoDecoder( scoped_refptr raster_context_provider, - bool enable_sw_decoding) + media::mojom::FuchsiaMediaResourceProvider* media_resource_provider) : raster_context_provider_(raster_context_provider), - enable_sw_decoding_(enable_sw_decoding), + media_resource_provider_(media_resource_provider), use_overlays_for_video_(base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kUseOverlaysForVideo)), sysmem_allocator_("CrFuchsiaVideoDecoder"), @@ -271,51 +254,9 @@ void FuchsiaVideoDecoder::Initialize(const VideoDecoderConfig& config, // Reset output buffers since we won't be able to re-use them. ReleaseOutputBuffers(); - fuchsia::mediacodec::CreateDecoder_Params decoder_params; - decoder_params.mutable_input_details()->set_format_details_version_ordinal(0); - - switch (config.codec()) { - case VideoCodec::kH264: - decoder_params.mutable_input_details()->set_mime_type("video/h264"); - break; - case VideoCodec::kVP8: - decoder_params.mutable_input_details()->set_mime_type("video/vp8"); - break; - case VideoCodec::kVP9: - decoder_params.mutable_input_details()->set_mime_type("video/vp9"); - break; - case VideoCodec::kHEVC: - decoder_params.mutable_input_details()->set_mime_type("video/hevc"); - break; - case VideoCodec::kAV1: - decoder_params.mutable_input_details()->set_mime_type("video/av1"); - break; - - default: - std::move(done_callback).Run(DecoderStatus::Codes::kUnsupportedCodec); - return; - } - - if (secure_mode) { - decoder_params.set_secure_input_mode( - fuchsia::mediacodec::SecureMemoryMode::ON); - } - - if (secure_mode || base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kForceProtectedVideoOutputBuffers)) { - decoder_params.set_secure_output_mode( - fuchsia::mediacodec::SecureMemoryMode::ON); - } - - decoder_params.set_promise_separate_access_units_on_input(true); - decoder_params.set_require_hw(!enable_sw_decoding_); - - auto decoder_factory = base::ComponentContextForProcess() - ->svc() - ->Connect(); fuchsia::media::StreamProcessorPtr decoder; - decoder_factory->CreateDecoder(std::move(decoder_params), - decoder.NewRequest()); + media_resource_provider_->CreateVideoDecoder(config.codec(), secure_mode, + decoder.NewRequest()); decoder_ = std::make_unique(std::move(decoder), this); current_config_ = config; @@ -569,11 +510,9 @@ void FuchsiaVideoDecoder::OnStreamProcessorOutputPacket( VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, VK_CHROMA_LOCATION_COSITED_EVEN, VK_CHROMA_LOCATION_COSITED_EVEN, /*format_features=*/0)); - // Mark the frame as power-efficient when software decoders are disabled. The - // codec may still decode on hardware even when |enable_sw_decoding_| is set - // (i.e. power_efficient flag would not be set correctly in that case). It - // doesn't matter because software decoders can be enabled only for tests. - frame->metadata().power_efficient = !enable_sw_decoding_; + // Mark the frame as power-efficient since (software decoders are used only in + // tests). + frame->metadata().power_efficient = true; // Allow this video frame to be promoted as an overlay, because it was // registered with an ImagePipe. diff --git a/media/filters/fuchsia/fuchsia_video_decoder.h b/media/fuchsia/video/fuchsia_video_decoder.h similarity index 86% rename from media/filters/fuchsia/fuchsia_video_decoder.h rename to media/fuchsia/video/fuchsia_video_decoder.h index bdabdb9d5236dd..22a115f339c1c7 100644 --- a/media/filters/fuchsia/fuchsia_video_decoder.h +++ b/media/fuchsia/video/fuchsia_video_decoder.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MEDIA_FILTERS_FUCHSIA_FUCHSIA_VIDEO_DECODER_H_ -#define MEDIA_FILTERS_FUCHSIA_FUCHSIA_VIDEO_DECODER_H_ +#ifndef MEDIA_FUCHSIA_VIDEO_FUCHSIA_VIDEO_DECODER_H_ +#define MEDIA_FUCHSIA_VIDEO_FUCHSIA_VIDEO_DECODER_H_ #include #include @@ -29,25 +29,17 @@ class RasterContextProvider; namespace media { +namespace mojom { +class FuchsiaMediaResourceProvider; +} // namespace mojom + class MEDIA_EXPORT FuchsiaVideoDecoder : public VideoDecoder, public SysmemBufferStream::Sink, public StreamProcessorHelper::Client { public: - // Creates VideoDecoder that uses fuchsia.mediacodec API. The returned - // VideoDecoder instance will only try to use hardware video codecs. - MEDIA_EXPORT static std::unique_ptr Create( - scoped_refptr raster_context_provider); - - // Same as above, but also allows to enable software codecs. This is useful - // for FuchsiaVideoDecoder tests that run on systems that don't have hardware - // decoder support. - MEDIA_EXPORT static std::unique_ptr CreateForTests( - scoped_refptr raster_context_provider, - bool enable_sw_decoding); - FuchsiaVideoDecoder( scoped_refptr raster_context_provider, - bool enable_sw_decoding); + media::mojom::FuchsiaMediaResourceProvider* media_resource_provider); ~FuchsiaVideoDecoder() override; FuchsiaVideoDecoder(const FuchsiaVideoDecoder&) = delete; @@ -121,7 +113,8 @@ class MEDIA_EXPORT FuchsiaVideoDecoder : public VideoDecoder, void ReleaseOutputBuffers(); const scoped_refptr raster_context_provider_; - const bool enable_sw_decoding_; + media::mojom::FuchsiaMediaResourceProvider* media_resource_provider_; + const bool use_overlays_for_video_; OutputCB output_cb_; @@ -168,4 +161,4 @@ class MEDIA_EXPORT FuchsiaVideoDecoder : public VideoDecoder, } // namespace media -#endif // MEDIA_FILTERS_FUCHSIA_FUCHSIA_VIDEO_DECODER_H_ +#endif // MEDIA_FUCHSIA_VIDEO_FUCHSIA_VIDEO_DECODER_H_ diff --git a/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc b/media/fuchsia/video/fuchsia_video_decoder_unittest.cc similarity index 89% rename from media/filters/fuchsia/fuchsia_video_decoder_unittest.cc rename to media/fuchsia/video/fuchsia_video_decoder_unittest.cc index fc20438fea8bc0..55e61b290f6cd0 100644 --- a/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc +++ b/media/fuchsia/video/fuchsia_video_decoder_unittest.cc @@ -2,8 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "media/filters/fuchsia/fuchsia_video_decoder.h" +#include "media/fuchsia/video/fuchsia_video_decoder.h" +#include #include #include @@ -24,6 +25,7 @@ #include "media/base/test_helpers.h" #include "media/base/video_decoder.h" #include "media/base/video_frame.h" +#include "media/fuchsia/mojom/fuchsia_media_resource_provider.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/gpu_fence.h" #include "ui/gfx/gpu_memory_buffer.h" @@ -286,6 +288,52 @@ class TestRasterContextProvider base::OnceClosure on_destroyed_; }; +class TestFuchsiaMediaResourceProvider + : public media::mojom::FuchsiaMediaResourceProvider { + public: + // media::mojom::FuchsiaMediaResourceProvider implementation. + void CreateCdm( + const std::string& key_system, + fidl::InterfaceRequest + request) final { + ADD_FAILURE(); + } + void CreateVideoDecoder( + media::VideoCodec codec, + bool secure_memory, + fidl::InterfaceRequest + stream_processor_request) final { + EXPECT_FALSE(secure_memory); + + fuchsia::mediacodec::CreateDecoder_Params decoder_params; + decoder_params.mutable_input_details()->set_format_details_version_ordinal( + 0); + + switch (codec) { + case VideoCodec::kH264: + decoder_params.mutable_input_details()->set_mime_type("video/h264"); + break; + case VideoCodec::kVP9: + decoder_params.mutable_input_details()->set_mime_type("video/vp9"); + break; + + default: + ADD_FAILURE() << "CreateVideoDecoder() called with unexpected codec: " + << static_cast(codec); + return; + } + + decoder_params.set_promise_separate_access_units_on_input(true); + decoder_params.set_require_hw(false); + + auto decoder_factory = base::ComponentContextForProcess() + ->svc() + ->Connect(); + decoder_factory->CreateDecoder(std::move(decoder_params), + std::move(stream_processor_request)); + } +}; + } // namespace class FuchsiaVideoDecoderTest : public testing::Test { @@ -293,9 +341,9 @@ class FuchsiaVideoDecoderTest : public testing::Test { FuchsiaVideoDecoderTest() : raster_context_provider_( base::MakeRefCounted()), - decoder_( - FuchsiaVideoDecoder::CreateForTests(raster_context_provider_.get(), - /*enable_sw_decoding=*/true)) {} + decoder_(std::make_unique( + raster_context_provider_.get(), + &test_media_resource_provider_)) {} FuchsiaVideoDecoderTest(const FuchsiaVideoDecoderTest&) = delete; FuchsiaVideoDecoderTest& operator=(const FuchsiaVideoDecoderTest&) = delete; @@ -376,6 +424,8 @@ class FuchsiaVideoDecoderTest : public testing::Test { base::test::SingleThreadTaskEnvironment task_environment_{ base::test::SingleThreadTaskEnvironment::MainThreadType::IO}; + TestFuchsiaMediaResourceProvider test_media_resource_provider_; + scoped_refptr raster_context_provider_; std::unique_ptr decoder_; diff --git a/media/renderers/default_decoder_factory.cc b/media/renderers/default_decoder_factory.cc index 430ec53038a847..f052f86cd39c3f 100644 --- a/media/renderers/default_decoder_factory.cc +++ b/media/renderers/default_decoder_factory.cc @@ -22,10 +22,6 @@ #include "media/filters/decrypting_video_decoder.h" #endif -#if BUILDFLAG(IS_FUCHSIA) -#include "media/filters/fuchsia/fuchsia_video_decoder.h" -#endif - #if BUILDFLAG(ENABLE_DAV1D_DECODER) #include "media/filters/dav1d_video_decoder.h" #endif @@ -160,27 +156,6 @@ void DefaultDecoderFactory::CreateVideoDecoders( std::move(request_overlay_info_cb), target_color_space, video_decoders); } -#if BUILDFLAG(IS_FUCHSIA) - // TODO(crbug.com/1122116): Minimize Fuchsia-specific code paths. - if (gpu_factories && gpu_factories->IsGpuVideoDecodeAcceleratorEnabled()) { - auto* context_provider = gpu_factories->GetMediaContextProvider(); - - // GetMediaContextProvider() may return nullptr when the context was lost - // (e.g. after GPU process crash). To handle this case RenderThreadImpl - // creates a new GpuVideoAcceleratorFactories with a new ContextProvider - // instance, but there is no way to get it here. For now just don't add - // FuchsiaVideoDecoder in that scenario. - // - // TODO(crbug.com/580386): Handle context loss properly. - if (context_provider) { - video_decoders->push_back(FuchsiaVideoDecoder::Create(context_provider)); - } else { - DLOG(ERROR) - << "Can't create FuchsiaVideoDecoder due to GPU context loss."; - } - } -#endif - #if BUILDFLAG(ENABLE_LIBVPX) video_decoders->push_back(std::make_unique()); #endif diff --git a/sandbox/policy/BUILD.gn b/sandbox/policy/BUILD.gn index 4e5b63ff322d51..3cfc7a365d3f41 100644 --- a/sandbox/policy/BUILD.gn +++ b/sandbox/policy/BUILD.gn @@ -157,7 +157,9 @@ component("policy") { "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.fonts", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.intl", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.logger", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mediacodec", + + # TODO(crbug.com/1224707): Remove after switching to fuchsia.scheduler API. + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.media", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.memorypressure", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.net.interfaces", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sysmem", diff --git a/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc b/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc index b58b66f26783d1..36169b39e0212e 100644 --- a/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc +++ b/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -121,7 +120,6 @@ constexpr SandboxConfig kRendererConfig = { fuchsia::fonts::Provider::Name_, // TODO(crbug.com/1224707): Use the fuchsia.scheduler API instead. fuchsia::media::ProfileProvider::Name_, - fuchsia::mediacodec::CodecFactory::Name_, fuchsia::memorypressure::Provider::Name_, fuchsia::sysmem::Allocator::Name_, fuchsia::ui::composition::Allocator::Name_,