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;
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;
}
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)) {
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;
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;
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;
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;
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;
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;
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;
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)) {
}
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;
_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;