Fix drop buffer when SetPlaybackRate() 78/301278/8
authorGilbok Lee <gilbok.lee@samsung.com>
Mon, 13 Nov 2023 08:37:00 +0000 (17:37 +0900)
committerGilbok Lee <gilbok.lee@samsung.com>
Mon, 27 Nov 2023 01:30:00 +0000 (10:30 +0900)
- when a segment event is sent, a buffer drop occurs in the decoder
  due to the qos event

Change-Id: I74c929fe6c0b86f56484880aaea2a9f0d4a0477a

packaging/libtrackrenderer.spec
src/include_internal/trackrenderer/core/pipeline.hpp
src/trackrenderer.cpp

index c48efb8613331b53b80ed440198d8264720417b7..5d1304f8b2fc6b0082fcf05aea698d6221e10222 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libtrackrenderer
 Summary:    new multimedia streaming player trackrenderer
-Version:    0.0.48
+Version:    0.0.49
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index 2812505981bffda2dbcace34f239c294714515ab..28140de0ffcf3df99d11acdeb07a4952ec612d62 100644 (file)
@@ -456,6 +456,20 @@ class Pipeline : private boost::noncopyable {
     return true;
   }
 
+  bool PushInstantRateChangeEvent(T type, gdouble rate, GstSegmentFlags flags) {
+    GstElement* obj = mainbin_[static_cast<int>(type)];
+    if (!obj) return false;
+    auto pad = gstguard::make_guard(gst_element_get_static_pad(obj, "src"));
+    auto peer_pad = GST_PAD_PEER(pad.get());
+
+    if (!gst_pad_send_event(peer_pad,
+        gst_event_new_instant_rate_change(rate, flags))) {
+      TRACKRENDERER_ERROR("Fail to send instant rate change event");
+      return false;
+    }
+    return true;
+  }
+
   bool AppSrcPushBuffer(T type, GstBuffer* buffer) {
     int index = static_cast<int>(type);
     GstElement* obj = mainbin_[index];
index 0fec0db806484eb2b5b3f413804b9962ff3d56fe..c8d753e66ac77c83d07cf35d77f97426787b055d 100644 (file)
@@ -776,62 +776,25 @@ bool TrackRenderer::SetPlaybackRate(double playback_rate, bool audio_mute) {
   if (state_ == State::kStopped) return false;
   if (!pipeline_) return false;
 
-  uint64_t curtime_in_msec = 0;
-
-  GetPlayingTime_(&curtime_in_msec);
-
   TRACKRENDERER_INFO("Set audio mute property as [%d], rate [%lf]", audio_mute,
                      playback_rate);
-  auto is_audio_track = [](const Track& item) noexcept -> bool {
-    return item.mimetype.find("audio") != std::string::npos;
-  };
-  auto target = find_if(trackinfo_.begin(), trackinfo_.end(), is_audio_track);
-  if (target != trackinfo_.end())
-    pipeline_->SetProperty(Elements::kSinkAudio, "mute", audio_mute);
 
-  Elements audio_probe_element = Elements::kDecAudio;
-  Elements video_probe_element = Elements::kDecVideo;
-  Elements subtitle_probe_element = Elements::kAppSrcSubtitle;
-  Elements close_caption_probe_element = Elements::kQueueCaption;
-
-  std::map<Elements, std::pair<std::string, std::string>> probe_map = {
-      {audio_probe_element,
-       {"AUDIO_RATE_IDLE_PROBE", "AUDIO_RATE_BLOCK_PROBE"}},
-      {video_probe_element,
-       {"VIDEO_RATE_IDLE_PROBE", "VIDEO_RATE_BLOCK_PROBE"}},
-      {subtitle_probe_element,
-       {"SUBTITLE_RATE_IDLE_PROBE", "SUBTITLE_RATE_BLOCK_PROBE"}},
-      {close_caption_probe_element,
-       {"CLOSE_CAPTION_RATE_IDLE_PROBE", "CLOSE_CAPTION_RATE_BLOCK_PROBE"}}};
-
-  std::map<Elements, Elements> probe_sink_map = {
-      {audio_probe_element, Elements::kSinkAudio},
-      {video_probe_element, Elements::kSinkVideo},
-      {subtitle_probe_element, Elements::kSinkSubtitle},
-      {close_caption_probe_element, Elements::kSinkCaption}};
-
-  for (auto& kv : probe_map) {
-    const Elements& element = kv.first;
-    std::pair<std::string, std::string>& probe = kv.second;
-    pipeline_->PadAddProbe(element, (probe.second).c_str(), "src",
-                           GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, nullptr,
-                           nullptr, nullptr);
-    gboolean is_sync = FALSE;
-    pipeline_->GetProperty(probe_sink_map[element], "sync", &is_sync);
-    pipeline_->SetProperty(probe_sink_map[element], "sync", FALSE);
-    FlushDownStream_(element, (probe.first).c_str(), TRUE);
-    if (is_sync) pipeline_->SetProperty(probe_sink_map[element], "sync", TRUE);
-  }
+  if (find_if(trackinfo_.begin(), trackinfo_.end(),
+            [](const Track& item) {
+              return item.mimetype.find("audio") != std::string::npos;
+            }) != trackinfo_.end())
+    pipeline_->SetProperty(Elements::kSinkAudio, "mute", audio_mute);
 
-  TRACKRENDERER_INFO("target %" PRIu64 " ms  rate [%lf]  mute [%d]", curtime_in_msec,
-                     playback_rate, audio_mute);
+  std::vector<Elements> targetElements {
+    Elements::kDecAudio,
+    Elements::kDecVideo,
+    Elements::kAppSrcSubtitle,
+    Elements::kQueueCaption
+  };
 
-  for (auto& kv : probe_map) {
-    const Elements& element = kv.first;
-    std::pair<std::string, std::string>& probe = kv.second;
-    pipeline_->PushSegmentEvent(element, curtime_in_msec * GST_MSECOND,
-                                playback_rate);
-    pipeline_->PadRemoveProbe((probe.second).c_str());
+  for (const auto& element : targetElements) {
+    pipeline_->PushInstantRateChangeEvent(element, playback_rate,
+            (GstSegmentFlags)GST_SEGMENT_INSTANT_FLAGS);
   }
 
   playback_rate_ = playback_rate;