make decoder according to the use_swdecoder option 57/298257/3
authorEunhye Choi <eunhae1.choi@samsung.com>
Mon, 4 Sep 2023 09:04:58 +0000 (18:04 +0900)
committerEunhye Choi <eunhae1.choi@samsung.com>
Tue, 5 Sep 2023 03:08:05 +0000 (12:08 +0900)
- make decoder according to the use_swdecoder option
  which is set by SetTrack or Activate interface
- if user use esplusplayer api, use_swdecoder option is set by
  calling below api.
  : esplusplayer_set_video_codec_type
    esplusplayer_set_audio_codec_type
- if there is no hw or sw decoder which user want to use,
  the default one (which has highest rank) will be selected.

[Version] 0.0.34

Change-Id: Ifbad22f35429ad0d68804b4e93003a58d93a8df5

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

index 3a5c46d5ead3d79fb4337984d217326218065fb6..d9b25b29b6d6dd62f3a034a34b19cafad14eae57 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libtrackrenderer
 Summary:    new multimedia streaming player trackrenderer
-Version:    0.0.33
+Version:    0.0.34
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index 50778436b2efa313b1f6a19fc353613086a508ed..d2f06127c4319b1b927e693e700a7df893bfb15c 100644 (file)
@@ -123,21 +123,22 @@ class Pipeline : private boost::noncopyable {
   }
 
   bool FactoryMake(const T element, GstCaps *caps, GstElementFactoryListType type, const char* nickname) {
-    GList *factories = NULL;
     GList *filtered = NULL;
-    GstElementFactory *factory = nullptr;
     GstElement* obj = nullptr;
+    bool use_hw = (type & GST_ELEMENT_FACTORY_TYPE_HARDWARE);
 
     if (!caps) {
       TRACKRENDERER_ERROR("invalid caps [null]");
       return false;
     }
 
+    type &= ~GST_ELEMENT_FACTORY_TYPE_HARDWARE; // control by use_hw flag
+
     auto caps_str = gstguard::make_guard(gst_caps_to_string(caps));
     TRACKRENDERER_DEBUG("finding factory based on [%s]", caps_str.get());
 
-    /* get all compatible factories for caps */
-    factories =
+    // get all compatible factories for caps
+    GList *factories =
       gst_element_factory_list_get_elements (type, GST_RANK_MARGINAL);
     if (factories) {
       filtered =
@@ -147,18 +148,39 @@ class Pipeline : private boost::noncopyable {
     }
 
     if (filtered) {
+      GstElementFactory *factory = nullptr;
+      GstElementFactory *dec_factory = nullptr;
       GList *l = filtered;
-      while(l) {
+
+      if (!(type & GST_ELEMENT_FACTORY_TYPE_DECODER)) {
         factory = GST_ELEMENT_FACTORY_CAST (l->data);
-        /* FIXME : need to skip avdec element for mp3 decoder */
-        if (!strstr(GST_OBJECT_NAME(factory), "avdec_mp1float") &&
-            !strstr(GST_OBJECT_NAME(factory), "avdec_mp2float") &&
-            !strstr(GST_OBJECT_NAME(factory), "avdec_mp3float")) {
-          break;
+      } else {
+        for (; l; l = l->next) {
+          factory = GST_ELEMENT_FACTORY_CAST (l->data);
+
+          // FIXME : need to skip avdec element for mp3 decoder -> ini
+          if (strstr(GST_OBJECT_NAME(factory), "avdec_mp1float") ||
+              strstr(GST_OBJECT_NAME(factory), "avdec_mp2float") ||
+              strstr(GST_OBJECT_NAME(factory), "avdec_mp3float")) {
+            TRACKRENDERER_DEBUG("skip %s factory", GST_OBJECT_NAME(factory));
+            continue;
+          }
+
+          const gchar *klass =
+              gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
+
+          if (!(use_hw ^ (strstr(klass, "Hardware") != NULL)))
+            break;
+
+          TRACKRENDERER_DEBUG("skip %s factory", GST_OBJECT_NAME(factory));
+          if (!dec_factory) // keep the highest rank decoder regardless of sw/hw type
+            dec_factory = factory;
         }
-        TRACKRENDERER_DEBUG("skip %s factory", GST_OBJECT_NAME(factory));
-        l = l->next;
+
+        if (!l)
+          factory = dec_factory;
       }
+
       TRACKRENDERER_DEBUG("factory name : %s", GST_OBJECT_NAME(factory));
       obj = gst_element_factory_create(factory, nickname);
       gst_plugin_feature_list_free (filtered);
index 9974a201eb9003c40aa8b0413dab546944155693..0bf0dcff13f7466b3c9575b9d5bb1173c5d2de2b 100644 (file)
@@ -1083,9 +1083,15 @@ bool TrackRenderer::CreateVideoPipeline_(const Track* track) {
   auto parse_caps =
       gstguard::make_guard(pipeline_->GetSrcPadCaps(Elements::kParseVideo));
 
+  GstElementFactoryListType factory_type = GST_ELEMENT_FACTORY_TYPE_DECODER;
+
+  if (!track->use_swdecoder &&
+      !internal::GetIniValue(properties_, "use_default_video_codec_sw"))
+    factory_type |= GST_ELEMENT_FACTORY_TYPE_HARDWARE;
+
   if (!pipeline_->FactoryMake(Elements::kDecVideo,
                           static_cast<GstCaps*>(parse_caps ? parse_caps.get() : caps.GetCaps_()),
-                          GST_ELEMENT_FACTORY_TYPE_DECODER, NULL)) {
+                          factory_type, NULL)) {
     const ErrorType err = ErrorType::kNotSupportedVideoCodec;
     TRACKRENDERER_ERROR("fail to make decoder");
     eventlistener_->OnError(err);
@@ -1155,12 +1161,11 @@ bool TrackRenderer::CreateVideoPipeline_(const Track* track) {
     }
   }
 
-  bool sw_codec =  internal::GetIniValue(properties_, "use_default_video_codec_sw");
-  if (!sw_codec && pipeline_->IsFactoryListType(Elements::kDecVideo, GST_ELEMENT_FACTORY_TYPE_HARDWARE)) {
+  if (pipeline_->IsFactoryListType(Elements::kDecVideo, GST_ELEMENT_FACTORY_TYPE_HARDWARE)) {
     TRACKRENDERER_INFO("HW codec");
     if (videosink_name && strstr(videosink_name, kVideoSinkName))
       pipeline_->SetProperty(Elements::kSinkVideo, "use-tbm", true);
-  } else { /* sw */
+  } else {
     TRACKRENDERER_INFO("SW codec");
     pipeline_->FactoryMake(Elements::kVideoQueue, "queue", NULL);
     pipeline_->SetProperty(Elements::kVideoQueue, "max-size-buffers", 2);
@@ -2207,8 +2212,14 @@ bool TrackRenderer::Activate(TrackType type, const Track& track) {
     auto parse_caps =
         gstguard::make_guard(pipeline_->GetSrcPadCaps(Elements::kParseVideo));
 
-    if (!pipeline_->FactoryMake(Elements::kDecVideo, (GstCaps*)parse_caps.get(),
-                            GST_ELEMENT_FACTORY_TYPE_DECODER, NULL)) {
+    GstElementFactoryListType factory_type = GST_ELEMENT_FACTORY_TYPE_DECODER;
+
+    if (!track.use_swdecoder &&
+        !internal::GetIniValue(properties_, "use_default_video_codec_sw"))
+      factory_type |= GST_ELEMENT_FACTORY_TYPE_HARDWARE;
+
+    if (!pipeline_->FactoryMake(Elements::kDecVideo,
+                                (GstCaps*)parse_caps.get(), factory_type, NULL)) {
       const ErrorType err = ErrorType::kNotSupportedVideoCodec;
       eventlistener_->OnError(err);
       return false;