acquire hw resource before make element 62/300562/5 accepted/tizen/unified/20231030.145734
authorEunhye Choi <eunhae1.choi@samsung.com>
Fri, 27 Oct 2023 06:40:04 +0000 (15:40 +0900)
committerEunhye Choi <eunhae1.choi@samsung.com>
Fri, 27 Oct 2023 11:12:38 +0000 (20:12 +0900)
- acquire hw resource before make hw element
- clear trackinfo in case of error during activate

[Version] 0.0.47

Change-Id: Ic898b9efde4d9f69ff9727a9ac01aa3716f4c56e

packaging/libtrackrenderer.spec
src/trackrenderer.cpp

index a45a55f27f385b5c74151f866a2af76bd2f65a21..746ac057983d9906c7598c7986ccbf0b2ce2ad07 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libtrackrenderer
 Summary:    new multimedia streaming player trackrenderer
-Version:    0.0.46
+Version:    0.0.47
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index e417ba9fd4d84147b7083b874389d89c9e064987..0fec0db806484eb2b5b3f413804b9962ff3d56fe 100644 (file)
@@ -540,12 +540,7 @@ bool TrackRenderer::Prepare() {
   }
 
   if (!CreatePipeline_()) {
-    TRACKRENDERER_ERROR("renderer pipeline creation failed");
-    return false;
-  }
-
-  if (!GetResource_()) {
-    TRACKRENDERER_ERROR("resource acquire failed");
+    TRACKRENDERER_ERROR("Failed to create pipeline");
     ReleaseResource_();
     return false;
   }
@@ -1031,7 +1026,15 @@ bool TrackRenderer::CreateDecoder_(const Track* track, const GstCaps* caps) {
     element = Elements::kDecVideo;
     if (internal::GetIniValue(properties_, "use_default_video_codec_sw"))
       factory_type &= ~GST_ELEMENT_FACTORY_TYPE_HARDWARE;
+    if (factory_type & GST_ELEMENT_FACTORY_TYPE_HARDWARE) {
+      std::list<ResourceProperty> properties {{ ResourceCategory::kVideoDecoder, *track }};
+      if (!resource_manager_->Acquire(properties)) {
+        TRACKRENDERER_ERROR("Failed to acquire video hw decoder resource");
+        return false;
+      }
+    }
   } else if (track->type == kTrackTypeAudio) {
+    /* FIXME: need to acquire audio hw resource if audio hw dec is supported */
     element = Elements::kDecAudio;
   } else {
     TRACKRENDERER_ERROR("Invalid track type %d", track->type);
@@ -1040,6 +1043,10 @@ bool TrackRenderer::CreateDecoder_(const Track* track, const GstCaps* caps) {
 
   if (!pipeline_->FactoryMake(element, caps, factory_type, NULL)) {
     TRACKRENDERER_ERROR("Failed to make decoder");
+    if ((track->type == kTrackTypeVideo) &&
+        (factory_type & GST_ELEMENT_FACTORY_TYPE_HARDWARE) &&
+        (!resource_manager_->Release(ResourceCategory::kVideoDecoder)))
+      TRACKRENDERER_ERROR("failed to release video hw decoder resources");
     return false;
   }
 
@@ -1057,13 +1064,21 @@ bool TrackRenderer::CreateVideoSink_(const Track* track) {
   DisplayType display_type;
   display_->GetDisplay(&display_type);
 
-  const char* videosink_name = [&] {
-     return internal::IsDisplayNeeded(display_type) ?
-             kVideoSinkName : "fakesink";
-  }();
+  const char* videosink_name = "fakesink";
+  if (internal::IsDisplayNeeded(display_type)) {
+    videosink_name = kVideoSinkName;
+    std::list<ResourceProperty> properties {{ ResourceCategory::kVideoRenderer, {} }};
+    if (!resource_manager_->Acquire(properties)) {
+      TRACKRENDERER_ERROR("Failed to acquire video hw renderer resource");
+      return false;
+    }
+  }
 
   if (!pipeline_->FactoryMake(Elements::kSinkVideo, videosink_name, nullptr)) {
     TRACKRENDERER_ERROR("Failed to create video sink");
+    if ((internal::IsDisplayNeeded(display_type)) &&
+        (!resource_manager_->Release(ResourceCategory::kVideoRenderer)))
+      TRACKRENDERER_ERROR("failed to release video hw renderer resources");
     return false;
   }
 
@@ -1410,36 +1425,6 @@ bool TrackRenderer::CreatePipeline_() {
   return true;
 }
 
-bool TrackRenderer::GetResource_() {
-  assert(!trackinfo_.empty());
-  std::list<ResourceProperty> properties;
-
-  Track track;
-  if (!track_util::GetActiveTrack(trackinfo_, kTrackTypeVideo, &track)) {
-    TRACKRENDERER_ERROR("There is no active video track");
-    return true;
-  }
-
-  if (pipeline_->IsFactoryListType(Elements::kDecVideo,
-        GST_ELEMENT_FACTORY_TYPE_HARDWARE)) {
-    TRACKRENDERER_DEBUG("will get video decoder resource");
-    properties.push_back({ ResourceCategory::kVideoDecoder, track });
-  }
-
-  DisplayType display_type;
-  display_->GetDisplay(&display_type);
-  if (internal::IsDisplayNeeded(display_type)) {
-    TRACKRENDERER_DEBUG("will get video renderer resource");
-    properties.push_back({ ResourceCategory::kVideoRenderer, {} });
-  }
-
-  bool ret = resource_manager_->Acquire(properties);
-  if (!ret)
-    TRACKRENDERER_ERROR("GetResource_ Fail");
-
-  return ret;
-}
-
 void TrackRenderer::SetDefaultAttributeValue_() {
   for (auto& kv : kAttributes_) {
     const Attribute& attr = kv.first;
@@ -1453,11 +1438,8 @@ bool TrackRenderer::ReleaseResource_() {
   TRACKRENDERER_ENTER;
   pipeline_.reset();
 
-  if (!resource_manager_->Release(ResourceCategory::kVideoDecoder))
-    TRACKRENDERER_ERROR("failed to release Decoder resources");
-
-  if (!resource_manager_->Release(ResourceCategory::kVideoRenderer))
-    TRACKRENDERER_ERROR("failed to release Renderer resources");
+  if (!resource_manager_->Release())
+    TRACKRENDERER_ERROR("failed to release hw resources");
 
   for (int i = 0; i < kTrackTypeMax; ++i) {
     trackctx_[i].index = kInvalidTrackIndex;
@@ -1465,6 +1447,7 @@ bool TrackRenderer::ReleaseResource_() {
     trackctx_[i].need_update_segment = true;
   }
   trackinfo_.clear();
+
   TRACKRENDERER_LEAVE;
   return true;
 }
@@ -2148,21 +2131,35 @@ ERROR:
 GstPadProbeReturn TrackRenderer::GstPadProbeCapsEventCb_(GstPad* pad,
                                                      GstPadProbeInfo* info,
                                                      gpointer userdata) {
-  auto trackrenderer = static_cast<TrackRenderer*>(userdata);
-
-  if (GST_EVENT_TYPE (info->data) == GST_EVENT_CAPS) {
-    GstCaps *caps;
-
-    gst_event_parse_caps ((GstEvent*)(info->data), &caps);
-    auto caps_str = gstguard::make_guard(gst_caps_to_string(caps));
+  if (GST_EVENT_TYPE(info->data) != GST_EVENT_CAPS)
+    return GST_PAD_PROBE_PASS;
 
-    TRACKRENDERER_INFO("caps %s", caps_str.get());
+  GstCaps *caps;
+  gst_event_parse_caps((GstEvent*)(info->data), &caps);
+  auto caps_str = gstguard::make_guard(gst_caps_to_string(caps));
+  TRACKRENDERER_INFO("caps %s", caps_str.get());
 
-    trackrenderer->ActivateAudioPipeline(caps);
+  auto trackrenderer = static_cast<TrackRenderer*>(userdata);
+  if (trackrenderer == nullptr) {
+    TRACKRENDERER_ERROR("trackrenderer is nullptr");
     return GST_PAD_PROBE_REMOVE;
   }
 
-  return GST_PAD_PROBE_PASS;
+  if (!trackrenderer->ActivateAudioPipeline(caps)) {
+    TRACKRENDERER_ERROR("Failed to create audio pipeline");
+    trackrenderer->trackctx_[kTrackTypeAudio].index = kInvalidTrackIndex;
+
+    auto target =
+              std::find_if(trackrenderer->trackinfo_.begin(),
+                          trackrenderer->trackinfo_.end(),
+                          [](const Track& item) -> bool {
+                            return item.type == kTrackTypeAudio;
+                          });
+    if (target != trackrenderer->trackinfo_.end())
+      trackrenderer->trackinfo_.erase(target);
+
+  }
+  return GST_PAD_PROBE_REMOVE;
 }
 
 bool TrackRenderer::Activate(TrackType type, const Track& track) {
@@ -2190,29 +2187,11 @@ bool TrackRenderer::Activate(TrackType type, const Track& track) {
     return false;
   }
 
-  trackctx_[type].index = track.index;
   TRACKRENDERER_INFO("track type %d, index %d", type, track.index);
-
+  trackctx_[type].index = track.index;
   trackinfo_.push_back(track);
 
   if (type == kTrackTypeVideo) {
-    if (!track.use_swdecoder) {
-      std::list<ResourceProperty> propertylist;
-      ResourceProperty videodecproperty;
-      videodecproperty.category = ResourceCategory::kVideoDecoder;
-      videodecproperty.track = track;
-      propertylist.push_back(videodecproperty);
-
-      ResourceProperty videorenderproperty;
-      videorenderproperty.category = ResourceCategory::kVideoRenderer;
-      propertylist.push_back(videorenderproperty);
-
-      if (!resource_manager_->Acquire(propertylist)) {
-        TRACKRENDERER_ERROR("Video resource acquire fail! ChangeTrack fail.");
-        return false;
-      }
-    } // FIXME: need to acquire the renderer res
-
     auto caps = caps_builder_.Build(track, internal::IsDrmEmeElementNecessary(
                                                drm_property_, track.mimetype));
 
@@ -2231,17 +2210,14 @@ bool TrackRenderer::Activate(TrackType type, const Track& track) {
 
     if (!CreateDecoder_(&track, static_cast<GstCaps*>(parse_caps.get()))) {
       TRACKRENDERER_ERROR("Failed to make video decoder");
-      pipeline_->ElementRemove(Elements::kParseVideo);
       const ErrorType err = ErrorType::kNotSupportedVideoCodec;
       eventlistener_->OnError(err);
-      return false;
+      goto ERROR_VIDEO;
     }
 
     if (!CreateVideoSink_(&track)) {
       TRACKRENDERER_ERROR("Failed to make video sink");
-      pipeline_->ElementRemove(Elements::kParseVideo);
-      pipeline_->ElementRemove(Elements::kDecVideo);
-      return false;
+      goto ERROR_VIDEO;
     }
 
     pipeline_->SetProperty(Elements::kSinkVideo, "async", FALSE);
@@ -2294,7 +2270,10 @@ bool TrackRenderer::Activate(TrackType type, const Track& track) {
       pipeline_->SetAppSrcCaps(Elements::kAppSrcAudio, new_caps);
     } else {
       TRACKRENDERER_INFO("Caps is the same");
-      ActivateAudioPipeline(new_caps.GetCaps_());
+      if (!ActivateAudioPipeline(new_caps.GetCaps_())) {
+        TRACKRENDERER_ERROR("Failed to create audio pipeline");
+        goto ERROR;
+      }
     }
   } else {
     auto caps =
@@ -2304,6 +2283,19 @@ bool TrackRenderer::Activate(TrackType type, const Track& track) {
   }
   TRACKRENDERER_LEAVE;
   return true;
+
+ERROR_VIDEO:
+  /* release elements which are not added in bin yet */
+  pipeline_->ElementRemove(Elements::kParseVideo);
+  pipeline_->ElementRemove(Elements::kDecVideo);
+
+  if (!resource_manager_->Release())
+    TRACKRENDERER_ERROR("failed to release hw resources");
+
+ERROR:
+  trackctx_[type].index = kInvalidTrackIndex;
+  trackinfo_.pop_back();
+  return false;
 }
 
 bool TrackRenderer::GetPlayingTime(uint64_t* curtime_in_msec) {