From: hj kim Date: Fri, 12 Aug 2022 06:20:47 +0000 (+0900) Subject: add videoscale to support dynamic resolution change X-Git-Tag: submit/tizen/20220823.080652~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bbbc026e43d56d41db7372df67856112478d0aa6;p=platform%2Fcore%2Fapi%2Fwebrtc.git add videoscale to support dynamic resolution change To support dynamic resolution change for sources that do not support dynamic resolution change. [Version] 0.3.204 [Issue Type] Improvement Change-Id: I617951d757150168e81a1f7efb8e4e390f1f9153 --- diff --git a/include/webrtc.h b/include/webrtc.h index 8332409d..112abfd6 100644 --- a/include/webrtc.h +++ b/include/webrtc.h @@ -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 diff --git a/include/webrtc_private.h b/include/webrtc_private.h index 9a89bd34..8445de0c 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -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; diff --git a/include/webrtc_source_private.h b/include/webrtc_source_private.h index 7edf37a1..b81b0d8b 100644 --- a/include/webrtc_source_private.h +++ b/include/webrtc_source_private.h @@ -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, diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 94ba7e7b..900d3211 100644 --- a/packaging/capi-media-webrtc.spec +++ b/packaging/capi-media-webrtc.spec @@ -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 diff --git a/src/webrtc_source.c b/src/webrtc_source.c index 7dc34a19..151edf62 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -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; diff --git a/src/webrtc_source_private.c b/src/webrtc_source_private.c index ca51ec19..8bb77b40 100644 --- a/src/webrtc_source_private.c +++ b/src/webrtc_source_private.c @@ -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;