add videoscale to support dynamic resolution change 98/279598/15
authorhj kim <backto.kim@samsung.com>
Fri, 12 Aug 2022 06:20:47 +0000 (15:20 +0900)
committerhj kim <backto.kim@samsung.com>
Tue, 23 Aug 2022 02:34:23 +0000 (11:34 +0900)
To support dynamic resolution change for sources that do not support dynamic resolution change.

[Version] 0.3.204
[Issue Type] Improvement

Change-Id: I617951d757150168e81a1f7efb8e4e390f1f9153

include/webrtc.h
include/webrtc_private.h
include/webrtc_source_private.h
packaging/capi-media-webrtc.spec
src/webrtc_source.c
src/webrtc_source_private.c

index 8332409d7b6f130eabd798830cb0f7f050425a16..112abfd6b47ae412ce7c43ffea3c91941b607590 100644 (file)
@@ -1296,6 +1296,8 @@ int webrtc_media_source_get_encoder_bitrate(webrtc_h webrtc, unsigned int source
  * @since_tizen 6.5
  * @remarks If @a source_id does not support for the dynamic resolution change, #WEBRTC_ERROR_INVALID_OPERATION will be returned\n
  *          while @a webrtc state is #WEBRTC_STATE_NEGOTIATING or #WEBRTC_STATE_PLAYING.
+ *          Since 7.0, this function supports dynamic resolution change regardless of state for all video sources mentioned in details.\n
+ *          However, some sources cannot be changed to a greater value than the resolution set in the #WEBRTC_STATE_IDLE.
  * @param[in] webrtc      WebRTC handle
  * @param[in] source_id   The video source id
  * @param[in] width       The video width
index 9a89bd34d1fe32fbea61c14d1034256221244ec3..8445de0c832ae6b89acbe3df541fd96194373c34 100644 (file)
@@ -557,6 +557,8 @@ typedef struct _webrtc_gst_slot_s {
                } render;
        } av[AV_IDX_MAX];
        struct {
+               int origin_width;
+               int origin_height;
                int width;
                int height;
                int framerate;
index 7edf37a1a9f74701a2e979bcf0f700005e8f15d4..b81b0d8b3d2bf914bf149b408bac4def9063993f 100644 (file)
@@ -40,6 +40,7 @@
 #define DEFAULT_ELEMENT_VOLUME            "volume"
 #define DEFAULT_ELEMENT_INPUT_SELECTOR    "input-selector"
 #define DEFAULT_ELEMENT_VIDEOCROP         "videocrop"
+#define DEFAULT_ELEMENT_VIDEOSCALE        "videoscale"
 #define DEFAULT_ELEMENT_FILESRC           "filesrc"
 
 #define ELEMENT_NAME_FIRST_CAPSFILTER        "firstCapsfilter"
@@ -63,6 +64,7 @@
 #define ELEMENT_NAME_VIDEO_FAKESINK          "videoFakeSink"
 #define ELEMENT_NAME_AUDIO_APPSRC            "audioAppsrc"
 #define ELEMENT_NAME_VIDEO_APPSRC            "videoAppsrc"
+#define ELEMENT_NAME_VIDEOSCALE_CAPSFILTER   "videoscaleCapsfilter"
 
 typedef enum {
        ELEMENT_APPSRC,
index 94ba7e7bfb981512be210f0618eee4291d3b411b..900d3211562cc1ab2acbf7f7a532be7a1a11102e 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.3.203
+Version:    0.3.204
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 7dc34a1909112c097ce9b3526b491b89f7d94934..151edf62fa6ba0dce3b8c6e75ffea10967f7c1a8 100644 (file)
@@ -140,6 +140,8 @@ static bool __set_default_video_info(webrtc_gst_slot_s *source, const ini_item_m
        RET_VAL_IF(ini_source == NULL, false, "ini_source is NULL");
 
        source->video_info.framerate = ini_source->v_framerate;
+       source->video_info.origin_width = ini_source->v_width;
+       source->video_info.origin_height = ini_source->v_height;
        source->video_info.width = ini_source->v_width;
        source->video_info.height = ini_source->v_height;
 
@@ -154,6 +156,9 @@ static bool __set_default_video_info(webrtc_gst_slot_s *source, const ini_item_m
                                return true;
                        }
                }
+
+               source->video_info.origin_width = width;
+               source->video_info.origin_height = height;
                source->video_info.width = width;
                source->video_info.height = height;
 #else
@@ -1349,7 +1354,7 @@ int _set_video_resolution(webrtc_s *webrtc, unsigned int source_id, int width, i
 {
        webrtc_gst_slot_s *source;
        GstElement *capsfilter;
-       GstCaps *new_caps = NULL;
+       bool drc_support = false;
 
        RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
        RET_VAL_IF((source = _get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "could not find source");
@@ -1362,18 +1367,36 @@ int _set_video_resolution(webrtc_s *webrtc, unsigned int source_id, int width, i
                const ini_item_media_source_s *ini_source = _ini_get_source_by_type(&webrtc->ini, source->type);
                if (ini_source == NULL)
                        ini_source = &webrtc->ini.media_source;
-               RET_VAL_IF(!ini_source->v_drc_support, WEBRTC_ERROR_INVALID_OPERATION, "not supported dynamic resolution change");
+
+               if (ini_source->v_drc_support)
+                       drc_support = true;
        }
 
-       if ((capsfilter = _find_element_in_bin(source->bin, ELEMENT_NAME_FIRST_CAPSFILTER))) {
-               /* FIXME: check if the [width x height] is supported or not */
+       if (webrtc->state == WEBRTC_STATE_IDLE || drc_support) {
+               capsfilter = _find_element_in_bin(source->bin, ELEMENT_NAME_FIRST_CAPSFILTER);
+
+               source->video_info.origin_width = width;
+               source->video_info.origin_height = height;
+       } else {
+
+               RET_VAL_IF(width > source->video_info.origin_width, WEBRTC_ERROR_INVALID_OPERATION,
+                       "it doesn't support upscale. invalid width. origin [%d] requested [%d]", source->video_info.origin_width, width);
+               RET_VAL_IF(height > source->video_info.origin_height, WEBRTC_ERROR_INVALID_OPERATION,
+                       "it doesn't support upscale. invalid height. origin [%d] requested [%d]", source->video_info.origin_height, height);
+
+               capsfilter = _find_element_in_bin(source->bin, ELEMENT_NAME_VIDEOSCALE_CAPSFILTER);
+               RET_VAL_IF(!capsfilter, WEBRTC_ERROR_INVALID_OPERATION, "not supported dynamic resolution change");
+       }
+
+       if (capsfilter) {
+               GstCaps *new_caps;
+
                if (!(new_caps = __make_video_raw_caps_with_resolution(source, &webrtc->ini, width, height)))
                        return WEBRTC_ERROR_INVALID_OPERATION;
                PRINT_CAPS(new_caps, "capsfilter");
 
                g_object_set(G_OBJECT(capsfilter), "caps", new_caps, NULL);
                gst_caps_unref(new_caps);
-
        }
 
        source->video_info.width = width;
index ca51ec190f6825d5e2a6cc0d6e7873dae6c9a1a7..8bb77b40e4fc83eb8e3d3b9e346b2975fac70784 100644 (file)
@@ -1004,6 +1004,32 @@ static GstElement * __prepare_encoder(webrtc_s *webrtc, webrtc_gst_slot_s *sourc
        return encoder;
 }
 
+static bool __is_videoscale_needed(webrtc_s *webrtc, webrtc_gst_slot_s *source)
+{
+       const ini_item_media_source_s *ini_source;
+
+       RET_VAL_IF(webrtc == NULL, false, "webrtc is NULL");
+       RET_VAL_IF(source == NULL, false, "source is NULL");
+
+       if (!(source->media_types & MEDIA_TYPE_VIDEO))
+               return false;
+
+       if (_is_encoded_format_supported(source->type, &webrtc->ini))
+               return false;
+
+       ini_source = _ini_get_source_by_type(&webrtc->ini, source->type);
+       if (ini_source == NULL)
+               ini_source = &webrtc->ini.media_source;
+
+       if (ini_source->v_drc_support)
+               return false;
+
+       if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_FILE || source->type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET)
+               return false;
+
+       return true;
+}
+
 int _create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool need_capsfilter, GList **element_list, bool is_audio)
 {
        GstElement *encoder = NULL;
@@ -1054,6 +1080,25 @@ int _create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool n
                _add_probe_to_pad_for_render(source, idx, gst_element_get_static_pad(capsfilter, "src"), _source_data_probe_cb);
        }
 
+       if (__is_videoscale_needed(webrtc, source)) {
+               GstElement *videoscale;
+               GstElement *videoscaleCapsfilter;
+               GstCaps *caps;
+
+               if (!(videoscale = _create_element(DEFAULT_ELEMENT_VIDEOSCALE, NULL)))
+                       goto error;
+               APPEND_ELEMENT(*element_list, videoscale);
+
+               if (!(videoscaleCapsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_VIDEOSCALE_CAPSFILTER)))
+                       goto error;
+               APPEND_ELEMENT(*element_list, videoscaleCapsfilter);
+
+               if ((caps = __make_default_raw_caps(source, &webrtc->ini))) {
+                       PRINT_CAPS(caps, ELEMENT_NAME_VIDEOSCALE_CAPSFILTER);
+                       g_object_set(G_OBJECT(videoscaleCapsfilter), "caps", caps, NULL);
+               }
+       }
+
        if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_SCREEN && !source->zerocopy_enabled) {
                if (!(videocrop = _create_element(DEFAULT_ELEMENT_VIDEOCROP, ELEMENT_NAME_VIDEOCROP)))
                        goto error;