webrtc_source: Release gst resources in case of error 74/257274/3
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 22 Apr 2021 04:36:10 +0000 (13:36 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 22 Apr 2021 09:43:42 +0000 (18:43 +0900)
[Version] 0.1.152
[Issue Type] Improvement

Change-Id: Ic9a5e8ffadae1384e5d3e2b7787e2df29382fabe
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc_source.c

index 0e24579e06d0c7841c10a57bd1c5ab872fc8e7f5..8fbef60324386f6a17ea80282c141ae1aec990b3 100644 (file)
@@ -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) \
index e7e83341d59ac621e19486d9985ee1f108340b9a..ff14f56f3b6a693037d3b67d3e209a6860d2a2c4 100644 (file)
@@ -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
index fc63e22de43ed10d33b36d83f9fd9d58ae6547b8..907a552d0ac5ddddde4e53d2106393fe63f7caa8 100644 (file)
@@ -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)