[M130 Migration][EMSS] Support playing clear content without `use.upstream.architecture` 43/324743/3
authorPiotr Bałut <p.balut@samsung.com>
Thu, 20 Feb 2025 11:27:35 +0000 (12:27 +0100)
committerBot Blink <blinkbot@samsung.com>
Sat, 24 May 2025 17:36:29 +0000 (17:36 +0000)
This is a port of the following patches:
* [EMSS] Support playing clear content without `use.upstream.architecture`
  https://review.tizen.org/gerrit/c/platform/framework/web/chromium-efl/+/315767
* [M130 Migration][EMSS] Use WASM Player with upstream architecture code path in HTMLMediaElement
  https://review.tizen.org/gerrit/c/platform/framework/web/chromium-efl/+/320450
* [EMSS] Make WASM Player use TTvdVideoRenderer regardless of upstream arch flag
  https://review.tizen.org/gerrit/c/platform/framework/web/chromium-efl/+/322962
* [M130 Migration][EMSS] Disable double seek hack when playing with WASM Player
  https://archive.tizen.org/gerrit/318822

[PROBLEM]
WASM Player on M120 runs exclusively on upstream architecture (TTvd
decoder). Before this patch an attempt to run it without
`use.upstream.architecture` flag resulted in a player that was mostly
non-functional.

[SOLUTION]
This patch adds code paths that selectively enables
`use.upstream.architecture` features in a pipeline that runs WASM
Player.

This has one limitation, namely protected content playback. As creating
CDM module implementation is not tied to any player instance, it is
impossible to create an upstream architecture CDM based on presence of
EMSS when `use.upstream.architecture` is not enabled. Playing
protected content with WASM Player still requires enabling upstream
arch.

Signed-off-by: Piotr Bałut <p.balut@samsung.com>
Bug: https://jira-eu.sec.samsung.net/browse/VDWASM-2372
Change-Id: I7199ea463d4ca8237cdb15d811217da3607dc203

content/renderer/media/media_factory.cc
media/base/pipeline.h
media/base/pipeline_impl.cc
media/filters/pipeline_controller.cc
media/filters/pipeline_controller.h
third_party/blink/renderer/core/html/media/html_media_element.cc
third_party/blink/renderer/core/html/media/html_media_element.h
third_party/blink/renderer/platform/media/web_media_player_impl.cc
third_party/blink/renderer/platform/media/web_media_player_impl.h
tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc
wrt/src/renderer/tv/wrt_renderer_client_tv.cc

index 4426b8984be9b2591316d646a50666e92e103d49..daf7311505454c452d4c73d53b5dbd0c7e0e11e8 100644 (file)
@@ -82,6 +82,7 @@
 #endif
 
 #if defined(TIZEN_MULTIMEDIA)
+#include "third_party/blink/renderer/core/html/media/html_media_element.h"
 #include "tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client_factory.h"
 #endif
 
@@ -495,7 +496,15 @@ std::unique_ptr<blink::WebMediaPlayer> MediaFactory::CreateMediaPlayer(
   GetInterfaceBroker().GetInterface(
       metrics_provider.InitWithNewPipeAndPassReceiver());
 
-  const bool use_surface_layer = features::UseSurfaceLayerForVideo();
+#if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+  const auto is_elementary_media_stream_source =
+      client->GetEmssPipelineMode().has_value();
+#else
+  const auto is_elementary_media_stream_source = false;
+#endif  // defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+
+  const bool use_surface_layer =
+      features::UseSurfaceLayerForVideo() || is_elementary_media_stream_source;
   std::unique_ptr<blink::WebVideoFrameSubmitter> submitter =
       use_surface_layer
           ? CreateSubmitter(main_thread_compositor_task_runner, settings,
@@ -537,7 +546,8 @@ std::unique_ptr<blink::WebMediaPlayer> MediaFactory::CreateMediaPlayer(
 #endif
 
 #if defined(TIZEN_MULTIMEDIA) && defined(TIZEN_VIDEO_HOLE)
-  if (media::IsUpstreamArchitectureEnabled()&&
+  if ((media::IsUpstreamArchitectureEnabled() ||
+       is_elementary_media_stream_source) &&
       is_video_hole) {
     LOG(INFO) << "Use upstream architecture, disable video hole";
     is_video_hole = false;
@@ -638,7 +648,8 @@ MediaFactory::CreateRendererFactorySelector(
   }
 
 #if defined(TIZEN_MULTIMEDIA)
-  if (!media::IsUpstreamArchitectureEnabled()) {
+  if (!media::IsUpstreamArchitectureEnabled() &&
+      !blink::IsMediaElementNodeWithEmss(element_id)) {
     auto media_player_factory =
         std::make_unique<MediaPlayerRendererClientFactory>(
             render_thread->compositor_task_runner(), CreateMojoRendererFactory());
index 1d718218457cbeaa3ea1d63a6a1c6f295110cd10..fa9e0c1ff2f340b50c42a5fb2121059e76261f91 100644 (file)
@@ -150,6 +150,7 @@ class MEDIA_EXPORT Pipeline {
     virtual void OnPrePlayerReload(bool is_reload) = 0;
 #endif
 #if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+    virtual bool IsElementaryMediaStreamSource() const = 0;
     virtual void OnSessionIdChange(uint32_t session_id) = 0;
 #endif
   };
index 781c02d6b73ed57cd6d8e3ebda7e625a1f801f16..78d3eb9f059e8d28955fdf8e391837165af247d9 100644 (file)
@@ -2137,6 +2137,13 @@ void PipelineImpl::RendererWrapper::ReportMetadata(StartType start_type) {
 
 #if defined(TIZEN_MULTIMEDIA)
 bool PipelineImpl::RendererWrapper::ShouldUseUpstreamArchitecture() const {
+#if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+  if (demuxer_ &&
+      demuxer_->GetDemuxerType() == DemuxerType::kElementaryMediaStreamSource) {
+    return true;
+  }
+#endif  // defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+
   return IsUpstreamArchitectureEnabled();
 }
 #endif  // defined(TIZEN_MULTIMEDIA)
@@ -2864,6 +2871,12 @@ void PipelineImpl::OnPrePlayerReload(bool is_reload) {
 
 #if defined(TIZEN_MULTIMEDIA)
 bool PipelineImpl::ShouldUseUpstreamArchitecture() const {
+#if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+  if (client_ && client_->IsElementaryMediaStreamSource()) {
+    return true;
+  }
+#endif  // defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+
   return IsUpstreamArchitectureEnabled();
 }
 #endif  // defined(TIZEN_MULTIMEDIA)
index 9ad32a8df2c6375c6b2b2b55fb3409554a90b5c3..d8f7aab762e0c98ef707b39880344a7ab8cb0002 100644 (file)
@@ -183,7 +183,7 @@ void PipelineController::OnPipelineStatus(State expected_state,
   State old_state = state_;
 
 #if BUILDFLAG(IS_TIZEN_TV)
-  if (!IsUpstreamArchitectureEnabled() && (old_state == State::RESUMING) &&
+  if (!ShouldUseUpstreamArchitecture() && (old_state == State::RESUMING) &&
       (expected_state == State::SUSPENDED))
     state_ = State::RESUMING;
   else
@@ -243,7 +243,7 @@ void PipelineController::Dispatch() {
 // error, so here can set suspended directly once suspend called.
 #if BUILDFLAG(IS_TIZEN_TV)
     state_ =
-        IsUpstreamArchitectureEnabled() ? State::SUSPENDING : State::SUSPENDED;
+        ShouldUseUpstreamArchitecture() ? State::SUSPENDING : State::SUSPENDED;
 #else
     state_ = State::SUSPENDING;
 #endif
@@ -708,5 +708,16 @@ void PipelineController::SetVideoVisibility(bool visible) {
     pipeline_->SetVideoVisibility(visible);
   }
 }
+
+bool PipelineController::ShouldUseUpstreamArchitecture() const {
+#if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+  if (demuxer_ &&
+      demuxer_->GetDemuxerType() == DemuxerType::kElementaryMediaStreamSource) {
+    return true;
+  }
+#endif  // defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+
+  return IsUpstreamArchitectureEnabled();
+}
 #endif
 }  // namespace media
index bdf153ee7c0927b458233f0e47d21ccc3751df2f..1720d4f5d03977a3cb20aa44c21d1da0e5cd64ca 100644 (file)
@@ -198,6 +198,7 @@ class MEDIA_EXPORT PipelineController {
   double GetStartDate() const;
   void DestroyPlayerSync(base::OnceClosure cb);
   void SetVideoVisibility(bool visible);
+  bool ShouldUseUpstreamArchitecture() const;
 #endif
  private:
   // Attempts to make progress from the current state to the target state.
index 6c2a9a56287bcb70f1c94141c305135ae20c9e44..02abe527de83abaab79b86acb00b88d3d65b1e54 100644 (file)
@@ -3421,7 +3421,7 @@ bool HTMLMediaElement::SetWallClock(const AtomicString& wallclock_url) {
 
 int32_t HTMLMediaElement::GetVideoId() const {
 #if BUILDFLAG(IS_TIZEN_TV)
-  if (media::IsUpstreamArchitectureEnabled()) {
+  if (ShouldUseUpstreamArchitecture()) {
     if (!web_media_player_) {
       return 0;
     }
@@ -3785,7 +3785,7 @@ void HTMLMediaElement::SelectedVideoTrackChanged(VideoTrack* track) {
   }
 
 #if BUILDFLAG(IS_TIZEN_TV)
-  if (media::IsUpstreamArchitectureEnabled()) {
+  if (ShouldUseUpstreamArchitecture()) {
     if (track->selected()) {
       web_media_player_->SelectedVideoTrackChanged(track->id());
     } else {
@@ -5685,6 +5685,19 @@ bool HTMLMediaElement::IsCanPlayControlledByEmss() const {
 #endif
 }
 
+#if BUILDFLAG(IS_TIZEN_TV)
+bool HTMLMediaElement::ShouldUseUpstreamArchitecture() const {
+#if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+  if (media_source_attachment_ &&
+      media_source_attachment_->IsElementaryMediaStreamSource()) {
+    return true;
+  }
+#endif  // defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+
+  return media::IsUpstreamArchitectureEnabled();
+}
+#endif  // BUILDFLAG(IS_TIZEN_TV)
+
 bool HTMLMediaElement::IsInteractiveContent() const {
   return FastHasAttribute(html_names::kControlsAttr);
 }
@@ -6365,6 +6378,17 @@ void HTMLMediaElement::ActivatePlayer() {
 }
 #endif
 
+#if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+bool IsMediaElementNodeWithEmss(blink::DOMNodeId dom_node_id) {
+  const auto* node = blink::Node::FromDomNodeId(dom_node_id);
+  if (!IsA<HTMLMediaElement>(*node)) {
+    return false;
+  }
+  const auto* media_element = static_cast<const blink::HTMLMediaElement*>(node);
+  return media_element ? media_element->IsElementaryMediaStreamSource() : false;
+}
+#endif  // defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+
 STATIC_ASSERT_ENUM(WebMediaPlayer::kReadyStateHaveNothing,
                    HTMLMediaElement::kHaveNothing);
 STATIC_ASSERT_ENUM(WebMediaPlayer::kReadyStateHaveMetadata,
index f4c465fec88acb1980c21b9a8f6e18f3474b70c0..0ce4729bb00befc5c621a05d1996f840a297c4c4 100644 (file)
@@ -676,6 +676,10 @@ class CORE_EXPORT HTMLMediaElement
   // in which case default canplay events should not be emitted.
   bool IsCanPlayControlledByEmss() const;
 
+#if BUILDFLAG(IS_TIZEN_TV)
+  bool ShouldUseUpstreamArchitecture() const;
+#endif  // BUILDFLAG(IS_TIZEN_TV)
+
   void RemotePlaybackCompatibilityChanged(const WebURL&,
                                           bool is_compatible) final;
   bool HasSelectedVideoTrack() final;
@@ -1195,6 +1199,14 @@ struct DowncastTraits<HTMLMediaElement> {
   }
 };
 
+#if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+bool IsMediaElementNodeWithEmss(blink::DOMNodeId dom_node_id);
+#else
+inline bool IsMediaElementNodeWithEmss(blink::DOMNodeId) {
+  return false;
+}
+#endif  // defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_
index f2b778ecc8e6aebf94736ef3fc2b40ebb602f766..34be41799920986b131350f638f2a5dee7871e50 100644 (file)
@@ -1837,6 +1837,10 @@ WebMediaPlayerImpl::GetHlsDataSourceProvider() {
 #endif
 
 #if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+bool WebMediaPlayerImpl::IsElementaryMediaStreamSource() const  {
+  return client_ && client_->IsElementaryMediaStreamSource();
+}
+
 void WebMediaPlayerImpl::OnSessionIdChange(uint32_t session_id) {
   session_id_ = session_id;
 }
@@ -2742,6 +2746,11 @@ bool WebMediaPlayerImpl::IsSyncDestroyPlayerNeeded() {
   if (media::IsUpstreamArchitectureEnabled())
     return false;
 
+#if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+  if (client_ && client_->IsElementaryMediaStreamSource())
+    return false;
+#endif  // defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+
   bool single_process_mode = base::CommandLine::ForCurrentProcess()->HasSwitch(
       switches::kSingleProcess);
   bool isMSE = load_type_ == kLoadTypeMediaSource;
index 87ba4842a0b980c0ee4c41e1bbb849f1dcb49697..576f2104598f5d12deab3b1bb7198c2fc2f6a22b 100644 (file)
@@ -508,6 +508,7 @@ class PLATFORM_EXPORT WebMediaPlayerImpl
   void OnAudioPipelineInfoChange(const media::AudioPipelineInfo& info) override;
   void OnVideoPipelineInfoChange(const media::VideoPipelineInfo& info) override;
 #if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+  bool IsElementaryMediaStreamSource() const override;
   void OnSessionIdChange(uint32_t session_id) override;
 #endif
 #if defined(TIZEN_MULTIMEDIA)
index 7e7e1b775cfeb65c31acfb642f73870816688a5c..d3eb8e49c0611b0d8aa994f8d9407445224f2375 100644 (file)
@@ -249,7 +249,8 @@ ContentRendererClientEfl::GetBaseRendererFactory(
     base::RepeatingCallback<media::GpuVideoAcceleratorFactories*()>
         get_gpu_factories_cb,
     int element_id) {
-  if (media::IsUpstreamArchitectureEnabled()) {
+  if (media::IsUpstreamArchitectureEnabled() ||
+      blink::IsMediaElementNodeWithEmss(element_id)) {
     mojo::SharedRemote<media::mojom::TTvdVideoRendererManager>
         ttvd_video_renderer_manager;
     render_frame->GetBrowserInterfaceBroker().GetInterface(
index b21cbd0c88e646bf54695cfa0da01cad8fb595fc..bc810e10345fe010ef0d3770df31dac989ffa97e 100644 (file)
@@ -184,7 +184,8 @@ WRTRendererClientTV::GetBaseRendererFactory(
     base::RepeatingCallback<media::GpuVideoAcceleratorFactories*()>
         get_gpu_factories_cb,
     int element_id) {
-  if (media::IsUpstreamArchitectureEnabled()) {
+  if (media::IsUpstreamArchitectureEnabled() ||
+      blink::IsMediaElementNodeWithEmss(element_id)) {
     mojo::SharedRemote<media::mojom::TTvdVideoRendererManager>
         ttvd_video_renderer_manager;
     render_frame->GetBrowserInterfaceBroker().GetInterface(