webrtc_source: fix crash when change resolution while loopback 88/279888/14
authorhj kim <backto.kim@samsung.com>
Fri, 19 Aug 2022 01:38:55 +0000 (10:38 +0900)
committerhj kim <backto.kim@samsung.com>
Tue, 23 Aug 2022 06:39:06 +0000 (15:39 +0900)
For sources whose resolution is dynamically changed, caps of appsrc for loopback should be changed as well.
Plus, initialize app source related information when destroy loopback pipeline.

[Version] 0.2.206
[Issue Type] Bug fix

Change-Id: I3dc9bd35a8e8f6075885eebd6f50af818054c4d4

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

index b81b0d8b3d2bf914bf149b408bac4def9063993f..1104466486658ca746188758bad834b3f304a7ef 100644 (file)
@@ -110,5 +110,7 @@ int _link_source_with_webrtcbin(webrtc_gst_slot_s *source, GstElement *webrtcbin
 int _create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool need_capsfilter, GList **element_list, bool is_audio);
 int _set_encoder_element_bitrate(GstElement *encoder, int target_bitrate);
 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);
 
 #endif /* __TIZEN_MEDIA_WEBRTC_SOURCE_COMMON_H__ */
index eea71f0429d52e418a507f34764b7b15a348acac..0275d99221a1da8491a2f72b31226f8ee8d3122e 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.3.205
+Version:    0.3.206
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 20573baab1577adf16e9524db3c62db08277aaf5..e8417976515f54a591fa666a52a05b362865aac9 100644 (file)
@@ -1403,6 +1403,17 @@ int _set_video_resolution(webrtc_s *webrtc, unsigned int source_id, int width, i
                gst_caps_unref(new_caps);
        }
 
+       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);
+       }
+
        source->video_info.width = width;
        source->video_info.height = height;
 
@@ -2463,6 +2474,8 @@ int _unset_audio_loopback(webrtc_s *webrtc, unsigned int source_id)
        gst_element_set_state(source->av[AV_IDX_AUDIO].render.pipeline, GST_STATE_NULL);
        SAFE_GST_OBJECT_UNREF(source->av[AV_IDX_AUDIO].render.pipeline);
 
+       source->av[AV_IDX_AUDIO].render.appsrc = NULL;
+
        return WEBRTC_ERROR_NONE;
 }
 
@@ -2532,6 +2545,8 @@ int _unset_video_loopback(webrtc_s *webrtc, unsigned int source_id)
        gst_element_set_state(source->av[AV_IDX_VIDEO].render.pipeline, GST_STATE_NULL);
        SAFE_GST_OBJECT_UNREF(source->av[AV_IDX_VIDEO].render.pipeline);
 
+       source->av[AV_IDX_VIDEO].render.appsrc = NULL;
+
        return WEBRTC_ERROR_NONE;
 }
 
index 8bb77b40e4fc83eb8e3d3b9e346b2975fac70784..fc72187ac954f63819048009547020fff5fc9904 100644 (file)
@@ -572,10 +572,7 @@ void _remove_probe_from_pad_for_render(webrtc_gst_slot_s *source, unsigned int i
        gst_object_unref(source->av[idx].render.src_pad);
        source->av[idx].render.src_pad = NULL;
 
-       if (source->av[idx].render.appsrc_caps) {
-               gst_caps_unref(source->av[idx].render.appsrc_caps);
-               source->av[idx].render.appsrc_caps = NULL;
-       }
+       _unset_caps_for_render(source, idx);
 }
 
 rtp_payload_info_s * _get_payload_info(webrtc_transceiver_codec_e codec)
@@ -1058,9 +1055,8 @@ int _create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool n
                        if ((sink_caps = __make_default_encoded_caps(source, &webrtc->ini, NULL))) {
                                PRINT_CAPS(sink_caps, "capsfilter");
                                g_object_set(G_OBJECT(capsfilter), "caps", sink_caps, NULL);
-                               source->av[idx].render.appsrc_caps = sink_caps;
-                               if (source->av[idx].render.appsrc)
-                                       g_object_set(G_OBJECT(source->av[idx].render.appsrc), "caps", sink_caps, NULL);
+
+                               _set_caps_for_render(source, sink_caps, idx);
                        }
 
                        source->av[idx].render.need_decoding = true;
@@ -1072,9 +1068,8 @@ int _create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool n
                if ((sink_caps = __make_default_raw_caps(source, &webrtc->ini))) {
                        PRINT_CAPS(sink_caps, "capsfilter");
                        g_object_set(G_OBJECT(capsfilter), "caps", sink_caps, NULL);
-                       source->av[idx].render.appsrc_caps = sink_caps;
-                       if (source->av[idx].render.appsrc)
-                               g_object_set(G_OBJECT(source->av[idx].render.appsrc), "caps", sink_caps, NULL);
+
+                       _set_caps_for_render(source, sink_caps, idx);
                }
 
                _add_probe_to_pad_for_render(source, idx, gst_element_get_static_pad(capsfilter, "src"), _source_data_probe_cb);
@@ -1150,3 +1145,25 @@ error:
 
        return WEBRTC_ERROR_INVALID_OPERATION;
 }
+
+void _set_caps_for_render(webrtc_gst_slot_s *source, GstCaps *caps, int av_idx)
+{
+       RET_IF(source == NULL, "source is NULL");
+       RET_IF(caps == NULL, "caps is NULL");
+
+       source->av[av_idx].render.appsrc_caps = caps;
+
+       if (source->av[av_idx].render.appsrc)
+               g_object_set(G_OBJECT(source->av[av_idx].render.appsrc), "caps", caps, NULL);
+}
+
+void _unset_caps_for_render(webrtc_gst_slot_s *source, int av_idx)
+{
+       RET_IF(source == NULL, "source is NULL");
+
+       if (!(source->av[av_idx].render.appsrc_caps))
+               return;
+
+       gst_caps_unref(source->av[av_idx].render.appsrc_caps);
+       source->av[av_idx].render.appsrc_caps = NULL;
+}