[M120 Migration][HBBTV] Implement getStartDate interface 74/308674/4
authorzhishun.zhou <zhishun.zhou@samsung.com>
Thu, 28 Mar 2024 13:14:51 +0000 (21:14 +0800)
committerBot Blink <blinkbot@samsung.com>
Fri, 29 Mar 2024 09:43:56 +0000 (09:43 +0000)
Support JS interface getStartDate(), that is used by HbbTV certification
for HTML5 video DASH tests.

Patch from:
https://review.tizen.org/gerrit/#/c/292999
https://review.tizen.org/gerrit/#/c/300457
https://review.tizen.org/gerrit/#/c/300758
https://review.tizen.org/gerrit/#/c/301571
https://review.tizen.org/gerrit/#/c/301776
https://review.tizen.org/gerrit/#/c/302497

Change-Id: Ic494eb1d8fac06a03c2004f53a02b0875b18e28b
Signed-off-by: xiaofang <fang.xiao@samsung.com>
Signed-off-by: zhishun.zhou <zhishun.zhou@samsung.com>
25 files changed:
media/base/pipeline.h
media/base/pipeline_impl.cc
media/base/pipeline_impl.h
media/base/renderer.h
media/filters/pipeline_controller.cc
media/filters/pipeline_controller.h
media/mojo/clients/mojo_renderer.cc
media/mojo/clients/mojo_renderer.h
media/mojo/clients/mojo_renderer_wrapper.cc
media/mojo/clients/mojo_renderer_wrapper.h
media/mojo/mojom/renderer.mojom
media/mojo/services/mojo_renderer_service.cc
media/mojo/services/mojo_renderer_service.h
third_party/blink/public/platform/web_media_player.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/html_media_element.idl
third_party/blink/renderer/platform/media/web_media_player_impl.cc
third_party/blink/renderer/platform/media/web_media_player_impl.h
tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc
tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h
tizen_src/chromium_impl/media/filters/media_player_bridge_capi.h
tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.cc
tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.h
tizen_src/chromium_impl/media/filters/media_player_tizen.h

index d0bbafb..233360b 100644 (file)
@@ -320,6 +320,7 @@ class MEDIA_EXPORT Pipeline {
   virtual void SetActiveAudioTrack(int index) = 0;
   virtual void SetActiveVideoTrack(int index) = 0;
   virtual void SetPreferTextLanguage(const std::string& lang) = 0;
+  virtual double GetStartDate() = 0;
   virtual void DestroyPlayerSync(base::OnceClosure cb) = 0;
 #endif
 };
index 49553d2..b33eec4 100644 (file)
@@ -40,6 +40,7 @@
 #endif  // BUILDFLAG(IS_WIN)
 
 #if BUILDFLAG(IS_TIZEN_TV)
+#include "media/base/logging_override_if_enabled.h"
 #include "media/filters/decrypting_media_resource.h"
 #endif
 
@@ -116,11 +117,13 @@ class PipelineImpl::RendererWrapper final : public DemuxerHost,
 #endif
 #if BUILDFLAG(IS_TIZEN_TV)
   void SetContentMimeType(const std::string& mime_type);
+  void WaitSignal();
   void SetParentalRatingResult(bool is_pass);
   void SetActiveTextTrack(int id, bool is_in_band);
   void SetActiveAudioTrack(int index);
   void SetActiveVideoTrack(int index);
   void SetPreferTextLanguage(const std::string& lang);
+  double GetStartDate();
   void DestroyPlayerSync(base::OnceClosure cb);
 #endif
 
@@ -235,6 +238,8 @@ class PipelineImpl::RendererWrapper final : public DemuxerHost,
   // Create decrypting media resource
   void CreateAndInitializeDecryptingMediaResource();
   void OnDecryptInitDone(bool success);
+  void RequestStartDate();
+  void StartDateCB(double start_date);
 #endif
 
   // Returns whether there's any encrypted stream in the demuxer.
@@ -294,7 +299,10 @@ class PipelineImpl::RendererWrapper final : public DemuxerHost,
 #endif
 
 #if BUILDFLAG(IS_TIZEN_TV)
+  base::WaitableEvent sync_with_worker_task_runner_{
+      base::WaitableEvent::ResetPolicy::AUTOMATIC};
   std::string mime_type_;
+  double start_date_{std::numeric_limits<double>::quiet_NaN()};
   std::unique_ptr<DecryptingMediaResource> decrypting_media_resource_{nullptr};
   base::OnceClosure player_destroy_cb_;
 #endif
@@ -717,6 +725,11 @@ void PipelineImpl::RendererWrapper::SetContentMimeType(
     shared_state_.renderer->SetContentMimeType(mime_type_);
 }
 
+void PipelineImpl::RendererWrapper::WaitSignal() {
+  LOG(INFO) << "Signal the sync_with_worker_task_runner_";
+  sync_with_worker_task_runner_.Signal();
+}
+
 void PipelineImpl::RendererWrapper::SetParentalRatingResult(bool is_pass) {
   DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
@@ -792,6 +805,32 @@ void PipelineImpl::RendererWrapper::
       base::BindRepeating(&RendererWrapper::OnWaiting,
                           weak_factory_.GetWeakPtr()));
 }
+
+void PipelineImpl::RendererWrapper::RequestStartDate() {
+  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  if (shared_state_.renderer) {
+    shared_state_.renderer->GetStartDate(base::BindOnce(
+        &RendererWrapper::StartDateCB, weak_factory_.GetWeakPtr()));
+  } else {
+    LOG(ERROR) << "No shared_state_.renderer!";
+    WaitSignal();
+  }
+}
+
+double PipelineImpl::RendererWrapper::GetStartDate() {
+  media_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&RendererWrapper::RequestStartDate,
+                                weak_factory_.GetWeakPtr()));
+  sync_with_worker_task_runner_.Wait();
+  return start_date_;
+}
+
+void PipelineImpl::RendererWrapper::StartDateCB(double start_date) {
+  DVLOG(1) << __func__;
+  start_date_ = start_date;
+  WaitSignal();
+}
+
 void PipelineImpl::RendererWrapper::DestroyPlayerSync(base::OnceClosure cb) {
   DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   LOG(INFO) << "(" << static_cast<void*>(this) << ") ;" << __func__;
@@ -2101,6 +2140,12 @@ void PipelineImpl::AddTrackInfo(media::MediaTrackInfo trackinfo) {
   DCHECK(client_);
   client_->AddTrackInfo(std::move(trackinfo));
 }
+
+double PipelineImpl::GetStartDate() {
+  DVLOG(2) << __func__;
+  DCHECK(thread_checker_.CalledOnValidThread());
+  return renderer_wrapper_->GetStartDate();
+}
 #endif
 
 void PipelineImpl::OnDurationChange(base::TimeDelta duration) {
index dfe55b6..e6de104 100644 (file)
@@ -183,6 +183,7 @@ class MEDIA_EXPORT PipelineImpl : public Pipeline {
   void SetActiveAudioTrack(int index) override;
   void SetActiveVideoTrack(int index) override;
   void SetPreferTextLanguage(const std::string& lang) override;
+  double GetStartDate() override;
   void DestroyPlayerSync(base::OnceClosure cb) override;
 #endif
   void OnBufferingStateChange(BufferingState state,
index 6884f6a..133476d 100644 (file)
@@ -107,6 +107,7 @@ class MEDIA_EXPORT Renderer {
   virtual void SetMediaGeometry(const gfx::RectF& rect) {}
 #endif
 
+  using StartDateCB = base::OnceCallback<void(double)>;
 #if BUILDFLAG(IS_TIZEN_TV)
   virtual void SetContentMimeType(const std::string& mime_type) {}
   virtual void SetParentalRatingResult(bool is_pass) {}
@@ -114,6 +115,7 @@ class MEDIA_EXPORT Renderer {
   virtual void SetActiveAudioTrack(int index) {}
   virtual void SetActiveVideoTrack(int index) {}
   virtual void SetPreferTextLanguage(const std::string& lang) {}
+  virtual void GetStartDate(StartDateCB cb) {}
   virtual void DestroyPlayerSync(base::OnceClosure cb) {}
 #endif
 
index 1128216..cc03a33 100644 (file)
@@ -522,6 +522,14 @@ void PipelineController::SetPreferTextLanguage(const std::string& lang) {
   pipeline_->SetPreferTextLanguage(lang);
 }
 
+double PipelineController::GetStartDate() const {
+  if (pipeline_)
+    return pipeline_->GetStartDate();
+
+  LOG(ERROR) << "pipeline_ is null";
+  return std::numeric_limits<double>::quiet_NaN();
+}
+
 void PipelineController::DestroyPlayerSync(base::OnceClosure cb) {
   if (pipeline_) {
     pipeline_->DestroyPlayerSync(std::move(cb));
index 6e678c1..383d166 100644 (file)
@@ -170,6 +170,7 @@ class MEDIA_EXPORT PipelineController {
   void SetActiveAudioTrack(int index);
   void SetActiveVideoTrack(int index);
   void SetPreferTextLanguage(const std::string& lang);
+  double GetStartDate() const;
   void DestroyPlayerSync(base::OnceClosure cb);
 #endif
  private:
index 4f4f7f2..148a8b3 100644 (file)
@@ -401,6 +401,20 @@ void MojoRenderer::SetPreferTextLanguage(const std::string& lang) {
   remote_renderer_->SetPreferTextLanguage(lang);
 }
 
+void MojoRenderer::GetStartDate(StartDateCB cb) {
+  DVLOG(2) << __func__;
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
+  if (!remote_renderer_.is_bound()) {
+    LOG(ERROR) << "remote_renderer is not bound";
+    double start_date = std::numeric_limits<double>::quiet_NaN();
+    std::move(cb).Run(start_date);
+    return;
+  }
+
+  remote_renderer_->GetStartDate(std::move(cb));
+}
+
 void MojoRenderer::DestroyPlayerSync(base::OnceClosure cb) {
   DVLOG(2) << __func__;
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
index 53c9754..8ae441e 100644 (file)
@@ -83,6 +83,7 @@ class MojoRenderer : public Renderer, public mojom::RendererClient {
   void SetActiveAudioTrack(int index) override;
   void SetActiveVideoTrack(int index) override;
   void SetPreferTextLanguage(const std::string& lang) override;
+  void GetStartDate(StartDateCB cb) override;
   void DestroyPlayerSync(base::OnceClosure cb) override;
 #endif
 
index 548e650..f5dee67 100644 (file)
@@ -112,6 +112,15 @@ void MojoRendererWrapper::SetPreferTextLanguage(const std::string& lang) {
     mojo_renderer_->SetPreferTextLanguage(lang);
 }
 
+void MojoRendererWrapper::GetStartDate(StartDateCB cb) {
+  if (!mojo_renderer_) {
+    LOG(ERROR) << "mojo_renderer_ is null";
+    double start_date = std::numeric_limits<double>::quiet_NaN();
+    std::move(cb).Run(start_date);
+  }
+  mojo_renderer_->GetStartDate(std::move(cb));
+}
+
 void MojoRendererWrapper::DestroyPlayerSync(base::OnceClosure cb) {
   if (mojo_renderer_) {
     mojo_renderer_->DestroyPlayerSync(std::move(cb));
index 719b0e1..4bf07fe 100644 (file)
@@ -49,12 +49,14 @@ class MojoRendererWrapper : public Renderer {
 #endif
 
 #if BUILDFLAG(IS_TIZEN_TV)
+  using StartDateCB = base::OnceCallback<void(double)>;
   void SetContentMimeType(const std::string& mime_type) override;
   void SetParentalRatingResult(bool is_pass) override;
   void SetActiveTextTrack(int id, bool is_in_band) override;
   void SetActiveVideoTrack(int index) override;
   void SetActiveAudioTrack(int index) override;
   void SetPreferTextLanguage(const std::string& lang) override;
+  void GetStartDate(StartDateCB cb) override;
   void DestroyPlayerSync(base::OnceClosure cb) override;
 #endif
 
index 7c83186..b6aaaf0 100644 (file)
@@ -87,6 +87,9 @@ interface Renderer {
   SetPreferTextLanguage(string lang);
 
   [EnableIf=is_tizen_tv]
+  GetStartDate()=> (double start_date);
+
+  [EnableIf=is_tizen_tv]
   DestroyPlayerSync() => ();
 };
 
index 43333c8..4d011ad 100644 (file)
@@ -260,6 +260,17 @@ void MojoRendererService::SetPreferTextLanguage(const std::string& lang) {
   renderer_->SetPreferTextLanguage(lang);
 }
 
+void MojoRendererService::GetStartDate(GetStartDateCallback cb) {
+  DVLOG(3) << __func__;
+  if (renderer_) {
+    renderer_->GetStartDate(std::move(cb));
+  } else {
+    LOG(ERROR) << "renderer_ is null";
+    double start_date = std::numeric_limits<double>::quiet_NaN();
+    std::move(cb).Run(start_date);
+  }
+}
+
 void MojoRendererService::OnPlayerDestroyed(base::OnceClosure destroy_cb) {
   LOG(INFO) << "OnPlayerDestroyed";
   std::move(destroy_cb).Run();
index 0dda352..c4ced5f 100644 (file)
@@ -89,6 +89,7 @@ class MEDIA_MOJO_EXPORT MojoRendererService final : public mojom::Renderer,
   void SetActiveAudioTrack(int index) final;
   void SetActiveVideoTrack(int index) final;
   void SetPreferTextLanguage(const std::string& lang) final;
+  void GetStartDate(GetStartDateCallback cb) final;
   void DestroyPlayerSync(base::OnceClosure destroy_cb) final;
 #endif
 
index 9dbf24f..04e4980 100644 (file)
@@ -413,6 +413,9 @@ class WebMediaPlayer {
   virtual void SetActiveAudioTrack(int) {}
   virtual void SetActiveVideoTrack(int) {}
   virtual void SetPreferTextLanguage(const std::string&) {}
+  virtual double GetStartDate() const {
+    return std::numeric_limits<double>::quiet_NaN();
+  }
 #endif
 };
 
index 8ff57d2..54dd800 100644 (file)
@@ -4499,6 +4499,16 @@ void HTMLMediaElement::SetPreferTextLang(const String& lang) {
     GetWebMediaPlayer()->SetPreferTextLanguage(prefer_text_lang_);
 }
 #endif
+double HTMLMediaElement::getStartDate() const {
+#if BUILDFLAG(IS_TIZEN_TV)
+  if (!IsHbbTV() || !GetWebMediaPlayer()) {
+    return std::numeric_limits<double>::quiet_NaN();
+  }
+  return GetWebMediaPlayer()->GetStartDate();
+#else
+  return std::numeric_limits<double>::quiet_NaN();
+#endif
+}
 
 bool HTMLMediaElement::HasPendingActivity() const {
   const auto result = HasPendingActivityInternal();
index 6a5a2b2..c957a9e 100644 (file)
@@ -253,6 +253,7 @@ class CORE_EXPORT HTMLMediaElement
   void SetLoop(bool);
   ScriptPromise playForBindings(ScriptState*);
   absl::optional<DOMExceptionCode> Play();
+  double getStartDate() const;
 
   // Called when the video should pause to let audio descriptions finish.
   void PauseToLetDescriptionFinish();
index 1fa8a06..d85635c 100644 (file)
@@ -63,7 +63,7 @@ enum CanPlayTypeResult { "" /* empty string */, "maybe", "probably" };
     attribute double currentTime;
     // FIXME: void fastSeek(double time);
     readonly attribute unrestricted double duration;
-    // FIXME: Date getStartDate(); crbug.com/312699
+    double getStartDate(); // for hbbtv
     readonly attribute boolean paused;
     attribute double defaultPlaybackRate;
     [RaisesException=Setter] attribute double playbackRate;
index 2e8bdd1..1542bc1 100644 (file)
@@ -2525,6 +2525,10 @@ void WebMediaPlayerImpl::AddTrackInfo(media::MediaTrackInfo trackinfo) {
     delete (pInbandCue);
   }
 }
+
+double WebMediaPlayerImpl::GetStartDate() const {
+  return pipeline_controller_->GetStartDate();
+}
 #endif
 
 void WebMediaPlayerImpl::OnDurationChange() {
index 834286d..78f9847 100644 (file)
@@ -331,6 +331,10 @@ class PLATFORM_EXPORT WebMediaPlayerImpl
     return is_background_suspend_enabled_;
   }
 
+#if BUILDFLAG(IS_TIZEN_TV)
+  double GetStartDate() const override;
+#endif
+
   // Distinct states that |delegate_| can be in. (Public for testing.)
   enum class DelegateState {
     GONE,
index 53c0d5a..7278fa9 100644 (file)
@@ -577,6 +577,15 @@ void TizenRendererImpl::SetParentalRatingResult(bool is_pass) {
     LOG_ID(ERROR, player_id_) << "media_player_ is null";
 }
 
+void TizenRendererImpl::GetStartDate(StartDateCB cb) {
+  double start_date = std::numeric_limits<double>::quiet_NaN();
+  if (media_player_)
+    start_date = media_player_->GetStartDate();
+  else
+    LOG_ID(ERROR, player_id_) << "media_player_ is nullptr";
+  std::move(cb).Run(start_date);
+}
+
 void TizenRendererImpl::DestroyPlayerSync(base::OnceClosure destroy_cb) {
   if (media_player_) {
     media::MediaPlayerRegistry::GetInstance()->DeactivateMediaPlayer(
index bc29db0..e45d45a 100644 (file)
@@ -159,6 +159,7 @@ class CONTENT_EXPORT TizenRendererImpl
 #if BUILDFLAG(IS_TIZEN_TV)
   void SetContentMimeType(const std::string& mime_type) override;
   void SetParentalRatingResult(bool is_pass) override;
+  void GetStartDate(StartDateCB cb) override;
   void DestroyPlayerSync(base::OnceClosure destroy_cb) override;
 #endif
 
index c5a748b..1e3ed05 100644 (file)
@@ -88,6 +88,9 @@ class MEDIA_EXPORT MediaPlayerBridgeCapi : public MediaPlayerTizen {
   void SetMediaPlayerClient(MediaPlayerTizenClient* client) override {
     client_ = client;
   }
+  double GetStartDate() override {
+    return std::numeric_limits<double>::quiet_NaN();
+  };
   void SetParentalRatingResult(bool is_pass) override {}
 
 #if defined(TIZEN_VIDEO_HOLE)
index 9173530..2d979d1 100644 (file)
@@ -1985,4 +1985,49 @@ void MediaPlayerBridgeCapiTV::SetPreferTextLanguage(const std::string& lang) {
                            << prefer_subtitle_language.c_str();
   player_set_ini_param(player_, prefer_subtitle_language.c_str());
 }
+
+std::string MediaPlayerBridgeCapiTV::ParseDashKeyword(
+    const std::string& keyword) {
+  std::string dash_info = GetDashInfo();
+  Json::CharReaderBuilder builder;
+  Json::CharReader* reader(builder.newCharReader());
+  Json::Value value;
+  std::string valueForKey;
+
+  if (reader->parse(dash_info.c_str(), dash_info.c_str() + dash_info.length(),
+                    &value, nullptr)) {
+    valueForKey = value[keyword].asString();
+    LOG_ID(INFO, player_id_)
+        << "keyword: " << keyword << ",valueForKey:" << valueForKey;
+    return valueForKey;
+  }
+  return "";
+}
+
+double MediaPlayerBridgeCapiTV::GetStartDate() {
+  int64_t millisecond = 0;
+  int ret = player_get_start_date(player_, &millisecond);
+  if (ret != PLAYER_ERROR_NONE) {
+    /* In case of invalid state try to use player_get_dash_info()
+     and parse it for availabilityStartTime -legacy hack*/
+    if (ret == PLAYER_ERROR_INVALID_STATE) {
+      const std::string start_date_keyword = "availabilityStartTime";
+      std::string start_date = ParseDashKeyword(start_date_keyword);
+      LOG_ID(ERROR, player_id_) << "from ParseDashKeyword: " << start_date;
+      if (!start_date.empty()) {
+        double start_date_ret = 0.0;
+        std::stringstream ss;
+        ss << start_date;
+        ss >> start_date_ret;
+        OnHandlePlayerError(ret, FROM_HERE);
+        return start_date_ret;
+      }
+    }
+    OnHandlePlayerError(ret, FROM_HERE);
+    LOG_ID(ERROR, player_id_) << "player_get_start_date fail,ret:" << ret;
+    return std::numeric_limits<double>::quiet_NaN();
+  }
+
+  return static_cast<double>(millisecond);
+}
 }  // namespace media
index dc78210..08df00e 100644 (file)
@@ -94,6 +94,8 @@ class MEDIA_EXPORT MediaPlayerBridgeCapiTV : public MediaPlayerBridgeCapi {
                      int media_position);
 
 #endif
+  double GetStartDate() override;
+
  protected:
   void PlayerPrepared() override;
 
@@ -148,6 +150,7 @@ class MEDIA_EXPORT MediaPlayerBridgeCapiTV : public MediaPlayerBridgeCapi {
   void GetAdaptiveStreamingInfo();
   void UpdateSeekableTime();
   void ParseDashInfo();
+  std::string ParseDashKeyword(const std::string& keyword);
   bool GetLiveStreamingDuration(int64_t* min, int64_t* max);
   bool GetDashLiveDuration(int64_t* duration);
   std::string GetDashInfo();
index 0fbfcb6..3caf276 100644 (file)
@@ -116,6 +116,9 @@ class MEDIA_EXPORT MediaPlayerTizen {
   virtual void SetActiveVideoTrack(int index) {}
   virtual void SetPreferTextLanguage(const std::string& lang) {}
   virtual void UpdateEventData(std::string data) {}
+  virtual double GetStartDate() {
+    return std::numeric_limits<double>::quiet_NaN();
+  }
 #if BUILDFLAG(IS_TIZEN_TV)
   virtual void DestroyPlayerSync(base::OnceClosure destroy_cb) {}
 #endif