webrtc_sink: Enable 'use-tbm' property of videosink if H/W decoder is used 79/279279/2
authorSangchul Lee <sc11.lee@samsung.com>
Fri, 5 Aug 2022 02:46:18 +0000 (11:46 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Fri, 5 Aug 2022 03:35:37 +0000 (12:35 +0900)
It supports both WEBRTC_DISPLAY_TYPE_OVERLAY and
WEBRTC_DISPLAY_TYPE_ECORE_WL display types.

videoconvert is also excluded in this situation.

[Version] 0.3.195
[Issue Type] Improvement

Change-Id: If6e432762ee75b42a570a871342ce154400cf702
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc_sink.c

index 30e717010a7d50d7f40df33c17a834e86b7867a8..023851e243ad2aaef1d5fd6e53ffd22f53b7145d 100644 (file)
@@ -549,6 +549,7 @@ typedef struct _webrtc_gst_slot_s {
                        GstElement *pipeline;
                        GstElement *appsrc;
                        GstCaps *appsrc_caps;
+                       bool hw_decoder_used;
                } render;
        } av[AV_IDX_MAX];
        struct {
index 1a3fc324c5b8ed85aeac3fe8cd0800d8ac760332..70720e3fc47178106904caad53bae823a0bb85cd 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.3.194
+Version:    0.3.195
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index fe4ce3b63ebc0b0c867686ff40fd5199f3bc5b29..b1b6a62e8ad829aaf879a2793fa035ad920eea28 100644 (file)
@@ -165,15 +165,18 @@ static int __build_videosink(webrtc_s *webrtc, GstElement *decodebin, GstPad *sr
 #endif
                if (sink->display->type == WEBRTC_DISPLAY_TYPE_OVERLAY ||
                        sink->display->type == WEBRTC_DISPLAY_TYPE_ECORE_WL) {
+                       g_object_set(G_OBJECT(videosink),
+                               "use-tbm", sink->av[AV_IDX_VIDEO].render.hw_decoder_used,
+                               "display-geometry-method", (gint)sink->display->mode, /* 0: letter box, 1: origin size, 2: full screen */
+                               "visible", (gboolean)sink->display->visible,
+                               NULL);
+
+                       /* FIXME: The order of setting property and display is important when 'use-tbm' is true. The reverse does not work */
                        gst_video_overlay_set_wl_window_wl_surface_id(GST_VIDEO_OVERLAY(videosink), sink->display->overlay_surface_id);
                        RET_VAL_IF(!g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(videosink)), "display-geometry-method"),
                                WEBRTC_ERROR_INVALID_OPERATION, "could not find 'display-geometry-method' property");
                        RET_VAL_IF(!g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(videosink)), "visible"),
                                WEBRTC_ERROR_INVALID_OPERATION, "could not find 'visible' property");
-                       g_object_set(G_OBJECT(videosink),
-                               "display-geometry-method", (gint)sink->display->mode, /* 0: letter box, 1: origin size, 2: full screen */
-                               "visible", (gboolean)sink->display->visible,
-                               NULL);
 
                } else if (sink->display->type == WEBRTC_DISPLAY_TYPE_EVAS) {
                        GstCaps *caps;
@@ -195,10 +198,17 @@ static int __build_videosink(webrtc_s *webrtc, GstElement *decodebin, GstPad *sr
                        gst_caps_unref(caps);
                }
 
-               if (!(videoconvert = _create_element(DEFAULT_ELEMENT_VIDEOCONVERT, NULL)))
-                       goto exit;
-               PREPEND_ELEMENT(element_list, videoconvert);
-               link_to = videoconvert;
+               if (sink->av[AV_IDX_VIDEO].render.hw_decoder_used &&
+                       (sink->display->type == WEBRTC_DISPLAY_TYPE_OVERLAY ||
+                       sink->display->type == WEBRTC_DISPLAY_TYPE_ECORE_WL)) {
+                       link_to = videosink;
+
+               } else {
+                       if (!(videoconvert = _create_element(DEFAULT_ELEMENT_VIDEOCONVERT, NULL)))
+                               goto exit;
+                       PREPEND_ELEMENT(element_list, videoconvert);
+                       link_to = videoconvert;
+               }
        }
 
        if (!_add_elements_to_bin(sink->bin, element_list)) {
@@ -348,16 +358,51 @@ static void __invoke_track_added_cb(webrtc_s *webrtc, const gchar *name, bool is
        }
 }
 
+static bool __is_factory_name_for_hw(gchar *factory_name)
+{
+       RET_VAL_IF(factory_name == NULL, FALSE, "factory_name is NULL");
+
+       /* more can be added later on */
+       if (g_str_has_prefix(factory_name, "sprd") ||
+               g_str_has_prefix(factory_name, "omx") ||
+               g_str_has_prefix(factory_name, "v4l2")) {
+               LOG_DEBUG("factory_name[%s]", factory_name);
+               return true;
+       }
+
+       return false;
+}
+
+static bool __is_hw_decoder_element(GstElementFactory *factory, bool is_audio)
+{
+       gchar *factory_name;
+       const gchar *klass;
+
+       RET_VAL_IF(factory == NULL, false, "factory is NULL");
+
+       factory_name = GST_OBJECT_NAME(factory);
+       klass = gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS);
+
+       if (is_audio)
+               return (g_strrstr(klass, "Decoder/Audio/Hardware") ||
+                       (g_strrstr(klass, "Decoder/Audio") && __is_factory_name_for_hw(factory_name)));
+
+       return (g_strrstr(klass, "Decoder/Video/Hardware") ||
+               (g_strrstr(klass, "Decoder/Video") && __is_factory_name_for_hw(factory_name)));
+}
+
 static void __decodebin_element_added_cb(GstElement *decodebin, GstElement *element, gpointer user_data)
 {
-       const webrtc_gst_slot_s *sink = (webrtc_gst_slot_s *)user_data;
+       webrtc_gst_slot_s *sink = (webrtc_gst_slot_s *)user_data;
+       GstElementFactory *factory;
        gchar *factory_name = NULL;
 
        RET_IF(decodebin == NULL, "decodebin is NULL");
        RET_IF(element == NULL, "element is NULL");
        RET_IF(sink == NULL, "sink is NULL");
 
-       factory_name = GST_OBJECT_NAME(gst_element_get_factory(element));
+       factory = gst_element_get_factory(element);
+       factory_name = GST_OBJECT_NAME(factory);
 
        LOG_INFO("element[name: %s] was added to decodebin", GST_ELEMENT_NAME(element));
 
@@ -383,6 +428,9 @@ static void __decodebin_element_added_cb(GstElement *decodebin, GstElement *elem
                                NULL);
                }
        }
+
+       sink->av[AV_IDX_AUDIO].render.hw_decoder_used = __is_hw_decoder_element(factory, true);
+       sink->av[AV_IDX_VIDEO].render.hw_decoder_used = __is_hw_decoder_element(factory, false);
 }
 
 static void __decodebin_pad_added_cb(GstElement *decodebin, GstPad *new_pad, gpointer user_data)
@@ -433,20 +481,6 @@ static void __decodebin_pad_added_cb(GstElement *decodebin, GstPad *new_pad, gpo
        GENERATE_DOT(webrtc, webrtc->gst.pipeline, "%s.%s", GST_ELEMENT_NAME(webrtc->gst.pipeline), GST_ELEMENT_NAME(decodebin));
 }
 
-static bool __is_factory_name_for_hw(gchar *factory_name)
-{
-       RET_VAL_IF(factory_name == NULL, FALSE, "factory_name is NULL");
-
-       /* more can be added later on */
-       if (g_str_has_prefix(factory_name, "sprd") ||
-               g_str_has_prefix(factory_name, "omx")) {
-               LOG_DEBUG("factory_name[%s]", factory_name);
-               return true;
-       }
-
-       return false;
-}
-
 int _decodebin_autoplug_select_cb(GstElement *decodebin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, gpointer user_data)
 {
        gchar *factory_name;
@@ -469,15 +503,14 @@ int _decodebin_autoplug_select_cb(GstElement *decodebin, GstPad *pad, GstCaps *c
                }
        }
 
-       if (g_strrstr(klass, "Decoder/Audio/Hardware") ||
-               (g_strrstr(klass, "Decoder/Audio") && __is_factory_name_for_hw(factory_name))) {
+       if (__is_hw_decoder_element(factory, true)) {
                str_arr = webrtc->ini.rendering_sink.a_hw_decoder_elements;
                if (str_arr == NULL || !g_strv_contains((const gchar * const *)str_arr, factory_name)) {
                        LOG_WARNING("this audio hw decoder element[%s] is not specified in ini file, skip it", factory_name);
                        return GST_AUTOPLUG_SELECT_SKIP;
                }
-       } else if (g_strrstr(klass, "Decoder/Video/Hardware") ||
-               (g_strrstr(klass, "Decoder/Video") && __is_factory_name_for_hw(factory_name))) {
+
+       } else if (__is_hw_decoder_element(factory, false)) {
                str_arr = webrtc->ini.rendering_sink.v_hw_decoder_elements;
                if (str_arr == NULL || !g_strv_contains((const gchar * const *)str_arr, factory_name)) {
                        LOG_WARNING("this video hw decoder element[%s] is not specified in ini file, skip it", factory_name);