From: hj kim Date: Fri, 19 Aug 2022 01:38:55 +0000 (+0900) Subject: webrtc_source: fix crash when change resolution while loopback X-Git-Tag: submit/tizen/20220823.080652~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e4259f971de2e6ddc5d1afebd3da5ed488ca89be;p=platform%2Fcore%2Fapi%2Fwebrtc.git webrtc_source: fix crash when change resolution while loopback 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 --- diff --git a/include/webrtc_source_private.h b/include/webrtc_source_private.h index b81b0d8b..11044664 100644 --- a/include/webrtc_source_private.h +++ b/include/webrtc_source_private.h @@ -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__ */ diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index eea71f04..0275d992 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.205 +Version: 0.3.206 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc_source.c b/src/webrtc_source.c index 20573baa..e8417976 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -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; } diff --git a/src/webrtc_source_private.c b/src/webrtc_source_private.c index 8bb77b40..fc72187a 100644 --- a/src/webrtc_source_private.c +++ b/src/webrtc_source_private.c @@ -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; +}