[EMSS] Return actually selected decoding mode (SW or HW) 21/320921/2
authorPiotr Bałut <p.balut@samsung.com>
Tue, 5 Nov 2024 15:42:00 +0000 (16:42 +0100)
committerBot Blink <blinkbot@samsung.com>
Mon, 25 Nov 2024 16:55:58 +0000 (16:55 +0000)
[PROBLEM]
When HW with fallback decoding mode is used, querying decoding mode does
not provide reliable results. Furthermore validation is performed on
every packet - improper assumption about currently selected decoder may
lead to refusing to accept correct packets.

[SOLUTION]
* In normal latency mode currently selected decoding mode will be
  retrieved when statistics are updated, as they carry decoding mode
  info. This is HTMLMediaElement code path.
* In low latency modes an internal EMSS code path to notify about
  selected decoder was added, as decoder is managed directly by EMSS in
  low latency.

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

22 files changed:
third_party/blink/public/platform/web_media_player_client.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/core/html/media/media_source_attachment.h
third_party/blink/renderer/modules/mediasource/media_source_attachment_supplement.cc
third_party/blink/renderer/modules/mediasource/media_source_attachment_supplement.h
third_party/blink/renderer/platform/media/web_media_player_impl.cc
tizen_src/chromium_impl/content/renderer/media/tizen/elementary_media_stream_source/control_thread/track_dispatcher_client.h
tizen_src/chromium_impl/content/renderer/media/tizen/elementary_media_stream_source/control_thread/track_impl.cc
tizen_src/chromium_impl/content/renderer/media/tizen/elementary_media_stream_source/control_thread/track_impl.h
tizen_src/chromium_impl/content/renderer/media/tizen/elementary_media_stream_source/worker_thread/append_client.h
tizen_src/chromium_impl/content/renderer/media/tizen/elementary_media_stream_source/worker_thread/ms_decoding_stream.cc
tizen_src/chromium_impl/content/renderer/media/tizen/elementary_media_stream_source/worker_thread/ms_decoding_stream.h
tizen_src/chromium_impl/content/renderer/media/tizen/elementary_media_stream_source/worker_thread/track_impl.cc
tizen_src/chromium_impl/content/renderer/media/tizen/elementary_media_stream_source/worker_thread/track_impl.h
tizen_src/chromium_impl/third_party/blink/renderer/modules/elementary_media_stream_source/elementary_media_stream_source.cc
tizen_src/chromium_impl/third_party/blink/renderer/modules/elementary_media_stream_source/elementary_media_stream_source.h
tizen_src/chromium_impl/third_party/blink/renderer/modules/elementary_media_stream_source/elementary_media_track.cc
tizen_src/chromium_impl/third_party/blink/renderer/modules/elementary_media_stream_source/elementary_media_track.h
tizen_src/chromium_impl/third_party/blink/renderer/modules/elementary_media_stream_source/same_thread_elementary_media_stream_source_attachment.cc
tizen_src/chromium_impl/third_party/blink/renderer/modules/elementary_media_stream_source/same_thread_elementary_media_stream_source_attachment.h
tizen_src/chromium_impl/third_party/blink/renderer/platform/elementary_media_stream_source/web_elementary_media_track_control.h

index f5165a901ee82f87587163d1cd5350593dd2b655..4d20d8a02199bea424db499d33a9c4d328467c7c 100644 (file)
@@ -139,6 +139,8 @@ class BLINK_PLATFORM_EXPORT WebMediaPlayerClient {
   virtual bool IsLowLatencyMode() const = 0;
   virtual bool IsVideoTextureMode() const = 0;
   virtual void OnLoadDeferredUntilSourceOpen() = 0;
+  virtual void SetIsAudioDecodedByPlatform(bool is_decoded_by_platform) = 0;
+  virtual void SetIsVideoDecodedByPlatform(bool is_decoded_by_platform) = 0;
   absl::optional<content::elementary_media_stream_source::PipelineMode>
   GetEmssPipelineMode() const;
 #endif  // defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
index f48b43282186573e8fe5ed64d8c9191ca6b9b463..d60db23b77b28b721e183674ee4cd170db99c0fa 100644 (file)
@@ -5541,6 +5541,28 @@ void HTMLMediaElement::FireDeferredLoadAfterSourceOpen() {
       media_source_attachment_->OnPlay(media_source_tracer_);
   }
 }
+
+void HTMLMediaElement::SetIsAudioDecodedByPlatform(
+    bool is_decoded_by_platform) {
+  if (!media_source_attachment_ ||
+      !media_source_attachment_->IsElementaryMediaStreamSource()) {
+    return;
+  }
+
+  media_source_attachment_->SetIsAudioDecodedByPlatform(media_source_tracer_,
+                                                        is_decoded_by_platform);
+}
+
+void HTMLMediaElement::SetIsVideoDecodedByPlatform(
+    bool is_decoded_by_platform) {
+  if (!media_source_attachment_ ||
+      !media_source_attachment_->IsElementaryMediaStreamSource()) {
+    return;
+  }
+
+  media_source_attachment_->SetIsVideoDecodedByPlatform(media_source_tracer_,
+                                                        is_decoded_by_platform);
+}
 #endif
 
 bool HTMLMediaElement::IsCanPlayControlledByEmss() const {
index e830f8a56351d00a7fc18f986e13d9e052586d94..1a47b1184d9df5a4d696f3c3cb324d9b6397f7ee 100644 (file)
@@ -656,6 +656,8 @@ class CORE_EXPORT HTMLMediaElement
           web_elementary_stream_source_dispatcher) final;
   void OnLoadDeferredUntilSourceOpen() final;
   void FireDeferredLoadAfterSourceOpen();
+  void SetIsAudioDecodedByPlatform(bool is_decoded_by_platform) final;
+  void SetIsVideoDecodedByPlatform(bool is_decoded_by_platform) final;
 #endif
 
   // Default implementation of upstream architecture in low latency mode fires
index 84997ce237093822581566a6ba40ac8b48f4d15f..a57f488cdcfe850f0a37581b05e1af9fde93f843 100644 (file)
@@ -164,6 +164,10 @@ class CORE_EXPORT MediaSourceAttachment
   virtual void OnPlay(MediaSourceTracer* tracer) = 0;
   virtual void OnResume(MediaSourceTracer* tracer) = 0;
   virtual void OnSuspend(MediaSourceTracer* tracer) = 0;
+  virtual void SetIsAudioDecodedByPlatform(MediaSourceTracer* tracer,
+                                           bool is_decoded_by_platform) = 0;
+  virtual void SetIsVideoDecodedByPlatform(MediaSourceTracer* tracer,
+                                           bool is_decoded_by_platform) = 0;
   // OnElementTimeUpdate() executes with media element's timeupdate timer and
   // during some key operations (like seeking). As opposed to that,
   // UpdatePlaybackPosition() notifies EMSS as soon as official playback
index 3c42a6ef0048f7e9be8a00a349399351a440c897..748c127201dd005ff4cbfd4dcdccdc0544d2ef65 100644 (file)
@@ -109,6 +109,14 @@ void MediaSourceAttachmentSupplement::OnResume(MediaSourceTracer*) {}
 
 void MediaSourceAttachmentSupplement::OnSuspend(MediaSourceTracer*) {}
 
+void MediaSourceAttachmentSupplement::SetIsAudioDecodedByPlatform(
+    MediaSourceTracer*,
+    bool) {}
+
+void MediaSourceAttachmentSupplement::SetIsVideoDecodedByPlatform(
+    MediaSourceTracer*,
+    bool) {}
+
 void MediaSourceAttachmentSupplement::UpdatePlaybackPosition(
     MediaSourceTracer*,
     double,
index 8a49add6d4059709f4fa8d28699d92f30fb464c4..e0f3e369876f16a022e32cc46200cc71ff133e84 100644 (file)
@@ -160,6 +160,10 @@ class MediaSourceAttachmentSupplement : public MediaSourceAttachment {
   void OnPlay(MediaSourceTracer* tracer) override;
   void OnResume(MediaSourceTracer* tracer) override;
   void OnSuspend(MediaSourceTracer* tracer) override;
+  void SetIsAudioDecodedByPlatform(MediaSourceTracer* tracer,
+                                   bool is_decoded_by_platform) override;
+  void SetIsVideoDecodedByPlatform(MediaSourceTracer* tracer,
+                                   bool is_decoded_by_platform) override;
   void UpdatePlaybackPosition(MediaSourceTracer* tracer,
                               double playback_position,
                               std::optional<uint32_t> session_id) override;
index 80eb90595f663b04aa24c2d9dbf29dc63a226793..49c843da1cace8f819f75dfa6de11f7d9674a476 100644 (file)
@@ -3073,6 +3073,12 @@ void WebMediaPlayerImpl::OnAudioPipelineInfoChange(
 
   audio_decoder_type_ = info.decoder_type;
 
+#if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+  if (client_) {
+    client_->SetIsVideoDecodedByPlatform(info.is_platform_decoder);
+  }
+#endif  // defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+
   // If there's no current reporter, there's nothing to be done.
   if (!watch_time_reporter_)
     return;
@@ -3088,6 +3094,12 @@ void WebMediaPlayerImpl::OnVideoPipelineInfoChange(
 
   video_decoder_type_ = info.decoder_type;
 
+#if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+  if (client_) {
+    client_->SetIsVideoDecodedByPlatform(info.is_platform_decoder);
+  }
+#endif  // defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
+
   // If there's no current reporter, there's nothing to be done.
   if (!watch_time_reporter_)
     return;
index 6d9a2edb31bbc20bc67f252181533d54007b0a06..06a1f4742a37b1a500b28de21da4e0c7e2612ca4 100644 (file)
@@ -23,6 +23,7 @@ class TrackDispatcherClient : public EnableDispatcher {
 
   virtual void OnTrackFinishedSeek(uint32_t session_id,
                                    base::TimeDelta time_after_seek) = 0;
+  virtual void SetIsDecodedByPlatform(bool is_decoded_by_platform) = 0;
   virtual void SetTrackClosing(uint32_t session_id,
                                base::OnceCallback<void(CallbackResult)> cb) = 0;
   virtual void TrackEOSAppended(uint32_t session_id) = 0;
index 4725837b60cbfc53faea4984de236a4add938b75..841160b0345170c3232aa38050d1cf364391363d 100644 (file)
@@ -207,6 +207,16 @@ void TrackImpl::OnTrackFinishedSeek(uint32_t session_id,
   }
 }
 
+void TrackImpl::SetIsDecodedByPlatform(bool is_decoded_by_platform) {
+  EMSS_DEBUG_TYPED() << is_decoded_by_platform;
+
+  if (!control_client_) {
+    return;
+  }
+
+  control_client_->SetIsDecodedByPlatform(is_decoded_by_platform);
+}
+
 void TrackImpl::SetTrackClosing(uint32_t session_id,
                                 base::OnceCallback<void(CallbackResult)> cb) {
   EMSS_DEBUG_TYPED();
index c8f4a7456e43c6eb18049bdcac9a8323e79d883d..4af919e40b3a76b1ac23a566020f44de7e9bad91 100644 (file)
@@ -64,6 +64,7 @@ class TrackImpl : public blink::WebElementaryMediaTrackControl,
   // TrackDispatcherClient
   void OnTrackFinishedSeek(uint32_t session_id,
                            base::TimeDelta time_after_seek) override;
+  void SetIsDecodedByPlatform(bool is_decoded_by_platform) override;
   void SetTrackClosing(uint32_t session_id,
                        base::OnceCallback<void(CallbackResult)> cb) override;
   void TrackEOSAppended(uint32_t session_id) override;
index 247bb9d0842f018083e0a85f68240c179169e2be..8d47eb0d6833b95b64d61f9be86117c6ca4d5370 100644 (file)
@@ -21,6 +21,7 @@ class AppendClient {
 
   virtual bool IsReadRequested() const = 0;
   virtual void ReadMediaPacket() = 0;
+  virtual void SetIsDecodedByPlatform(bool is_decoded_by_platform) = 0;
 
  protected:
   AppendClient() = default;
index 346e5ebfacf95bc1906f40c96491b2967ce47180..05fa9583bf80617328ef0a1165770da7b4d1f57b 100644 (file)
@@ -16,6 +16,7 @@
 #include "content/renderer/media/tizen/elementary_media_stream_source/common/common.h"
 #include "content/renderer/media/tizen/elementary_media_stream_source/common/logger.h"
 #include "content/renderer/media/tizen/elementary_media_stream_source/control_thread/demuxer_dispatcher_client.h"
+#include "content/renderer/media/tizen/elementary_media_stream_source/worker_thread/append_client.h"
 #include "content/renderer/media/tizen/elementary_media_stream_source/worker_thread/demuxer_client.h"
 #include "media/base/audio_buffer.h"
 #include "media/base/audio_decoder.h"
@@ -545,6 +546,8 @@ void MsDecodingStream::DecodingStream<StreamType>::OnDecoderInitialized(
   if constexpr (StreamType == TrackType::kVideo) {
     process_output_cb_ = parent_->GetBufferProcessorForDecoder(*decoder_);
   }
+  parent_->SetIsDecodedByPlatform(StreamType, decoder_->IsPlatformDecoder());
+
   TryProcessPendingDecodes();
 }
 
@@ -827,9 +830,11 @@ void MsDecodingStream::OnInitialConfigReady(
   }
 }
 
-void MsDecodingStream::SetAppendClient(TrackType,
-                                       std::shared_ptr<AppendClient>) {
+void MsDecodingStream::SetAppendClient(TrackType track_type,
+                                       std::shared_ptr<AppendClient> client) {
   EMSS_DEBUG();
+
+  append_clients_[+track_type] = client;
 }
 
 //////////////////// DemuxerDispatcherClient: ////////////////////
@@ -944,6 +949,19 @@ void MsDecodingStream::OnNewCreateVideoDecodersPrerequisiteAvailable() {
                                  std::move(control_task_runner)));
 }
 
+void MsDecodingStream::SetIsDecodedByPlatform(TrackType track_type,
+                                              bool is_decoded_by_platform) {
+  EMSS_VERBOSE();
+
+  auto append_client = append_clients_[+track_type].lock();
+
+  if (!append_client) {
+    return;
+  }
+
+  append_client->SetIsDecodedByPlatform(is_decoded_by_platform);
+}
+
 MsDecodingStream::ProcessVideoOutputCb
 MsDecodingStream::GetBufferProcessorForDecoder(
     const media::VideoDecoder& video_decoder) {
index 5733017851184a6825a40fc2aa22b8b03b937d71..dabdbb73194ada658c2182911a12fc44545ec308 100644 (file)
@@ -106,6 +106,7 @@ class MsDecodingStream : public Demuxer,
   void OnNewCreateAudioDecodersPrerequisiteAvailable();
   void OnNewCreateVideoDecodersPrerequisiteAvailable();
 
+  void SetIsDecodedByPlatform(TrackType, bool is_decoded_by_platform);
   ProcessVideoOutputCb GetBufferProcessorForDecoder(const media::VideoDecoder&);
   void ProcessSoftwareDecodedVideoFrame(
       scoped_refptr<media::VideoFrame> frame,
@@ -121,6 +122,9 @@ class MsDecodingStream : public Demuxer,
   media::GpuVideoAcceleratorFactories* gpu_factories_{nullptr};
   std::unique_ptr<media::MediaLog> media_log_;
 
+  std::array<std::weak_ptr<AppendClient>, (+TrackType::kMaxValue + 1)>
+      append_clients_;
+
   base::WeakPtrFactory<MsDecodingStream> weak_ptr_factory_{this};
 };
 
index a736fc20e34c5c65c160fbe626cac565623dd929..94dd7a2d1654bdce14e6e1b1e40064ae36a99e81 100644 (file)
@@ -92,6 +92,16 @@ void TrackImpl::ReadMediaPacket() {
   }
 }
 
+void TrackImpl::SetIsDecodedByPlatform(bool is_decoded_by_platform) {
+  EMSS_VERBOSE_TYPED() << is_decoded_by_platform;
+
+  if (auto dispatcher = dispatcher_.lock()) {
+    dispatcher->DispatchTask(
+        &control_thread::TrackDispatcherClient::SetIsDecodedByPlatform,
+        is_decoded_by_platform);
+  }
+}
+
 //////////////////// SourceClient ////////////////////
 
 std::shared_ptr<AppendClient> TrackImpl::GetAppendClient() {
index 3291e96e0028016221582bb4eef819bf17f963b6..159b762479c7f131a30f40120904de9234b94190 100644 (file)
@@ -37,6 +37,7 @@ class TrackImpl : public AppendClient,
   // AppendClient
   bool IsReadRequested() const override;
   void ReadMediaPacket() override;
+  void SetIsDecodedByPlatform(bool is_decoded_by_platform) override;
 
   // SourceClient
   std::shared_ptr<AppendClient> GetAppendClient() override;
index 1632718c0dd4a6e8cc2dd47cb0245bb83618d3c7..bda1411a61e676876078410e345d7eea32f925fe 100644 (file)
@@ -987,6 +987,24 @@ void ElementaryMediaStreamSource::OnTrackChanged(TrackBase*) {
   EMSS_LOG(WARNING) << "not supported in ElementaryMediaStreamSource";
 }
 
+void ElementaryMediaStreamSource::SetIsAudioDecodedByPlatform(
+    bool is_decoded_by_platform) {
+  EMSS_VERBOSE();
+
+  for (const auto& audio_track : audio_tracks_) {
+    audio_track->SetIsDecodedByPlatform(is_decoded_by_platform);
+  }
+}
+
+void ElementaryMediaStreamSource::SetIsVideoDecodedByPlatform(
+    bool is_decoded_by_platform) {
+  EMSS_VERBOSE();
+
+  for (const auto& video_track : video_tracks_) {
+    video_track->SetIsDecodedByPlatform(is_decoded_by_platform);
+  }
+}
+
 WebTimeRanges ElementaryMediaStreamSource::SeekableInternal() const {
   EMSS_VERBOSE();
 
index 54c4d2f35267052e96be90c183ee37ef81aa8eb1..41e41673a412022441463b47990eacc5a0cb6a6c 100644 (file)
@@ -151,6 +151,8 @@ class ElementaryMediaStreamSource final
   void OnResume();
   void OnSuspend();
   void OnTrackChanged(TrackBase*);
+  void SetIsAudioDecodedByPlatform(bool is_decoded_by_platform);
+  void SetIsVideoDecodedByPlatform(bool is_decoded_by_platform);
   WebTimeRanges BufferedInternal() const;
   WebTimeRanges SeekableInternal() const;
   void UpdatePlaybackPosition(double playback_position,
index b97acaf411df4c9ff14f413c659e5bf92bbda966..5abd4fbb956eeef8226fbc4e3477b9abbb198d71 100644 (file)
@@ -896,7 +896,6 @@ void ElementaryMediaTrack::recyclePicture(ElementaryVideoPicture* video_picture,
 
 const AtomicString& ElementaryMediaTrack::activeDecodingMode() const {
   EMSS_DEBUG_TYPED();
-  // FIXME(p.balut): provide the actually selected mode
   return active_decoding_mode_;
 }
 
@@ -1253,6 +1252,14 @@ media::VideoDecoderConfig ElementaryMediaTrack::CreateVideoDecoderConfig(
   return video_decoder_config;
 }
 
+void ElementaryMediaTrack::SetIsDecodedByPlatform(bool is_decoded_by_platform) {
+  EMSS_DEBUG() << is_decoded_by_platform;
+
+  active_decoding_mode_ = is_decoded_by_platform
+                              ? DecodingModeHardwareKeyword()
+                              : DecodingModeSoftwareKeyword();
+}
+
 double ElementaryMediaTrack::GetHighestBufferedPresentationTimestamp() const {
   EMSS_DEBUG_TYPED();
 
index dff44627f8ac78f21eebe6ce615c59ac38c59caf..399db2213e35b0f563921da305e510892ae9e6d6 100644 (file)
@@ -165,6 +165,7 @@ class ElementaryMediaTrack final
   void OnTrackClosed(
       WebElementaryMediaTrackControl::ChangeReason reason) override;
   void OnTrackOpen() override;
+  void SetIsDecodedByPlatform(bool is_decoded_by_platform) override;
   void Stop() override;
 
   // content::WebElementaryMediaTrackOperations::
@@ -308,7 +309,7 @@ class ElementaryMediaTrack final
 
   DOMExceptionCode ValidateGetPicturePrecondition(WebGLTexture* texture) const;
 
-  const AtomicString active_decoding_mode_;
+  AtomicString active_decoding_mode_;
 
   std::atomic<bool> append_finished_;
   std::deque<std::unique_ptr<BoundVideoTexture>> bound_video_frames_
index b7b4b461e04af0d9e39d1ac7cf066d61e61c665a..0eb6c2244f0388dc05db2a31f1f767be3535fffc 100644 (file)
@@ -215,6 +215,22 @@ void SameThreadElementaryMediaStreamSourceAttachment::OnSuspend(
   GetSource(tracer)->OnSuspend();
 }
 
+void SameThreadElementaryMediaStreamSourceAttachment::
+    SetIsAudioDecodedByPlatform(MediaSourceTracer* tracer,
+                                bool is_decoded_by_platform) {
+  EMSS_DEBUG();
+
+  GetSource(tracer)->SetIsAudioDecodedByPlatform(is_decoded_by_platform);
+}
+
+void SameThreadElementaryMediaStreamSourceAttachment::
+    SetIsVideoDecodedByPlatform(MediaSourceTracer* tracer,
+                                bool is_decoded_by_platform) {
+  EMSS_DEBUG();
+
+  GetSource(tracer)->SetIsVideoDecodedByPlatform(is_decoded_by_platform);
+}
+
 void SameThreadElementaryMediaStreamSourceAttachment::UpdatePlaybackPosition(
     MediaSourceTracer* tracer,
     double playback_position,
index d4e7819340c847c987e60fc8798bcd3ea18ff851..fcbd0671e56ce3b503eb5a746514068c21a5b081 100644 (file)
@@ -76,6 +76,12 @@ class SameThreadElementaryMediaStreamSourceAttachment final
 
   void OnSuspend(MediaSourceTracer* tracer) override;
 
+  void SetIsAudioDecodedByPlatform(MediaSourceTracer* tracer,
+                                   bool is_decoded_by_platform) override;
+
+  void SetIsVideoDecodedByPlatform(MediaSourceTracer* tracer,
+                                   bool is_decoded_by_platform) override;
+
   void UpdatePlaybackPosition(MediaSourceTracer* tracer,
                               double playback_position,
                               std::optional<uint32_t> session_id) override;
index 060a36ec392a5f154ac54ab83187a6ceb28dc550..fe69e7e2f8d00c7882a096d38ae3cd0899664511 100644 (file)
@@ -44,6 +44,7 @@ class WebElementaryMediaTrackControl
     virtual void OnSessionIdChanged(uint32_t session_id) = 0;
     virtual void OnTrackClosed(ChangeReason reason) = 0;
     virtual void OnTrackOpen() = 0;
+    virtual void SetIsDecodedByPlatform(bool is_decoded_by_platform) = 0;
     virtual void Stop() = 0;
 
    protected: