g_mutex_unlock(&ms_streamer->mutex_lock);
}
-static void _sink_node_unlock_state(const GValue * item, gpointer user_data)
-{
- GstElement *sink_element = GST_ELEMENT(g_value_get_object(item));
- ms_retm_if(!sink_element, "Handle is NULL");
-
- if (gst_element_is_locked_state(sink_element)) {
- gst_element_set_locked_state(sink_element, FALSE);
- gst_element_sync_state_with_parent(sink_element);
- }
-}
-
static void __decodebin_nomore_pads_combine(GstPad *src_pad, media_streamer_s *ms_streamer, gboolean is_server_part)
{
GstElement *found_element = NULL;
const gchar *new_pad_type = __ms_get_pad_type(src_pad);
if (MS_ELEMENT_IS_VIDEO(new_pad_type)) {
- found_element = __ms_bin_find_element_by_type(parent_element, src_pad, ms_streamer->topology_bin, __ms_node_get_klass_by_its_type(MEDIA_STREAMER_NODE_TYPE_TEXT_OVERLAY));
- if (found_element) {
- ms_info(" Overlay Element [%s]", GST_ELEMENT_NAME(found_element));
- src_pad = NULL;
- } else {
- found_element = parent_element;
- }
+ found_element = __ms_bin_find_element_by_type(parent_element, src_pad, ms_streamer->topology_bin, __ms_node_get_klass_by_its_type(MEDIA_STREAMER_NODE_TYPE_TEXT_OVERLAY));
+ if (found_element) {
+ ms_info(" Overlay Element [%s]", GST_ELEMENT_NAME(found_element));
+ src_pad = NULL;
+ } else {
+ found_element = parent_element;
+ }
if (is_server_part) {
found_element = __ms_combine_next_element(found_element, src_pad, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_VIDEO_ENCODER);
found_element = __ms_combine_next_element(found_element, NULL, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_VIDEO_PAY);
found_element = __ms_combine_next_element(found_element, NULL, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_RTP);
} else {
found_element = __ms_combine_next_element(found_element, src_pad, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_VIDEO_CONVERTER);
- found_element = __ms_combine_next_element(found_element, NULL, ms_streamer->sink_bin, MEDIA_STREAMER_NODE_TYPE_QUEUE);
found_element = __ms_combine_next_element(found_element, NULL, ms_streamer->sink_bin, MEDIA_STREAMER_NODE_TYPE_SINK);
}
} else if (MS_ELEMENT_IS_AUDIO(new_pad_type)) {
found_element = __ms_combine_next_element(found_element, NULL, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_AUDIO_PAY);
found_element = __ms_combine_next_element(found_element, NULL, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_RTP);
} else {
- found_element = __ms_combine_next_element(parent_element, src_pad, ms_streamer->sink_bin, MEDIA_STREAMER_NODE_TYPE_QUEUE);
- found_element = __ms_combine_next_element(found_element, NULL, ms_streamer->sink_bin, MEDIA_STREAMER_NODE_TYPE_SINK);
+ found_element = __ms_combine_next_element(parent_element, src_pad, ms_streamer->sink_bin, MEDIA_STREAMER_NODE_TYPE_SINK);
}
} else if (MS_ELEMENT_IS_TEXT(new_pad_type)) {
found_element = __ms_combine_next_element(parent_element, src_pad, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_TEXT_OVERLAY);
__ms_generate_dots(ms_streamer->pipeline, "after_sink_linked");
}
-static void __decodebin_nomore_pads_cb(GstElement * decodebin, gpointer user_data)
+static void __decodebin_nomore_pads_cb(GstElement *decodebin, gpointer user_data)
{
media_streamer_s *ms_streamer = (media_streamer_s *) user_data;
ms_retm_if(ms_streamer == NULL, "Handle is NULL");
__decodebin_nomore_pads_combine(src_pad, ms_streamer, is_server_part);
}
- MS_BIN_FOREACH_ELEMENTS(ms_streamer->sink_bin, _sink_node_unlock_state, NULL);
g_mutex_unlock(&ms_streamer->mutex_lock);
}
return TRUE;
} else {
previous_element = __ms_combine_next_element(previous_element, NULL, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER);
- previous_element = __ms_combine_next_element(previous_element, NULL, ms_streamer->sink_bin, MEDIA_STREAMER_NODE_TYPE_QUEUE);
previous_element = __ms_combine_next_element(previous_element, NULL, ms_streamer->sink_bin, MEDIA_STREAMER_NODE_TYPE_SINK);
}
} else {
__ms_link_two_elements(previous_element, NULL, found_element);
- previous_element = __ms_combine_next_element(found_element, NULL, ms_streamer->sink_bin, MEDIA_STREAMER_NODE_TYPE_QUEUE);
- previous_element = __ms_combine_next_element(previous_element, NULL, ms_streamer->sink_bin, MEDIA_STREAMER_NODE_TYPE_SINK);
+ previous_element = __ms_combine_next_element(found_element, NULL, ms_streamer->sink_bin, MEDIA_STREAMER_NODE_TYPE_SINK);
}
} else if (MS_ELEMENT_IS_AUDIO(src_pad_type)) {
previous_element = __ms_combine_next_element(parent_rtp_element, source_pad, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_AUDIO_DEPAY);
previous_element = __ms_combine_next_element(previous_element, NULL, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER);
- previous_element = __ms_combine_next_element(previous_element, NULL, ms_streamer->sink_bin, MEDIA_STREAMER_NODE_TYPE_QUEUE);
previous_element = __ms_combine_next_element(previous_element, NULL, ms_streamer->sink_bin, MEDIA_STREAMER_NODE_TYPE_SINK);
} else {
ms_info("Unknown media type received from rtp element!");
}
MS_SAFE_UNREF(parent_rtp_element);
- MS_BIN_FOREACH_ELEMENTS(ms_streamer->sink_bin, _sink_node_unlock_state, NULL);
return TRUE;
}
ms_retvm_if(gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
GstStateChangeReturn ret_state;
- gchar *element_name = gst_element_get_name(gst_element);
ret_state = gst_element_set_state(gst_element, gst_state);
if (ret_state == GST_STATE_CHANGE_FAILURE) {
- ms_error("Failed to set element [%s] into %s state", element_name, gst_element_state_get_name(gst_state));
- MS_SAFE_GFREE(element_name);
+ ms_error("Failed to set element [%s] into %s state", GST_ELEMENT_NAME(gst_element), gst_element_state_get_name(gst_state));
return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
}
- MS_SAFE_GFREE(element_name);
return MEDIA_STREAMER_ERROR_NONE;
}
case MEDIA_STREAMER_NODE_TYPE_SINK:
bin = ms_streamer->sink_bin;
break;
- case MEDIA_STREAMER_NODE_TYPE_QUEUE:
- bin = ms_streamer->sink_bin;
- break;
default:
/* Another elements will be add into topology bin */
bin = ms_streamer->topology_bin;
return TRUE;
}
+static GstPadProbeReturn __ms_element_event_probe(GstPad * pad, GstPadProbeInfo *info, gpointer user_data)
+{
+ GstElement *parent_element = gst_pad_get_parent_element(pad);
+ GstEvent *event = GST_PAD_PROBE_INFO_EVENT(info);
+ if (GST_PAD_PROBE_INFO_TYPE(info) & GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM) {
+ if (GST_EVENT_TYPE(event) == GST_EVENT_BUFFERSIZE) {
+ GValue *val_ = (GValue *) g_object_get_data(G_OBJECT(parent_element), "pad_sink");
+ ms_info("Set locking probe [%d] on [%s] pad of [%s] element", g_value_get_int(val_), GST_PAD_NAME(pad), GST_ELEMENT_NAME(parent_element));
+ MS_SAFE_UNREF(parent_element);
+ return GST_PAD_PROBE_OK;
+ }
+ }
+ MS_SAFE_UNREF(parent_element);
+ return GST_PAD_PROBE_PASS;
+}
+
+void __ms_element_lock_state(const GValue *item, gpointer user_data)
+{
+ GstElement *sink_element = GST_ELEMENT(g_value_get_object(item));
+ ms_retm_if(!sink_element, "Handle is NULL");
+
+ GstPad *sink_pad = gst_element_get_static_pad(sink_element, "sink");
+ if (!gst_pad_is_blocked(sink_pad)) {
+ int probe_id = gst_pad_add_probe(sink_pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, __ms_element_event_probe, NULL, NULL);
+
+ GValue *val = g_malloc0(sizeof(GValue));
+ g_value_init(val, G_TYPE_INT);
+ g_value_set_int(val, probe_id);
+ g_object_set_data(G_OBJECT(sink_element), "pad_sink", (gpointer)val);
+
+ val = (GValue *) g_object_get_data(G_OBJECT(sink_element), "pad_sink");
+ if (val)
+ ms_info("Added locking probe [%d] on pad [%s] of element [%s]", g_value_get_int(val), GST_PAD_NAME(sink_pad), GST_ELEMENT_NAME(sink_element));
+ } else {
+ ms_info("Pad [%s] of element [%s] is already locked", GST_PAD_NAME(sink_pad), GST_ELEMENT_NAME(sink_element));
+ }
+ MS_SAFE_UNREF(sink_pad);
+}
+
+void __ms_element_unlock_state(const GValue *item, gpointer user_data)
+{
+ GstElement *sink_element = GST_ELEMENT(g_value_get_object(item));
+ ms_retm_if(!sink_element, "Handle is NULL");
+
+ GValue *val = (GValue *) g_object_get_data(G_OBJECT(sink_element), "pad_sink");
+ if (val) {
+ GstPad *sink_pad = gst_element_get_static_pad(sink_element, "sink");
+ if (gst_pad_is_blocked(sink_pad)) {
+ ms_info("Removing locking probe [%d] ID on [%s] pad of [%s] element", g_value_get_int(val), GST_PAD_NAME(sink_pad), GST_ELEMENT_NAME(sink_element));
+ gst_pad_remove_probe(sink_pad, g_value_get_int(val));
+ } else {
+ ms_info("No locking Probe on pad [%s] of element [%s]", GST_PAD_NAME(sink_pad), GST_ELEMENT_NAME(sink_element));
+ }
+ }
+}
+
static gboolean __ms_bus_cb(GstBus *bus, GstMessage *message, gpointer userdata)
{
int ret = MEDIA_STREAMER_ERROR_NONE;
{"Filter/Converter/Video", "videoconvert"}, /* MEDIA_STREAMER_NODE_TYPE_VIDEO_CONVERTER */
{"Filter/Converter/Audio", "audioconvert"}, /* MEDIA_STREAMER_NODE_TYPE_AUDIO_CONVERTER */
{MEDIA_STREAMER_STRICT, "audioresample"}, /* MEDIA_STREAMER_NODE_TYPE_AUDIO_RESAMPLE */
- {"Codec/Payloader/Network/RTP", "rtph264pay"}, /* MEDIA_STREAMER_NODE_TYPE_VIDEO_PAY */
+ {"Codec/Payloader/Network/RTP", "rtph263pay"}, /* MEDIA_STREAMER_NODE_TYPE_VIDEO_PAY */
{"Codec/Payloader/Network/RTP", "rtpamrpay"}, /* MEDIA_STREAMER_NODE_TYPE_AUDIO_PAY */
- {"Codec/Depayloader/Network/RTP", "rtph264depay"}, /* MEDIA_STREAMER_NODE_TYPE_VIDEO_DEPAY */
+ {"Codec/Depayloader/Network/RTP", "rtph263depay"}, /* MEDIA_STREAMER_NODE_TYPE_VIDEO_DEPAY */
{"Codec/Depayloader/Network/RTP", "rtpamrdepay"}, /* MEDIA_STREAMER_NODE_TYPE_AUDIO_DEPAY */
{"Filter/Effect/Video", "videorate"}, /* MEDIA_STREAMER_NODE_TYPE_VIDEO_RATE */
{"Filter/Converter/Video/Scaler", "videoscale"}, /* MEDIA_STREAMER_NODE_TYPE_VIDEO_SCALE */
{MEDIA_STREAMER_STRICT, "textoverlay"}, /* MEDIA_STREAMER_NODE_TYPE_TEXT_OVERLAY */
- {"Codec/Parser/Converter/Video", "h264parse"}, /* MEDIA_STREAMER_NODE_TYPE_PARSER */
+ {"Codec/Parser/Converter/Video", "h263parse"}, /* MEDIA_STREAMER_NODE_TYPE_PARSER */
{MEDIA_STREAMER_STRICT, "capsfilter"}, /* MEDIA_STREAMER_NODE_TYPE_FILTER */
{MEDIA_STREAMER_STRICT, "tee"}, /* MEDIA_STREAMER_NODE_TYPE_TEE */
{MEDIA_STREAMER_STRICT, "queue"}, /* MEDIA_STREAMER_NODE_TYPE_QUEUE */
return ret;
}
-static void _sink_node_lock_state(const GValue *item, gpointer user_data)
-{
- GstElement *sink_element = GST_ELEMENT(g_value_get_object(item));
- ms_retm_if(!sink_element, "Handle is NULL");
-
- if (!gst_element_is_locked_state(sink_element)) {
- GstState current_state = GST_STATE_VOID_PENDING;
- gst_element_set_locked_state(sink_element, TRUE);
-
- gst_element_get_state(sink_element, ¤t_state, NULL, GST_MSECOND);
-
- ms_debug("Locked sink element [%s] into state [%s]", GST_ELEMENT_NAME(sink_element), gst_element_state_get_name(current_state));
- } else {
- gst_element_set_locked_state(sink_element, FALSE);
- gst_element_sync_state_with_parent(sink_element);
- }
-}
-
node_info_s * __ms_node_get_klass_by_its_type(media_streamer_node_type_e element_type)
{
int it_klass;
/* Check the source element`s pad type */
const gchar *new_pad_type = __ms_get_pad_type(src_pad);
if (gst_pad_is_linked(src_pad)) {
- MS_BIN_FOREACH_ELEMENTS(ms_streamer->sink_bin, _sink_node_lock_state, NULL);
MS_SAFE_UNREF(src_pad);
return;
}
if (rtp_node)
__ms_rtp_element_prepare(rtp_node);
- MS_BIN_FOREACH_ELEMENTS(ms_streamer->sink_bin, _sink_node_lock_state, NULL);
+ MS_BIN_FOREACH_ELEMENTS(ms_streamer->sink_bin, __ms_element_lock_state, ms_streamer);
MS_BIN_FOREACH_ELEMENTS(ms_streamer->src_bin, _src_node_prepare, ms_streamer);
return MEDIA_STREAMER_ERROR_NONE;
ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
int ret = MEDIA_STREAMER_ERROR_NONE;
+ __ms_element_set_state(ms_streamer->pipeline, GST_STATE_NULL);
+
+ MS_BIN_FOREACH_ELEMENTS(ms_streamer->sink_bin, __ms_element_unlock_state, ms_streamer);
+
/* Disconnects and clean all autoplug signals */
g_list_free_full(ms_streamer->autoplug_sig_list, __ms_signal_destroy);
ms_streamer->autoplug_sig_list = NULL;
media_streamer_node_add(current_media_streamer, video_dec);
APPEND_NODE(video_dec);
- /* ********************** videoqueue ************************************ */
- media_streamer_node_h video_queue = NULL;
- media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_QUEUE, NULL, NULL, &video_queue);
- media_streamer_node_add(current_media_streamer, video_queue);
- APPEND_NODE(video_queue);
-
/* ********************** videosink *********************************** */
media_streamer_node_h video_sink = NULL;
media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY, &video_sink);
/* ====================Linking Video Client=========================== */
media_streamer_node_link(video_depay, "src", video_dec, "sink");
- media_streamer_node_link(video_dec, "src", video_queue, "sink");
- media_streamer_node_link(video_queue, "src", video_sink, "sink");
+ media_streamer_node_link(video_dec, "src", video_sink, "sink");
g_print("== success client video part \n");
}
media_streamer_node_add(current_media_streamer, audio_dec);
APPEND_NODE(audio_dec);
- /* ********************** audioqueue ********************************** */
- media_streamer_node_h audio_queue = NULL;
- media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_QUEUE, NULL, NULL, &audio_queue);
- media_streamer_node_add(current_media_streamer, audio_queue);
- APPEND_NODE(audio_queue);
-
/* ********************** audiosink *********************************** */
media_streamer_node_h audio_sink = NULL;
media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_AUDIO, &audio_sink);
/* ====================Linking Audio Client=========================== */
media_streamer_node_link(audio_depay, "src", audio_dec, "sink");
- media_streamer_node_link(audio_dec, "src", audio_queue, "sink");
- media_streamer_node_link(audio_queue, "src", audio_sink, "sink");
+ media_streamer_node_link(audio_dec, "src", audio_sink, "sink");
/* =================================================================== */
g_print("== success client audio part \n");