From: Sangchul Lee Date: Tue, 2 Nov 2021 03:32:42 +0000 (+0900) Subject: webrtc_source: Improve error handling when failure on adding element to bin X-Git-Tag: submit/tizen/20211109.062149~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=81e6de0c6f86adbb41ca2653d9a1579fee3a0856;p=platform%2Fcore%2Fapi%2Fwebrtc.git webrtc_source: Improve error handling when failure on adding element to bin If an error occurs when calling gst_bin_add() for element list, error handling codes for unreferencing the elements should be divided with two phases, one is for elements already added to the bin, the other one is for the rest of elements in the list. [Version] 0.2.144 [Issue Type] Improvement Change-Id: Ie5a8c9eaa0f8dd462ec0079a59e85ebc1b8f070a Signed-off-by: Sangchul Lee --- diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 6a94242a..4e528b6c 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.2.143 +Version: 0.2.144 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc_source.c b/src/webrtc_source.c index 66d52c01..9932ab99 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -1130,7 +1130,7 @@ static void __remove_probe_from_pad_for_pause(webrtc_gst_slot_s *source, unsigne source->av[idx].src_pad = NULL; } -static bool __add_elements_to_bin(GstBin *bin, GList *element_list) +static bool __remove_elements_from_bin(GstBin *bin, GList *element_list) { GstElement *element; GList *list; @@ -1139,35 +1139,50 @@ static bool __add_elements_to_bin(GstBin *bin, GList *element_list) RET_VAL_IF(bin == NULL, false, "bin is NULL"); RET_VAL_IF(element_list == NULL, false, "element_list is NULL"); - for (list = element_list; list; list = list->next) { + for (list = element_list; list; list = g_list_next(list)) { element = (GstElement *)list->data; - RET_VAL_IF(!gst_bin_add(bin, element), false, - "failed to gst_bin_add(), bin[%s], element[%s]", GST_ELEMENT_NAME(bin), GST_ELEMENT_NAME(element)); + RET_VAL_IF(!gst_bin_remove(bin, element), false, + "failed to gst_bin_remove(), bin[%s], element[%s]", GST_ELEMENT_NAME(bin), GST_ELEMENT_NAME(element)); count++; } - LOG_DEBUG("%d elements are added to bin[%s]", count, GST_ELEMENT_NAME(bin)); + LOG_DEBUG("%d elements are removed from bin[%s]", count, GST_ELEMENT_NAME(bin)); return true; } -static bool __remove_elements_from_bin(GstBin *bin, GList *element_list) +static void __foreach_unref_object_cb(gpointer data, gpointer user_data) +{ + GstElement *element = (GstElement *)data; + + LOG_DEBUG("%s is unreferenced", GST_ELEMENT_NAME(element)); + SAFE_GST_OBJECT_UNREF(element); +} + +static bool __add_elements_to_bin(GstBin *bin, GList *element_list) { GstElement *element; GList *list; - int count = 0; + GList *added_list = NULL; RET_VAL_IF(bin == NULL, false, "bin is NULL"); RET_VAL_IF(element_list == NULL, false, "element_list is NULL"); - for (list = element_list; list; list = g_list_next(list)) { + for (list = element_list; list; list = list->next) { element = (GstElement *)list->data; - RET_VAL_IF(!gst_bin_remove(bin, element), false, - "failed to gst_bin_remove(), bin[%s], element[%s]", GST_ELEMENT_NAME(bin), GST_ELEMENT_NAME(element)); - count++; + if (!gst_bin_add(bin, element)) { + LOG_ERROR("failed to gst_bin_add(), bin[%s], element[%s]", GST_ELEMENT_NAME(bin), GST_ELEMENT_NAME(element)); + __remove_elements_from_bin(bin, added_list); + SAFE_G_LIST_FREE(added_list); + g_list_foreach(list, __foreach_unref_object_cb, NULL); /* rest of elements on the list should be unreferenced */ + return false; + } + APPEND_ELEMENT(added_list, element); } - LOG_DEBUG("%d elements are removed from bin[%s]", count, GST_ELEMENT_NAME(bin)); + LOG_DEBUG("%d elements are added to bin[%s]", g_list_length(added_list), GST_ELEMENT_NAME(bin)); + + SAFE_G_LIST_FREE(added_list); return true; } @@ -1304,12 +1319,16 @@ static int __build_screensrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) if ((ret = __create_rest_of_elements(webrtc, source, true, &element_list, false)) != WEBRTC_ERROR_NONE) goto exit; - if (!__add_elements_to_bin(source->bin, switch_src_list)) - goto exit; + if (!__add_elements_to_bin(source->bin, switch_src_list)) { + SAFE_G_LIST_FREE(switch_src_list); + return WEBRTC_ERROR_INVALID_OPERATION; + } if (!__add_elements_to_bin(source->bin, element_list)) { - ret = WEBRTC_ERROR_INVALID_OPERATION; - goto exit_with_remove_from_bin; + __remove_elements_from_bin(source->bin, switch_src_list); + SAFE_G_LIST_FREE(switch_src_list); + SAFE_G_LIST_FREE(element_list); + return WEBRTC_ERROR_INVALID_OPERATION; } if (!__link_switch_srcs(videoswitch, switch_src_list)) { @@ -1384,8 +1403,10 @@ static int __build_camerasrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) if ((ret = __create_rest_of_elements(webrtc, source, true, &element_list, false)) != WEBRTC_ERROR_NONE) goto exit; - if (!__add_elements_to_bin(source->bin, element_list)) - goto exit; + if (!__add_elements_to_bin(source->bin, element_list)) { + SAFE_G_LIST_FREE(element_list); + return WEBRTC_ERROR_INVALID_OPERATION; + } if (!__link_elements(element_list)) { ret = WEBRTC_ERROR_INVALID_OPERATION; @@ -1450,8 +1471,10 @@ static int __build_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool us if ((ret = __create_rest_of_elements(webrtc, source, true, &element_list, true)) != WEBRTC_ERROR_NONE) goto exit; - if (!__add_elements_to_bin(source->bin, element_list)) - goto exit; + if (!__add_elements_to_bin(source->bin, element_list)) { + SAFE_G_LIST_FREE(element_list); + return WEBRTC_ERROR_INVALID_OPERATION; + } if (!__link_elements(element_list)) { ret = WEBRTC_ERROR_INVALID_OPERATION; @@ -1511,8 +1534,10 @@ static int __build_videotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) if ((ret = __create_rest_of_elements(webrtc, source, true, &element_list, false)) != WEBRTC_ERROR_NONE) goto exit; - if (!__add_elements_to_bin(source->bin, element_list)) - goto exit; + if (!__add_elements_to_bin(source->bin, element_list)) { + SAFE_G_LIST_FREE(element_list); + return WEBRTC_ERROR_INVALID_OPERATION; + } if (!__link_elements(element_list)) { ret = WEBRTC_ERROR_INVALID_OPERATION; @@ -1568,8 +1593,10 @@ static int __build_custom_videosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) if ((ret = __create_rest_of_elements(webrtc, source, true, &element_list, false)) != WEBRTC_ERROR_NONE) goto exit; - if (!__add_elements_to_bin(source->bin, element_list)) - goto exit; + if (!__add_elements_to_bin(source->bin, element_list)) { + SAFE_G_LIST_FREE(element_list); + return WEBRTC_ERROR_INVALID_OPERATION; + } if (!__link_elements(element_list)) { ret = WEBRTC_ERROR_INVALID_OPERATION; @@ -1631,8 +1658,10 @@ static int __build_custom_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) if ((ret = __create_rest_of_elements(webrtc, source, true, &element_list, true)) != WEBRTC_ERROR_NONE) goto exit; - if (!__add_elements_to_bin(source->bin, element_list)) - goto exit; + if (!__add_elements_to_bin(source->bin, element_list)) { + SAFE_G_LIST_FREE(element_list); + return WEBRTC_ERROR_INVALID_OPERATION; + } if (!__link_elements(element_list)) { ret = WEBRTC_ERROR_INVALID_OPERATION; @@ -1697,8 +1726,10 @@ static int __build_filesrc_bin(webrtc_gst_slot_s *source, media_type_e media_typ goto exit; APPEND_ELEMENT(element_list, capsfilter); - if (!__add_elements_to_bin(source->bin, element_list)) - goto exit; + if (!__add_elements_to_bin(source->bin, element_list)) { + SAFE_G_LIST_FREE(element_list); + return WEBRTC_ERROR_INVALID_OPERATION; + } if (!__link_elements(element_list)) goto exit_with_remove_from_bin; @@ -1901,8 +1932,10 @@ static int __create_rest_of_elements_for_filesrc_pipeline(webrtc_gst_slot_s *sou goto exit; APPEND_ELEMENT(element_list, fakesink); - if (!__add_elements_to_bin(bin, element_list)) - goto exit; + if (!__add_elements_to_bin(bin, element_list)) { + SAFE_G_LIST_FREE(element_list); + return WEBRTC_ERROR_INVALID_OPERATION; + } if (!__link_elements(element_list)) goto exit_with_remove_from_bin; @@ -2264,19 +2297,22 @@ static int __complete_mediapacketsrc_from_raw_format(webrtc_s *webrtc, webrtc_gs source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types); if ((ret = __create_rest_of_elements(webrtc, source, false, &element_list, (source->media_types == MEDIA_TYPE_AUDIO))) != WEBRTC_ERROR_NONE) - return ret; + goto exit; if (!(sink_caps = __make_raw_caps_from_media_format(source))) { LOG_ERROR("failed to __make_raw_caps_from_media_format()"); - return WEBRTC_ERROR_INVALID_OPERATION; + ret = WEBRTC_ERROR_INVALID_OPERATION; + goto exit; } PRINT_CAPS(sink_caps, "appsrc"); g_object_set(G_OBJECT(appsrc), "caps", sink_caps, NULL); gst_caps_unref(sink_caps); - if (!__add_elements_to_bin(source->bin, element_list)) - goto exit; + if (!__add_elements_to_bin(source->bin, element_list)) { + SAFE_G_LIST_FREE(element_list); + return WEBRTC_ERROR_INVALID_OPERATION; + } PREPEND_ELEMENT(element_list, appsrc); if (!__link_elements(element_list)) { @@ -3741,8 +3777,10 @@ static int __build_loopback_audiosink(webrtc_gst_slot_s *source, GstElement *lin } g_object_set(G_OBJECT(audiosink), "sync", FALSE, NULL); - if (!__add_elements_to_bin(GST_BIN(source->av[AV_IDX_AUDIO].render.pipeline), element_list)) - goto exit; + if (!__add_elements_to_bin(GST_BIN(source->av[AV_IDX_AUDIO].render.pipeline), element_list)) { + SAFE_G_LIST_FREE(element_list); + return WEBRTC_ERROR_INVALID_OPERATION; + } if (!__link_elements(element_list)) goto exit_with_remove_from_bin; @@ -3830,8 +3868,10 @@ static int __build_loopback_videosink(webrtc_gst_slot_s *source, GstElement *lin _connect_and_append_signal(&source->signals, (GObject *)videosink, "handoff", G_CALLBACK(_video_stream_decoded_cb), source->display); } - if (!__add_elements_to_bin(GST_BIN(source->av[AV_IDX_VIDEO].render.pipeline), element_list)) - goto exit; + if (!__add_elements_to_bin(GST_BIN(source->av[AV_IDX_VIDEO].render.pipeline), element_list)) { + SAFE_G_LIST_FREE(element_list); + return WEBRTC_ERROR_INVALID_OPERATION; + } if (!__link_elements(element_list)) goto exit_with_remove_from_bin;