Modified mediastreamer prepare() functionality 94/73794/1
authorVolodymyr Brynza <v.brynza@samsung.com>
Thu, 9 Jun 2016 08:58:04 +0000 (11:58 +0300)
committerVolodymyr Brynza <v.brynza@samsung.com>
Thu, 9 Jun 2016 08:58:04 +0000 (11:58 +0300)
Change-Id: I94d6ef4c7a309d1f9447038d0e031b71818ff988
Signed-off-by: Volodymyr Brynza <v.brynza@samsung.com>
include/media_streamer_gst.h
src/media_streamer.c
src/media_streamer_gst.c
src/media_streamer_node.c
src/media_streamer_priv.c
test/media_streamer_test.c

index 8428e1c..671f8da 100644 (file)
@@ -164,6 +164,20 @@ GstElement *__ms_decodebin_create(media_streamer_s *ms_streamer);
 GstElement *__ms_combine_next_element(GstElement *previous_element, GstPad *prev_elem_src_pad, GstElement *bin_to_find_in, media_streamer_node_type_e node_type);
 
 /**
+ * @brief Locks gst_element being contained in GValue data.
+ *
+ * @since_tizen 3.0
+ */
+void __ms_element_lock_state(const GValue *item, gpointer user_data);
+
+/**
+ * @brief Unlocks gst_element being contained in GValue data.
+ *
+ * @since_tizen 3.0
+ */
+void __ms_element_unlock_state(const GValue *item, gpointer user_data);
+
+/**
  * @brief Creates pipeline, bus and src/sink/topology bins.
  *
  * @since_tizen 3.0
index ce28edc..1016f9d 100644 (file)
@@ -190,8 +190,11 @@ int media_streamer_prepare(media_streamer_h streamer)
 
        ret = __ms_pipeline_prepare(ms_streamer);
 
-       if (ret == MEDIA_STREAMER_ERROR_NONE)
+       if (ret == MEDIA_STREAMER_ERROR_NONE) {
                ret = __ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_READY);
+               if (ret != MEDIA_STREAMER_ERROR_NONE)
+                       __ms_pipeline_unprepare(ms_streamer);
+       }
 
        __ms_generate_dots(ms_streamer->pipeline, "after_prepare");
 
index 46cddcc..f83e993 100755 (executable)
@@ -530,17 +530,6 @@ static void __decodebin_newpad_cb(GstElement * decodebin, GstPad * new_pad, gpoi
        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;
@@ -548,20 +537,19 @@ static void __decodebin_nomore_pads_combine(GstPad *src_pad, media_streamer_s *m
        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)) {
@@ -570,8 +558,7 @@ static void __decodebin_nomore_pads_combine(GstPad *src_pad, media_streamer_s *m
                        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);
@@ -582,7 +569,7 @@ static void __decodebin_nomore_pads_combine(GstPad *src_pad, media_streamer_s *m
        __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");
@@ -609,7 +596,6 @@ static void __decodebin_nomore_pads_cb(GstElement * decodebin, gpointer user_dat
                __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);
 }
 
@@ -647,24 +633,20 @@ static gboolean __ms_sink_bin_prepare(media_streamer_s * ms_streamer, GstPad * s
                                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;
 }
@@ -721,16 +703,13 @@ int __ms_element_set_state(GstElement * gst_element, GstState gst_state)
        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;
 }
 
@@ -1238,9 +1217,6 @@ int __ms_add_node_into_bin(media_streamer_s *ms_streamer, media_streamer_node_s
        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;
@@ -1282,6 +1258,62 @@ static gboolean __ms_parse_gst_error(media_streamer_s *ms_streamer, GstMessage *
        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;
index 3525748..2f55ed2 100755 (executable)
@@ -57,14 +57,14 @@ node_info_s nodes_info[] = {
        {"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 */
@@ -419,24 +419,6 @@ static gboolean __ms_src_need_typefind(GstPad *src_pad)
        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, &current_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;
@@ -472,7 +454,6 @@ static void _src_node_prepare(const GValue *item, gpointer user_data)
                /* 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;
                }
@@ -504,7 +485,7 @@ int __ms_pipeline_prepare(media_streamer_s *ms_streamer)
        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;
@@ -560,6 +541,10 @@ int __ms_pipeline_unprepare(media_streamer_s *ms_streamer)
        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;
index a41a571..00e7e16 100644 (file)
@@ -43,13 +43,16 @@ int __ms_state_change(media_streamer_s *ms_streamer, media_streamer_state_e stat
                /*
                 * Unlink all gst_elements, set pipeline into state NULL
                 */
-               if (previous_state != MEDIA_STREAMER_STATE_NONE)
+               if (previous_state != MEDIA_STREAMER_STATE_NONE) {
+                       MS_BIN_FOREACH_ELEMENTS(ms_streamer->sink_bin, __ms_element_unlock_state, ms_streamer);
                        ret = __ms_element_set_state(ms_streamer->pipeline, GST_STATE_NULL);
+               }
                break;
        case MEDIA_STREAMER_STATE_READY:
-               ret = __ms_element_set_state(ms_streamer->pipeline, GST_STATE_READY);
+               ret = __ms_element_set_state(ms_streamer->pipeline, GST_STATE_PAUSED);
                break;
        case MEDIA_STREAMER_STATE_PLAYING:
+               MS_BIN_FOREACH_ELEMENTS(ms_streamer->sink_bin, __ms_element_unlock_state, ms_streamer);
                ret = __ms_element_set_state(ms_streamer->pipeline, GST_STATE_PLAYING);
                break;
        case MEDIA_STREAMER_STATE_PAUSED:
index ffbc6c4..a285add 100644 (file)
@@ -551,12 +551,6 @@ static void _create_rtp_client(media_streamer_node_h rtp_bin)
                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);
@@ -565,8 +559,7 @@ static void _create_rtp_client(media_streamer_node_h rtp_bin)
 
                /* ====================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");
        }
@@ -585,12 +578,6 @@ static void _create_rtp_client(media_streamer_node_h rtp_bin)
                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);
@@ -599,8 +586,7 @@ static void _create_rtp_client(media_streamer_node_h rtp_bin)
 
                /* ====================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");