webrtc_source_screen: move pad probe position for loopback on crop 43/280143/15
authorhj kim <backto.kim@samsung.com>
Wed, 24 Aug 2022 08:53:03 +0000 (17:53 +0900)
committerhj kim <backto.kim@samsung.com>
Wed, 31 Aug 2022 23:46:16 +0000 (08:46 +0900)
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

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

index 7de4fe8a2755e723902d3fa4005d8b29dabfe5b4..8ac609720f880ece612de21ee69c3d4b687311c8 100644 (file)
@@ -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__ */
index 3547844694a27c0823dec858487a53776cd57422..c771cc628e5705c424b4c75cee804bf0810a6b53 100644 (file)
@@ -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
index 553f481018ba02bc6e804baa59b9a37223e073b3..3b54adefec75c85349b98a3c066a4e833ac37312 100644 (file)
@@ -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);
index 31bbdf3a76c94c71a10a4f39689314255fb33894..7448aab71c81cb4e87dd32c42c8efae4ddde9919 100644 (file)
@@ -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;
+}
index c5006f59666f8f18faccd58b24c931695ec6a46c..f8d14fac1ee9b792236ba4adf9bad9151406082d 100644 (file)
@@ -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;