[EMSS] Fix crash during low latency suspend/resume 39/315939/2
authorPiotr Bałut <p.balut@samsung.com>
Tue, 3 Dec 2024 16:18:24 +0000 (17:18 +0100)
committerBot Blink <blinkbot@samsung.com>
Fri, 6 Dec 2024 10:46:29 +0000 (10:46 +0000)
[PROBLEM]
When suspend happens, decoder should be removed and recreated when app
resumes. Furthermore some MsDecodingStream methods are not properly
plumbed to classes in layers that receive suspend/resume notifications.

[SOLUTION]
Destroy decoder upon suspend and recreate it when app resumes.
Additionally all suspend/resume notifications are not properly delivered
to MsDecodingStream.

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

tizen_src/chromium_impl/content/renderer/media/tizen/elementary_media_stream_source/control_thread/ms_decoding_stream.cc
tizen_src/chromium_impl/content/renderer/media/tizen/elementary_media_stream_source/worker_thread/ms_decoding_stream.cc

index ea0861e3f8bc00e7f789af8f41be1158dd065172..b0bb8656b026a4700efa6acbd263d1c7f7b0732d 100644 (file)
@@ -4,9 +4,9 @@
 
 #include "content/renderer/media/tizen/elementary_media_stream_source/control_thread/ms_decoding_stream.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_client.h"
 #include "content/renderer/media/tizen/elementary_media_stream_source/worker_thread/demuxer_dispatcher_client.h"
-#include "content/renderer/media/tizen/elementary_media_stream_source/common/logger.h"
 
 namespace content::elementary_media_stream_source::control_thread {
 
@@ -33,14 +33,29 @@ void MsDecodingStream::OnDemuxerSeekDone(base::TimeDelta, uint32_t session_id) {
 void MsDecodingStream::OnPipelineClosed() {
   EMSS_DEBUG();
 
-  if (auto demuxer_dispatcher = dispatcher_.lock())
+  if (auto demuxer_dispatcher = dispatcher_.lock()) {
     demuxer_dispatcher->DispatchTask(
         &worker_thread::DemuxerDispatcherClient::OnPipelineClosed);
+  }
 }
 
-void MsDecodingStream::OnPipelineResuming() {}
+void MsDecodingStream::OnPipelineResuming() {
+  EMSS_DEBUG();
 
-void MsDecodingStream::OnPipelineSuspended() {}
+  if (auto demuxer_dispatcher = dispatcher_.lock()) {
+    demuxer_dispatcher->DispatchTask(
+        &worker_thread::DemuxerDispatcherClient::OnPipelineResuming);
+  }
+}
+
+void MsDecodingStream::OnPipelineSuspended() {
+  EMSS_DEBUG();
+
+  if (auto demuxer_dispatcher = dispatcher_.lock()) {
+    demuxer_dispatcher->DispatchTask(
+        &worker_thread::DemuxerDispatcherClient::OnPipelineSuspended);
+  }
+}
 
 void MsDecodingStream::SetDuration(base::TimeDelta) {}
 
@@ -55,15 +70,22 @@ void MsDecodingStream::OnPlayerError(BackendError error,
                                      base::OnceClosure on_error_reported) {
   EMSS_DEBUG() << error << ", message = " << message;
 
-  if (auto client = client_.lock())
+  if (auto client = client_.lock()) {
     client->OnPlayerError(error, message);
+  }
 
   // We're on control thread and we can safely assume that the error was already
   // reported to JS after the client call above.
   std::move(on_error_reported).Run();
 }
 
-void MsDecodingStream::OnResumeComplete() {}
+void MsDecodingStream::OnResumeComplete() {
+  EMSS_DEBUG();
+
+  if (auto client = client_.lock()) {
+    client->OnResumeComplete();
+  }
+}
 
 //////////////////// PlatformDemuxerAdapterClient ////////////////////
 
index 05fa9583bf80617328ef0a1165770da7b4d1f57b..765a6bf8bfc54f9ead982826f2e1d003e716e0f3 100644 (file)
@@ -285,6 +285,9 @@ class MsDecodingStream::DecodingStream {
                  std::shared_ptr<Sink> sink);
   ~DecodingStream();
 
+  void Resume();
+  void Suspend();
+
   void DecodeFrames(std::vector<Packet> frames);
   void ResetSink();
 
@@ -355,6 +358,30 @@ MsDecodingStream::DecodingStream<StreamType>::~DecodingStream() {
   EMSS_DEBUG_TYPED() << "Destructing object";
 }
 
+template <TrackType StreamType>
+void MsDecodingStream::DecodingStream<StreamType>::Resume() {
+  EMSS_LOG_TYPED(INFO);
+
+  if (!config_.IsValidConfig()) {
+    return;
+  }
+
+  StartInitializingDecoder(config_);
+}
+
+template <TrackType StreamType>
+void MsDecodingStream::DecodingStream<StreamType>::Suspend() {
+  EMSS_LOG_TYPED(INFO);
+
+  DestroyCurrentDecoder();
+
+  while (!pending_decodes_.empty()) {
+    EMSS_LOG_TYPED(VERBOSE)
+        << "Flushing: " << pending_decodes_.front()->AsHumanReadableString();
+    pending_decodes_.pop();
+  }
+}
+
 template <TrackType StreamType>
 void MsDecodingStream::DecodingStream<StreamType>::DecodeFrames(
     std::vector<Packet> frames) {
@@ -850,9 +877,35 @@ void MsDecodingStream::OnPipelineClosed() {
   }
 }
 
-void MsDecodingStream::OnPipelineResuming() {}
+void MsDecodingStream::OnPipelineResuming() {
+  EMSS_LOG(INFO);
 
-void MsDecodingStream::OnPipelineSuspended() {}
+  if (audio_stream_) {
+    audio_stream_->Resume();
+  }
+  if (video_stream_) {
+    video_stream_->Resume();
+  }
+
+  if (auto dispatcher = dispatcher_.lock()) {
+    dispatcher->DispatchTask(
+        &control_thread::DemuxerDispatcherClient::OnResumeComplete);
+  }
+}
+
+void MsDecodingStream::OnPipelineSuspended() {
+  EMSS_LOG(INFO);
+
+  if (audio_stream_) {
+    audio_stream_->Suspend();
+  }
+  if (video_stream_) {
+    video_stream_->Suspend();
+  }
+  if (gmb_pool_) {
+    gmb_pool_.reset();
+  }
+}
 
 void MsDecodingStream::OnReadRequested(TrackType) {}
 
@@ -991,7 +1044,12 @@ void MsDecodingStream::ProcessSoftwareDecodedVideoFrame(
     scoped_refptr<media::VideoFrame> frame,
     VideoOutputProcessedCb on_frame_processed) {
   EMSS_VERBOSE();
-  EMSS_LOG_ASSERT(gmb_pool_);
+
+  if (!gmb_pool_) {
+    EMSS_DEBUG() << "GMB pool was deleted, discarding "
+                 << frame->timestamp().InMilliseconds();
+    return;
+  }
 
   gmb_pool_->MaybeCreateHardwareFrame(std::move(frame),
                                       std::move(on_frame_processed));