From: Sangchul Lee Date: Thu, 22 Apr 2021 04:36:10 +0000 (+0900) Subject: webrtc_source: Release gst resources in case of error X-Git-Tag: submit/tizen/20210729.023123~89 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fad5b007d8b0a47ba15f88b09bfa086b3fc2160e;p=platform%2Fcore%2Fapi%2Fwebrtc.git webrtc_source: Release gst resources in case of error [Version] 0.1.152 [Issue Type] Improvement Change-Id: Ic9a5e8ffadae1384e5d3e2b7787e2df29382fabe Signed-off-by: Sangchul Lee --- diff --git a/include/webrtc_private.h b/include/webrtc_private.h index 0e24579e..8fbef603 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -159,6 +159,7 @@ do { \ } while (0) #define SAFE_FREE(src) { if (src) { free(src); src = NULL; } } +#define SAFE_GST_OBJECT_UNREF(src) { if (src) { gst_object_unref(src); src = NULL; } } #define SAFE_STR(str) (str) ? str : "null" #define CREATE_ELEMENT_FROM_REGISTRY(x_elem_info, x_klass_name, x_sink_caps, x_src_caps, x_element) \ diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index e7e83341..ff14f56f 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.1.151 +Version: 0.1.152 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc_source.c b/src/webrtc_source.c index fc63e22d..907a552d 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -711,11 +711,11 @@ static int __build_camerasrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) { int ret = WEBRTC_ERROR_NONE; GstElement *camerasrc; - GstElement *capsfilter; - GstElement *videoenc; - GstElement *videopay; - GstElement *queue; - GstElement *capsfilter2; + GstElement *capsfilter = NULL; + GstElement *videoenc = NULL; + GstElement *videopay = NULL; + GstElement *queue = NULL; + GstElement *capsfilter2 = 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"); @@ -738,26 +738,44 @@ static int __build_camerasrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) g_object_set(G_OBJECT(camerasrc), "empty-buffer-timeout", 0, NULL); if ((ret = __create_rest_of_elements(webrtc, source, &capsfilter, &videoenc, &videopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE) - return ret; + goto exit; gst_bin_add_many(source->bin, camerasrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL); if (!gst_element_link_many(camerasrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL)) { LOG_ERROR("failed to gst_element_link_many()"); - return WEBRTC_ERROR_INVALID_OPERATION; + ret = WEBRTC_ERROR_INVALID_OPERATION; + goto exit_with_remove_from_bin; } - return _set_ghost_pad_target(source->src_pad, capsfilter2, true); + ret = _set_ghost_pad_target(source->src_pad, capsfilter2, true); + if (ret != WEBRTC_ERROR_NONE) + goto exit_with_remove_from_bin; + + return WEBRTC_ERROR_NONE; + +exit_with_remove_from_bin: + /* elements will be dereferenced */ + gst_bin_remove_many(source->bin, camerasrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL); + return ret; +exit: + SAFE_GST_OBJECT_UNREF(camerasrc); + SAFE_GST_OBJECT_UNREF(capsfilter); + SAFE_GST_OBJECT_UNREF(videoenc); + SAFE_GST_OBJECT_UNREF(videopay); + SAFE_GST_OBJECT_UNREF(queue); + SAFE_GST_OBJECT_UNREF(capsfilter2); + return ret; } static int __build_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) { int ret = WEBRTC_ERROR_NONE; GstElement *audiosrc; - GstElement *capsfilter; - GstElement *audioenc; - GstElement *audiopay; - GstElement *queue; - GstElement *capsfilter2; + GstElement *capsfilter = NULL; + GstElement *audioenc = NULL; + GstElement *audiopay = NULL; + GstElement *queue = NULL; + GstElement *capsfilter2 = 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"); @@ -772,26 +790,44 @@ static int __build_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) } if ((ret = __create_rest_of_elements(webrtc, source, &capsfilter, &audioenc, &audiopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE) - return ret; + goto exit; gst_bin_add_many(source->bin, audiosrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL); if (!gst_element_link_many(audiosrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL)) { LOG_ERROR("failed to gst_element_link_many()"); - return WEBRTC_ERROR_INVALID_OPERATION; + ret = WEBRTC_ERROR_INVALID_OPERATION; + goto exit_with_remove_from_bin; } - return _set_ghost_pad_target(source->src_pad, capsfilter2, true); + ret = _set_ghost_pad_target(source->src_pad, capsfilter2, true); + if (ret != WEBRTC_ERROR_NONE) + goto exit_with_remove_from_bin; + + return WEBRTC_ERROR_NONE; + +exit_with_remove_from_bin: + /* elements will be dereferenced */ + gst_bin_remove_many(source->bin, audiosrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL); + return ret; +exit: + SAFE_GST_OBJECT_UNREF(audiosrc); + SAFE_GST_OBJECT_UNREF(capsfilter); + SAFE_GST_OBJECT_UNREF(audioenc); + SAFE_GST_OBJECT_UNREF(audiopay); + SAFE_GST_OBJECT_UNREF(queue); + SAFE_GST_OBJECT_UNREF(capsfilter2); + return ret; } static int __build_videotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) { int ret = WEBRTC_ERROR_NONE; GstElement *videotestsrc; - GstElement *capsfilter; - GstElement *videoenc; - GstElement *videopay; - GstElement *queue; - GstElement *capsfilter2; + GstElement *capsfilter = NULL; + GstElement *videoenc = NULL; + GstElement *videopay = NULL; + GstElement *queue = NULL; + GstElement *capsfilter2 = 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"); @@ -807,26 +843,44 @@ static int __build_videotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) g_object_set(G_OBJECT(videotestsrc), "is-live", TRUE, "pattern", 18, NULL); /* 18: ball */ if ((ret = __create_rest_of_elements(webrtc, source, &capsfilter, &videoenc, &videopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE) - return ret; + goto exit; gst_bin_add_many(source->bin, videotestsrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL); if (!gst_element_link_many(videotestsrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL)) { LOG_ERROR("failed to gst_element_link_many()"); - return WEBRTC_ERROR_INVALID_OPERATION; + ret = WEBRTC_ERROR_INVALID_OPERATION; + goto exit_with_remove_from_bin; } - return _set_ghost_pad_target(source->src_pad, capsfilter2, true); + ret = _set_ghost_pad_target(source->src_pad, capsfilter2, true); + if (ret != WEBRTC_ERROR_NONE) + goto exit_with_remove_from_bin; + + return WEBRTC_ERROR_NONE; + +exit_with_remove_from_bin: + /* elements will be dereferenced */ + gst_bin_remove_many(source->bin, videotestsrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL); + return ret; +exit: + SAFE_GST_OBJECT_UNREF(videotestsrc); + SAFE_GST_OBJECT_UNREF(capsfilter); + SAFE_GST_OBJECT_UNREF(videoenc); + SAFE_GST_OBJECT_UNREF(videopay); + SAFE_GST_OBJECT_UNREF(queue); + SAFE_GST_OBJECT_UNREF(capsfilter2); + return ret; } static int __build_audiotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) { int ret = WEBRTC_ERROR_NONE; GstElement *audiotestsrc; - GstElement *capsfilter; - GstElement *audioenc; - GstElement *audiopay; - GstElement *queue; - GstElement *capsfilter2; + GstElement *capsfilter = NULL; + GstElement *audioenc = NULL; + GstElement *audiopay = NULL; + GstElement *queue = NULL; + GstElement *capsfilter2 = 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"); @@ -842,15 +896,33 @@ static int __build_audiotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source) g_object_set(G_OBJECT(audiotestsrc), "is-live", TRUE, NULL); if ((ret = __create_rest_of_elements(webrtc, source, &capsfilter, &audioenc, &audiopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE) - return ret; + goto exit; gst_bin_add_many(source->bin, audiotestsrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL); if (!gst_element_link_many(audiotestsrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL)) { LOG_ERROR("failed to gst_element_link_many()"); - return WEBRTC_ERROR_INVALID_OPERATION; + ret = WEBRTC_ERROR_INVALID_OPERATION; + goto exit_with_remove_from_bin; } - return _set_ghost_pad_target(source->src_pad, capsfilter2, true); + ret = _set_ghost_pad_target(source->src_pad, capsfilter2, true); + if (ret != WEBRTC_ERROR_NONE) + goto exit_with_remove_from_bin; + + return WEBRTC_ERROR_NONE; + +exit_with_remove_from_bin: + /* elements will be dereferenced */ + gst_bin_remove_many(source->bin, audiotestsrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL); + return ret; +exit: + SAFE_GST_OBJECT_UNREF(audiotestsrc); + SAFE_GST_OBJECT_UNREF(capsfilter); + SAFE_GST_OBJECT_UNREF(audioenc); + SAFE_GST_OBJECT_UNREF(audiopay); + SAFE_GST_OBJECT_UNREF(queue); + SAFE_GST_OBJECT_UNREF(capsfilter2); + return ret; } static void _appsrc_need_data_cb(GstElement *appsrc, guint size, gpointer data)