return WEBRTC_ERROR_INVALID_OPERATION;
}
-static void __remove_rest_of_filesrc_element(webrtc_gst_slot_s *source, bool is_audio)
+static void __remove_rest_of_elements_for_filesrc_pipeline(webrtc_gst_slot_s *source, bool is_audio)
{
- GstElement *queue = NULL;
+ GstBin *bin = NULL;
+
+ GstElement *payload = NULL;
GstElement *capsfilter = NULL;
+ GstElement *fakesink = NULL;
+
+ RET_IF(source == NULL, "pad is NULL");
+
+ bin = GST_BIN(source->filesrc_pipeline);
- queue = gst_bin_get_by_name(source->bin, is_audio ? DEFAULT_NAME_AUDIO_QUEUE : DEFAULT_NAME_VIDEO_QUEUE);
- RET_IF(queue == NULL, "queue is NULL");
+ payload = gst_bin_get_by_name(bin, is_audio ? DEFAULT_NAME_AUDIO_PAYLOAD: DEFAULT_NAME_VIDEO_PAYLOAD);
+ RET_IF(payload == NULL, "payload is NULL");
- capsfilter = gst_bin_get_by_name(source->bin, is_audio ? DEFAULT_NAME_AUDIO_CAPSFILTER : DEFAULT_NAME_VIDEO_CAPSFILTER);
+ capsfilter = gst_bin_get_by_name(bin, is_audio ? DEFAULT_NAME_AUDIO_CAPSFILTER : DEFAULT_NAME_VIDEO_CAPSFILTER);
RET_IF(capsfilter == NULL, "capsfilter is NULL");
- gst_bin_remove_many(source->bin, queue, capsfilter, NULL);
+ fakesink = gst_bin_get_by_name(bin, is_audio ? DEFAULT_NAME_AUDIO_FAKESINK: DEFAULT_NAME_VIDEO_FAKESINK);
+ RET_IF(fakesink == NULL, "fakesink is NULL");
+
+ gst_bin_remove_many(bin, payload, capsfilter, fakesink, NULL);
}
static void __filesrc_pipeline_audio_stream_handoff_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data)
return GST_PAD_PROBE_REMOVE;
}
+static GstElement * __create_payload_for_filesrc_pipeline(GstPad *pad, bool is_audio)
+{
+ element_info_s elem_info;
+ GstElement *payload = NULL;
+
+ RET_VAL_IF(pad == NULL, NULL, "pad is NULL");
+
+ CREATE_ELEMENT_FROM_REGISTRY(elem_info, GST_KLASS_NAME_PAYLOADER_RTP,
+ gst_pad_get_current_caps(pad),
+ NULL,
+ payload);
+
+ RET_VAL_IF(payload == NULL, NULL, "payload is NULL");
+
+ gst_element_set_name(payload, is_audio ? DEFAULT_NAME_AUDIO_PAYLOAD : DEFAULT_NAME_VIDEO_PAYLOAD);
+
+ return payload;
+}
+
static GstElement * __prepare_capsfilter_for_filesrc_pipeline(webrtc_gst_slot_s *source, bool is_audio)
{
GstElement *capsfilter = NULL;
return fakesink;
}
-static int __create_rest_of_elements_for_filesrc_pipeline(webrtc_gst_slot_s *source, GstElement *payloader, bool is_audio)
+static int __create_rest_of_elements_for_filesrc_pipeline(webrtc_gst_slot_s *source, GstPad *pad, bool is_audio)
{
GstBin *bin = NULL;
+ GstElement *payload = NULL;
GstElement *capsfilter = NULL;
GstElement *fakesink = NULL;
RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
- RET_VAL_IF(payloader == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "payloader is NULL");
RET_VAL_IF(source->filesrc_pipeline == NULL, WEBRTC_ERROR_INVALID_OPERATION, "filesrc_pipeline is NULL");
bin = GST_BIN(source->filesrc_pipeline);
- if (!(capsfilter = __prepare_capsfilter_for_filesrc_pipeline(source, is_audio)))
+ if (!(payload = __create_payload_for_filesrc_pipeline(pad, is_audio)))
return WEBRTC_ERROR_INVALID_OPERATION;
+ if (!(capsfilter = __prepare_capsfilter_for_filesrc_pipeline(source, is_audio))) {
+ SAFE_GST_OBJECT_UNREF(payload);
+ return WEBRTC_ERROR_INVALID_OPERATION;
+ }
if (!(fakesink = __prepare_fakesink_for_filesrc_pipeline(source, is_audio))) {
+ SAFE_GST_OBJECT_UNREF(payload);
SAFE_GST_OBJECT_UNREF(capsfilter);
return WEBRTC_ERROR_INVALID_OPERATION;
}
- gst_bin_add_many(bin, capsfilter, fakesink, NULL);
+ gst_bin_add_many(bin, payload, capsfilter, fakesink, NULL);
- if (!gst_element_link_many(payloader, capsfilter, fakesink, NULL)) {
+ if (!gst_element_link_many(payload, capsfilter, fakesink, NULL)) {
LOG_ERROR("failed to gst_element_link_many()");
goto error;
}
+ if (!gst_element_sync_state_with_parent(payload)) {
+ LOG_ERROR("failed to gst_element_sync_state_with_parent() for [%s]", GST_ELEMENT_NAME(payload));
+ goto error;
+ }
+
if (!gst_element_sync_state_with_parent(capsfilter)) {
LOG_ERROR("failed to gst_element_sync_state_with_parent() for [%s]", GST_ELEMENT_NAME(capsfilter));
goto error;
return WEBRTC_ERROR_NONE;
error:
- gst_bin_remove_many(bin, capsfilter, fakesink, NULL);
+ gst_bin_remove_many(bin, payload, capsfilter, fakesink, NULL);
return WEBRTC_ERROR_INVALID_OPERATION;
}
-static GstElement * __link_decodebin_with_payload(GstPad *pad, webrtc_gst_slot_s *source, bool is_audio, bool create)
+static int __link_decodebin_with_payload(GstPad *pad, webrtc_gst_slot_s *source, bool is_audio)
{
- element_info_s elem_info;
- GstBin *bin = NULL;
GstElement *payload = NULL;
- GstPad *payload_sink_pad = NULL;
-
- RET_VAL_IF(pad == NULL, NULL, "pad is NULL");
- RET_VAL_IF(source == NULL, NULL, "source is NULL");
- RET_VAL_IF(source->filesrc_pipeline == NULL, NULL, "filesrc_pipeline is NULL");
-
- bin = GST_BIN(source->filesrc_pipeline);
-
- if (create) {
- CREATE_ELEMENT_FROM_REGISTRY(elem_info, GST_KLASS_NAME_PAYLOADER_RTP,
- gst_pad_get_current_caps(pad),
- NULL,
- payload);
-
- RET_VAL_IF(payload == NULL, NULL, "There is no payload that supports this content.");
-
- gst_element_set_name(payload, is_audio ? DEFAULT_NAME_AUDIO_PAYLOAD : DEFAULT_NAME_VIDEO_PAYLOAD);
+ GstPad *sink_pad = NULL;
- gst_bin_add(bin, payload);
+ RET_VAL_IF(pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "pad is NULL");
+ RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
- if (!gst_element_sync_state_with_parent(payload)) {
- LOG_ERROR("failed to gst_element_sync_state_with_parent() for [%s]", GST_ELEMENT_NAME(payload));
- gst_bin_remove(bin, payload);
- return NULL;
- }
- } else {
- payload = gst_bin_get_by_name(bin, is_audio ? DEFAULT_NAME_AUDIO_PAYLOAD : DEFAULT_NAME_VIDEO_PAYLOAD);
- RET_VAL_IF(payload == NULL, NULL, "There is no payload to link");
+ payload = gst_bin_get_by_name(GST_BIN(source->filesrc_pipeline), is_audio ? DEFAULT_NAME_AUDIO_PAYLOAD : DEFAULT_NAME_VIDEO_PAYLOAD);
+ if (!payload) {
+ LOG_ERROR("failed to get element [%s]", is_audio ? DEFAULT_NAME_AUDIO_PAYLOAD : DEFAULT_NAME_VIDEO_PAYLOAD);
+ return WEBRTC_ERROR_INVALID_OPERATION;
}
- payload_sink_pad = gst_element_get_static_pad(payload, "sink");
- if (!payload_sink_pad) {
- LOG_ERROR("payload_sink_pad is NULL");
- gst_bin_remove(bin, payload);
- return NULL;
+ sink_pad = gst_element_get_static_pad(payload, "sink");
+ if (!sink_pad) {
+ LOG_ERROR("sink_pad is NULL for [%s]", GST_ELEMENT_NAME(payload));
+ return WEBRTC_ERROR_INVALID_OPERATION;
}
- if (gst_pad_link(pad, payload_sink_pad) != GST_PAD_LINK_OK) {
+ if (gst_pad_link(pad, sink_pad) != GST_PAD_LINK_OK) {
LOG_ERROR("failed to gst_pad_link()");
- gst_bin_remove(bin, payload);
- g_object_unref(payload_sink_pad);
- return NULL;
+ g_object_unref(sink_pad);
+ return WEBRTC_ERROR_INVALID_OPERATION;
}
- g_object_unref(payload_sink_pad);
+ g_object_unref(sink_pad);
LOG_INFO("decodebin is linked to [%s]", GST_ELEMENT_NAME(payload));
- return payload;
+ return WEBRTC_ERROR_NONE;
}
static void __filesrc_pipeline_decodebin_pad_added_cb(GstElement *element, GstPad *pad, gpointer data)
{
int ret = WEBRTC_ERROR_NONE;
webrtc_gst_slot_s *source = data;
- GstBin *bin = NULL;
const gchar *media_type = NULL;
- GstElement *payload = NULL;
gboolean is_audio;
int av_idx;
RET_IF(source == NULL, "source is NULL");
RET_IF(source->filesrc_pipeline == NULL, "filesrc_pipeline is NULL");
- bin = GST_BIN(source->filesrc_pipeline);
-
media_type = gst_structure_get_name(gst_caps_get_structure(gst_pad_get_current_caps(pad), 0));
RET_IF(media_type == NULL, "media_type is NULL");
if (source->av[av_idx].src_pad_probe_id > 0) {
LOG_INFO("Pipeline already built");
- __link_decodebin_with_payload(pad, source, is_audio, false);
+ __link_decodebin_with_payload(pad, source, is_audio);
return;
}
- payload = __link_decodebin_with_payload(pad, source, is_audio, true);
- RET_IF(payload == NULL, "failed to __link_decodebin_with_payload()");
-
- ret = __create_rest_of_elements_for_filesrc_pipeline(source, payload, is_audio);
+ ret = __create_rest_of_elements_for_filesrc_pipeline(source, pad, is_audio);
if (ret != WEBRTC_ERROR_NONE) {
LOG_ERROR("failed to __create_rest_of_elements_for_filesrc_pipeline()");
- gst_bin_remove(bin, payload);
+ return;
+ }
+
+ ret = __link_decodebin_with_payload(pad, source, is_audio);
+ if (ret != WEBRTC_ERROR_NONE) {
+ LOG_ERROR("failed to __link_decodebin_with_payload()");
+ __remove_rest_of_elements_for_filesrc_pipeline(source, is_audio);
return;
}
ret = __build_filesrc_bin(source, is_audio ? MEDIA_TYPE_AUDIO : MEDIA_TYPE_VIDEO);
if (ret != WEBRTC_ERROR_NONE) {
LOG_ERROR("failed to __build_filesrc_bin()");
- gst_bin_remove(bin, payload);
+ __remove_rest_of_elements_for_filesrc_pipeline(source, is_audio);
return;
}
ret = __link_source_with_webrtcbin(source, source->webrtc->gst.webrtcbin);
if (ret != WEBRTC_ERROR_NONE) {
LOG_ERROR("failed to __link_source_with_webrtcbin()");
- gst_bin_remove(bin, payload);
- __remove_rest_of_filesrc_element(source, is_audio);
+ __remove_rest_of_elements_for_filesrc_pipeline(source, is_audio);
g_hash_table_remove(source->webrtc->gst.source_slots, GST_ELEMENT_NAME(source->bin));
return;
}