From: hj kim Date: Wed, 24 Aug 2022 08:53:03 +0000 (+0900) Subject: webrtc_source_screen: move pad probe position for loopback on crop X-Git-Tag: submit/tizen/20220902.031026~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F43%2F280143%2F15;p=platform%2Fcore%2Fapi%2Fwebrtc.git webrtc_source_screen: move pad probe position for loopback on crop screen source can have crop element, so the video stream for loopback should be collected on crop element. and proper resolution after crop should be applied to video loopback. [Version] 0.3.224 [Issue Type] Improvement Change-Id: Ie7585d3115cad392fe272a254ff460ee0e92b353 --- diff --git a/include/webrtc_source_private.h b/include/webrtc_source_private.h index 7de4fe8a..8ac60972 100644 --- a/include/webrtc_source_private.h +++ b/include/webrtc_source_private.h @@ -112,5 +112,7 @@ int _get_encoder_element_bitrate(GstElement *encoder, int *target_bitrate); void _set_caps_for_render(webrtc_gst_slot_s *source, GstCaps *caps, int av_idx); void _unset_caps_for_render(webrtc_gst_slot_s *source, int av_idx); void _set_video_src_resolution(webrtc_gst_slot_s *source, int width, int height); +GstCaps *_make_video_raw_caps_with_resolution(webrtc_gst_slot_s *source, webrtc_ini_s *ini, int width, int height); +int _update_caps_for_render_with_resolution(webrtc_gst_slot_s *source, int width, int height); #endif /* __TIZEN_MEDIA_WEBRTC_SOURCE_COMMON_H__ */ diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 35478446..c771cc62 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.223 +Version: 0.3.224 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc_source.c b/src/webrtc_source.c index 553f4810..3b54adef 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -35,38 +35,6 @@ static direction_info_s __direction_info[] = { static GstPadProbeReturn __camerasrc_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); -static GstCaps *__make_video_raw_caps_with_resolution(webrtc_gst_slot_s *source, webrtc_ini_s *ini, int width, int height) -{ - GstCaps *caps = NULL; - const ini_item_media_source_s *ini_source; - - RET_VAL_IF(source == NULL, NULL, "source is NULL"); - RET_VAL_IF(ini == NULL, NULL, "ini is NULL"); - - ini_source = _ini_get_source_by_type(ini, source->type); - if (ini_source == NULL) - ini_source = &ini->media_source; - - switch (source->type) { - case WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST: - case WEBRTC_MEDIA_SOURCE_TYPE_CAMERA: - case WEBRTC_MEDIA_SOURCE_TYPE_SCREEN: { - caps = gst_caps_new_simple(MEDIA_TYPE_VIDEO_RAW, - "format", G_TYPE_STRING, ini_source->v_raw_format, - "framerate", GST_TYPE_FRACTION, source->video_info.framerate, 1, - "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, - NULL); - break; - } - default: - LOG_ERROR_IF_REACHED("type(%d)", source->type); - break; - } - - return caps; -} - static GstCaps *__make_video_raw_caps_with_framerate(webrtc_gst_slot_s *source, webrtc_ini_s *ini, int framerate) { GstCaps *caps = NULL; @@ -1452,7 +1420,7 @@ int _set_video_resolution(webrtc_s *webrtc, unsigned int source_id, int width, i if (capsfilter) { GstCaps *new_caps; - if (!(new_caps = __make_video_raw_caps_with_resolution(source, &webrtc->ini, width, height))) + if (!(new_caps = _make_video_raw_caps_with_resolution(source, &webrtc->ini, width, height))) return WEBRTC_ERROR_INVALID_OPERATION; PRINT_CAPS(new_caps, "capsfilter"); @@ -1461,14 +1429,8 @@ int _set_video_resolution(webrtc_s *webrtc, unsigned int source_id, int width, i } if (webrtc->state != WEBRTC_STATE_IDLE) { - 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, "appsrc"); - - _unset_caps_for_render(source, AV_IDX_VIDEO); - _set_caps_for_render(source, new_caps, AV_IDX_VIDEO); + int ret = _update_caps_for_render_with_resolution(source, width, height); + RET_VAL_IF(ret != WEBRTC_ERROR_NONE, ret, "failed to _update_caps_for_render_with_resolution()"); } _set_video_src_resolution(source, width, height); diff --git a/src/webrtc_source_private.c b/src/webrtc_source_private.c index 31bbdf3a..7448aab7 100644 --- a/src/webrtc_source_private.c +++ b/src/webrtc_source_private.c @@ -1062,6 +1062,8 @@ int _create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool n element_info_s elem_info; gchar *media_type = NULL; int idx; + GstPad *pad_for_render = NULL; + GstCaps *caps_for_render = NULL; RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL"); @@ -1080,11 +1082,11 @@ int _create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool n PRINT_CAPS(sink_caps, "capsfilter"); g_object_set(G_OBJECT(capsfilter), "caps", sink_caps, NULL); - _set_caps_for_render(source, sink_caps, idx); + caps_for_render = sink_caps; } source->av[idx].render.need_decoding = true; - _add_probe_to_pad_for_render(source, idx, gst_element_get_static_pad(capsfilter, "src"), _source_data_probe_cb); + pad_for_render = gst_element_get_static_pad(capsfilter, "src"); goto skip_encoder; } @@ -1093,10 +1095,10 @@ int _create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool n PRINT_CAPS(sink_caps, "capsfilter"); g_object_set(G_OBJECT(capsfilter), "caps", sink_caps, NULL); - _set_caps_for_render(source, sink_caps, idx); + caps_for_render = sink_caps; } - _add_probe_to_pad_for_render(source, idx, gst_element_get_static_pad(capsfilter, "src"), _source_data_probe_cb); + pad_for_render = gst_element_get_static_pad(capsfilter, "src"); } if (__is_videoscale_needed(webrtc, source)) { @@ -1112,29 +1114,40 @@ int _create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool n goto error; APPEND_ELEMENT(*element_list, videoscaleCapsfilter); - _remove_probe_from_pad_for_render(source, idx); - 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); - _set_caps_for_render(source, caps, idx); + gst_caps_unref(caps_for_render); + caps_for_render = caps; } - _add_probe_to_pad_for_render(source, idx, gst_element_get_static_pad(videoscaleCapsfilter, "src"), _source_data_probe_cb); + gst_object_unref(pad_for_render); + pad_for_render = gst_element_get_static_pad(videoscaleCapsfilter, "src"); } if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_SCREEN && !source->zerocopy_enabled) { + GstCaps *caps; + if (!(videocrop = _create_element(DEFAULT_ELEMENT_VIDEOCROP, ELEMENT_NAME_VIDEOCROP))) goto error; APPEND_ELEMENT(*element_list, videocrop); + + if ((caps = __make_default_raw_caps(source, &webrtc->ini))) { + PRINT_CAPS(caps, ELEMENT_NAME_VIDEOSCALE_CAPSFILTER); + + gst_caps_unref(caps_for_render); + caps_for_render = caps; + } + + gst_object_unref(pad_for_render); + pad_for_render = gst_element_get_static_pad(videocrop, "src"); } encoder = __prepare_encoder(webrtc, source, is_audio); - if (encoder == NULL) { - _remove_probe_from_pad_for_render(source, idx); - return WEBRTC_ERROR_INVALID_OPERATION; - } + if (encoder == NULL) + goto error; + APPEND_ELEMENT(*element_list, encoder); source->av[idx].render.need_decoding = false; @@ -1167,10 +1180,18 @@ skip_encoder: g_free(media_type); + if (caps_for_render) + _set_caps_for_render(source, caps_for_render, idx); + + if (pad_for_render) + _add_probe_to_pad_for_render(source, idx, pad_for_render, _source_data_probe_cb); + return WEBRTC_ERROR_NONE; error: - _remove_probe_from_pad_for_render(source, idx); + gst_caps_unref(caps_for_render); + gst_object_unref(pad_for_render); + g_free(media_type); return WEBRTC_ERROR_INVALID_OPERATION; @@ -1205,3 +1226,51 @@ void _set_video_src_resolution(webrtc_gst_slot_s *source, int width, int height) source->video_info.width = width; source->video_info.height = height; } + +GstCaps *_make_video_raw_caps_with_resolution(webrtc_gst_slot_s *source, webrtc_ini_s *ini, int width, int height) +{ + GstCaps *caps = NULL; + const ini_item_media_source_s *ini_source; + + RET_VAL_IF(source == NULL, NULL, "source is NULL"); + RET_VAL_IF(ini == NULL, NULL, "ini is NULL"); + + ini_source = _ini_get_source_by_type(ini, source->type); + if (ini_source == NULL) + ini_source = &ini->media_source; + + switch (source->type) { + case WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST: + case WEBRTC_MEDIA_SOURCE_TYPE_CAMERA: + case WEBRTC_MEDIA_SOURCE_TYPE_SCREEN: { + caps = gst_caps_new_simple(MEDIA_TYPE_VIDEO_RAW, + "format", G_TYPE_STRING, ini_source->v_raw_format, + "framerate", GST_TYPE_FRACTION, source->video_info.framerate, 1, + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + NULL); + break; + } + default: + LOG_ERROR_IF_REACHED("type(%d)", source->type); + break; + } + + return caps; +} + +int _update_caps_for_render_with_resolution(webrtc_gst_slot_s *source, int width, int height) +{ + GstCaps *new_caps; + + RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL"); + + if (!(new_caps = _make_video_raw_caps_with_resolution(source, &source->webrtc->ini, width, height))) + return WEBRTC_ERROR_INVALID_OPERATION; + PRINT_CAPS(new_caps, "appsrc"); + + _unset_caps_for_render(source, AV_IDX_VIDEO); + _set_caps_for_render(source, new_caps, AV_IDX_VIDEO); + + return WEBRTC_ERROR_NONE; +} diff --git a/src/webrtc_source_screen.c b/src/webrtc_source_screen.c index c5006f59..f8d14fac 100644 --- a/src/webrtc_source_screen.c +++ b/src/webrtc_source_screen.c @@ -28,9 +28,11 @@ int _set_screen_source_crop(webrtc_s *webrtc, unsigned int source_id, int x, int GstElement *videocrop = NULL; int src_width, src_height, output_width, output_height; int mirroring_x, mirroring_y, mirroring_width, mirroring_height; + int _width, _height; float rw, rh; int left, right, top, bottom; bool portrait_mode = true; + int ret; RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); RET_VAL_IF(source_id == 0, WEBRTC_ERROR_INVALID_PARAMETER, "source_id is 0"); @@ -88,10 +90,16 @@ int _set_screen_source_crop(webrtc_s *webrtc, unsigned int source_id, int x, int LOG_INFO("cropped: left:%d, right:%d, top:%d, bottom:%d", left, right, top, bottom); - *width = output_width - (left + right); - *height = output_height - (top + bottom); + _width = output_width - (left + right); + _height = output_height - (top + bottom); - _set_video_src_resolution(source, *width, *height); + if((ret = _update_caps_for_render_with_resolution(source, _width, _height)) != WEBRTC_ERROR_NONE) + return ret; + + _set_video_src_resolution(source, _width, _height); + + *width = _width; + *height = _height; LOG_INFO("source_id[%u], video resolution is changed [%dx%d] ==> [%dx%d]", source_id, output_width, output_height, *width, *height); @@ -103,6 +111,7 @@ int _unset_screen_source_crop(webrtc_s *webrtc, unsigned int source_id) webrtc_gst_slot_s *source = NULL; GstElement *videocrop = NULL; GstElement *screen_source = NULL; + int ret; RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); RET_VAL_IF(source_id == 0, WEBRTC_ERROR_INVALID_PARAMETER, "source_id is 0"); @@ -123,6 +132,9 @@ int _unset_screen_source_crop(webrtc_s *webrtc, unsigned int source_id) "bottom", 0, NULL); + if((ret = _update_caps_for_render_with_resolution(source, source->video_info.origin_width, source->video_info.origin_height)) != WEBRTC_ERROR_NONE) + return ret; + _set_video_src_resolution(source, source->video_info.origin_width, source->video_info.origin_height); return WEBRTC_ERROR_NONE;