Modified Mediastreamer State Change 95/73795/1
authorVolodymyr Brynza <v.brynza@samsung.com>
Thu, 9 Jun 2016 09:00:52 +0000 (12:00 +0300)
committerVolodymyr Brynza <v.brynza@samsung.com>
Thu, 9 Jun 2016 09:00:52 +0000 (12:00 +0300)
Change-Id: I4a2ac52963faeb727a4bfee45590648273ee33bb
Signed-off-by: Volodymyr Brynza <v.brynza@samsung.com>
include/media_streamer_node.h
include/media_streamer_priv.h
include/media_streamer_util.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 d68ec71..eb89d8c 100644 (file)
 
 #include <media_streamer_priv.h>
 
+/**
+ * @brief Gets state of media streamer.
+ *
+ * @since_tizen 3.0
+ */
+void __ms_get_state(media_streamer_s *ms_streamer);
 
 /**
  * @brief Creates media streamer node using input and output format.
index c930c6c..c559c1a 100755 (executable)
@@ -105,6 +105,7 @@ typedef struct {
        gboolean is_seeking;
 
        media_streamer_state_e state;
+       media_streamer_state_e pend_state;
 
        media_streamer_callback_s error_cb;
        media_streamer_callback_s state_changed_cb;
index 7377677..3079de5 100644 (file)
@@ -223,7 +223,6 @@ typedef struct {
 #define MS_BIN_UNPREPARE(bin) \
        if (!__ms_bin_remove_elements(ms_streamer, bin)) {\
                ms_debug("Got a few errors during unprepare [%s] bin.", GST_ELEMENT_NAME(bin));\
-               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;\
        }
 
 #define MS_SET_INT_RTP_PARAM(obj, key, value) \
index 1016f9d..c3cf041 100644 (file)
@@ -190,16 +190,12 @@ int media_streamer_prepare(media_streamer_h streamer)
 
        ret = __ms_pipeline_prepare(ms_streamer);
 
-       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");
 
        g_mutex_unlock(&ms_streamer->mutex_lock);
 
+       __ms_get_state(ms_streamer);
+
        return ret;
 }
 
@@ -215,10 +211,7 @@ int media_streamer_unprepare(media_streamer_h streamer)
 
        __ms_generate_dots(ms_streamer->pipeline, "before_unprepare");
 
-       ret = __ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_IDLE);
-
-       if (ret == MEDIA_STREAMER_ERROR_NONE)
-               ret = __ms_pipeline_unprepare(ms_streamer);
+       ret = __ms_pipeline_unprepare(ms_streamer);
 
        __ms_generate_dots(ms_streamer->pipeline, "after_unprepare");
 
@@ -241,6 +234,8 @@ int media_streamer_play(media_streamer_h streamer)
 
        g_mutex_unlock(&ms_streamer->mutex_lock);
 
+       __ms_get_state(ms_streamer);
+
        return ret;
 }
 
@@ -264,7 +259,8 @@ int media_streamer_create(media_streamer_h *streamer)
                return ret;
        }
 
-       ms_streamer->state = MEDIA_STREAMER_STATE_IDLE;
+       ms_streamer->pend_state = MEDIA_STREAMER_STATE_NONE;
+       ret = __ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_IDLE);
        *streamer = ms_streamer;
 
        ms_info("Media Streamer created successfully");
@@ -454,6 +450,8 @@ int media_streamer_pause(media_streamer_h streamer)
 
        g_mutex_unlock(&ms_streamer->mutex_lock);
 
+       __ms_get_state(ms_streamer);
+
        return ret;
 }
 
@@ -476,6 +474,8 @@ int media_streamer_stop(media_streamer_h streamer)
 
        g_mutex_unlock(&ms_streamer->mutex_lock);
 
+       __ms_get_state(ms_streamer);
+
        return ret;
 }
 
index f83e993..423fd24 100755 (executable)
@@ -1346,11 +1346,31 @@ static gboolean __ms_bus_cb(GstBus *bus, GstMessage *message, gpointer userdata)
                                        gchar *state_transition_name;
 
                                        gst_message_parse_state_changed(message, &state_old, &state_new, &state_pending);
-                                       state_transition_name = g_strdup_printf("%s_%s", gst_element_state_get_name(state_old), gst_element_state_get_name(state_new));
-                                       ms_info("GST_MESSAGE_STATE_CHANGED: [%s] %s", GST_OBJECT_NAME(GST_MESSAGE_SRC(message)), state_transition_name);
+                                       state_transition_name = g_strdup_printf("Old_[%s]_New_[%s]_Pending_[%s]", gst_element_state_get_name(state_old),
+                                                                                       gst_element_state_get_name(state_new), gst_element_state_get_name(state_pending));
+                                       ms_info("GST_MESSAGE_STATE_CHANGED: [%s] %s. ", GST_OBJECT_NAME(GST_MESSAGE_SRC(message)), state_transition_name);
                                        __ms_generate_dots(ms_streamer->pipeline, state_transition_name);
-
                                        MS_SAFE_GFREE(state_transition_name);
+
+                                       media_streamer_state_e old_state = ms_streamer->state;
+                                       if (state_new >= GST_STATE_PAUSED)
+                                       {
+                                               if ((old_state == MEDIA_STREAMER_STATE_PLAYING) && (state_new <= GST_STATE_PAUSED))
+                                                       ms_streamer->pend_state = MEDIA_STREAMER_STATE_PAUSED;
+
+                                               if (ms_streamer->pend_state != ms_streamer->state) {
+
+                                                       g_mutex_lock(&ms_streamer->mutex_lock);
+                                                       ms_streamer->state = ms_streamer->pend_state;
+                                                       g_mutex_unlock(&ms_streamer->mutex_lock);
+
+                                                       ms_info("Media streamer state changed to [%d] [%d]", old_state, ms_streamer->state);
+                                                       if (ms_streamer->state_changed_cb.callback) {
+                                                               media_streamer_state_changed_cb cb = (media_streamer_state_changed_cb) ms_streamer->state_changed_cb.callback;
+                                                               cb((media_streamer_h) ms_streamer, old_state, ms_streamer->state, ms_streamer->state_changed_cb.user_data);
+                                                       }
+                                               }
+                                       }
                                }
                                break;
                        }
@@ -1359,14 +1379,21 @@ static gboolean __ms_bus_cb(GstBus *bus, GstMessage *message, gpointer userdata)
                                if (GST_MESSAGE_SRC(message) == GST_OBJECT(ms_streamer->pipeline)
                                        && ms_streamer->is_seeking) {
 
+                                       g_mutex_lock(&ms_streamer->mutex_lock);
+                                       ms_streamer->pend_state = MEDIA_STREAMER_STATE_SEEKING;
+                                       g_mutex_unlock(&ms_streamer->mutex_lock);
+
                                        if (ms_streamer->seek_done_cb.callback) {
                                                media_streamer_position_changed_cb cb = (media_streamer_position_changed_cb) ms_streamer->seek_done_cb.callback;
                                                cb(ms_streamer->seek_done_cb.user_data);
                                        }
 
+                                       g_mutex_lock(&ms_streamer->mutex_lock);
                                        ms_streamer->is_seeking = FALSE;
+                                       ms_streamer->pend_state = MEDIA_STREAMER_STATE_PLAYING;
                                        ms_streamer->seek_done_cb.callback = NULL;
                                        ms_streamer->seek_done_cb.user_data = NULL;
+                                       g_mutex_unlock(&ms_streamer->mutex_lock);
                                }
                                break;
                        }
index 2f55ed2..03ecab8 100755 (executable)
@@ -79,6 +79,16 @@ node_info_s nodes_info[] = {
        {NULL, NULL}
 };
 
+void __ms_get_state(media_streamer_s *ms_streamer)
+{
+       GstState state_old, state_new;
+       GstStateChangeReturn ret_state = gst_element_get_state(ms_streamer->pipeline, &state_old, &state_new, GST_CLOCK_TIME_NONE);
+       if (ret_state == GST_STATE_CHANGE_SUCCESS)
+               ms_info("Got state for [%s]: old [%s], new [%s]", GST_ELEMENT_NAME(ms_streamer->pipeline), gst_element_state_get_name(state_old), gst_element_state_get_name(state_new));
+       else
+               ms_error("Couldn`t get state for [%s]", GST_ELEMENT_NAME(ms_streamer->pipeline));
+}
+
 static gboolean __ms_rtp_node_has_property(media_streamer_node_s *ms_node, const gchar *param_name)
 {
        ms_retvm_if(!ms_node || !ms_node->gst_element, FALSE, "Error: empty node");
@@ -481,14 +491,31 @@ int __ms_pipeline_prepare(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;
        media_streamer_node_s *rtp_node = (media_streamer_node_s *)g_hash_table_lookup(ms_streamer->nodes_table, "rtp_container");
-       if (rtp_node)
-               __ms_rtp_element_prepare(rtp_node);
+       if (rtp_node) {
+               ret = __ms_rtp_element_prepare(rtp_node) ? MEDIA_STREAMER_ERROR_NONE : MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
+       } else {
+               GstBin *nodes_bin = GST_BIN(ms_streamer->src_bin);
+               if(nodes_bin->numchildren == 0) {
+                       ms_debug(" No any node is added to [%s]", GST_ELEMENT_NAME(ms_streamer->src_bin));
+                       return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
+               }
+               nodes_bin = GST_BIN(ms_streamer->sink_bin);
+               if(nodes_bin->numchildren == 0) {
+                       ms_debug(" No any node is added to [%s]", GST_ELEMENT_NAME(ms_streamer->sink_bin));
+                       return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
+               }
+       }
 
        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;
+       ret = __ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_READY);
+       if (ret != MEDIA_STREAMER_ERROR_NONE)
+               __ms_pipeline_unprepare(ms_streamer);
+
+       return ret;
 }
 
 static gboolean __ms_bin_remove_elements(media_streamer_s *ms_streamer, GstElement *bin)
@@ -542,6 +569,8 @@ int __ms_pipeline_unprepare(media_streamer_s *ms_streamer)
        int ret = MEDIA_STREAMER_ERROR_NONE;
 
        __ms_element_set_state(ms_streamer->pipeline, GST_STATE_NULL);
+       ms_streamer->state = MEDIA_STREAMER_STATE_IDLE;
+       ms_streamer->pend_state = ms_streamer->state;
 
        MS_BIN_FOREACH_ELEMENTS(ms_streamer->sink_bin, __ms_element_unlock_state, ms_streamer);
 
index 00e7e16..47dd4bb 100644 (file)
@@ -26,9 +26,7 @@ int __ms_state_change(media_streamer_s *ms_streamer, media_streamer_state_e stat
        int ret = MEDIA_STREAMER_ERROR_NONE;
 
        ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
-
-       media_streamer_state_e previous_state = ms_streamer->state;
-       ms_retvm_if(previous_state == state, MEDIA_STREAMER_ERROR_NONE, "Media streamer already in this state");
+       ms_retvm_if(ms_streamer->state == state, MEDIA_STREAMER_ERROR_NONE, "Media streamer already in this state");
 
        switch (state) {
        case MEDIA_STREAMER_STATE_NONE:
@@ -36,27 +34,31 @@ int __ms_state_change(media_streamer_s *ms_streamer, media_streamer_state_e stat
                 * Media streamer must be in IDLE state
                 * Unlink and destroy all bins and elements.
                 */
-               if (previous_state != MEDIA_STREAMER_STATE_IDLE)
-                       __ms_state_change(ms_streamer, MEDIA_STREAMER_STATE_IDLE);
+               ret = __ms_element_set_state(ms_streamer->pipeline, GST_STATE_NULL);
+               ms_streamer->pend_state = 0;
+               ms_streamer->state = state;
                break;
        case MEDIA_STREAMER_STATE_IDLE:
                /*
                 * Unlink all gst_elements, set pipeline into state NULL
                 */
-               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);
-               }
+               ret = __ms_element_set_state(ms_streamer->pipeline, GST_STATE_NULL);
+               MS_BIN_FOREACH_ELEMENTS(ms_streamer->sink_bin, __ms_element_unlock_state, ms_streamer);
+               ms_streamer->pend_state = MEDIA_STREAMER_STATE_NONE;
+               ms_streamer->state = state;
                break;
        case MEDIA_STREAMER_STATE_READY:
                ret = __ms_element_set_state(ms_streamer->pipeline, GST_STATE_PAUSED);
+               ms_streamer->pend_state = MEDIA_STREAMER_STATE_READY;
                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);
+               MS_BIN_FOREACH_ELEMENTS(ms_streamer->sink_bin, __ms_element_unlock_state, ms_streamer);
+               ms_streamer->pend_state = MEDIA_STREAMER_STATE_PLAYING;
                break;
        case MEDIA_STREAMER_STATE_PAUSED:
                ret = __ms_element_set_state(ms_streamer->pipeline, GST_STATE_PAUSED);
+               ms_streamer->pend_state = MEDIA_STREAMER_STATE_PAUSED;
                break;
        case MEDIA_STREAMER_STATE_SEEKING:
        default:{
@@ -65,13 +67,6 @@ int __ms_state_change(media_streamer_s *ms_streamer, media_streamer_state_e stat
                }
        }
 
-       if (ret != MEDIA_STREAMER_ERROR_NONE) {
-               ms_error("Failed change state");
-               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
-       }
-
-       ms_streamer->state = state;
-       ms_info("Media streamer state changed to [%d]", state);
        return ret;
 }
 
index a285add..09c6b1b 100644 (file)
@@ -142,6 +142,11 @@ static void streamer_seek_cb(void *user_data)
        g_print("Current play position [%02d:%02d:%03d] \n", current_time / (1000 * 60), (current_time / 1000) % 60, current_time % 1000);
 }
 
+static void streamer_changed_cb(media_streamer_h streamer, media_streamer_state_e previous_state, media_streamer_state_e current_state, void *user_data)
+{
+       g_print("Media Streamer State changed [%d] -> [%d]", previous_state, current_state);
+}
+
 static void _create(media_streamer_h *streamer)
 {
        g_print("== create \n");
@@ -170,6 +175,8 @@ static void _prepare(void)
                g_print("Fail to prepare media streamer");
                return;
        }
+
+       media_streamer_set_state_change_cb(current_media_streamer, streamer_changed_cb, NULL);
        g_print("== success prepare \n");
 }