GError *err = NULL;
gchar *debug = NULL;
gchar *state_transition_name = NULL;
- GstState state_old = 0, state_new = 0, state_pending = 0;
+ GstState gst_state_old = GST_STATE_VOID_PENDING;
+ GstState gst_state_new = GST_STATE_VOID_PENDING;
+ GstState gst_state_pending = GST_STATE_VOID_PENDING;
+ media_streamer_state_e old_state = MEDIA_STREAMER_STATE_NONE;
ms_streamer = (media_streamer_s *) userdata;
- ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
- ms_retvm_if(ms_streamer->pipeline == NULL, MEDIA_STREAMER_ERROR_INVALID_STATE, "Pipeline doesn`t exist");
+ ms_retvm_if(ms_streamer == NULL, FALSE, "Handle is NULL");
+ ms_retvm_if(ms_streamer->pipeline == NULL, FALSE, "Pipeline doesn`t exist");
/* Parse message */
- if (message != NULL) {
- switch (GST_MESSAGE_TYPE(message)) {
- case GST_MESSAGE_ERROR:{
- gst_message_parse_error(message, &err, &debug);
+ if (message == NULL) {
+ ms_debug("message is null");
+ return TRUE;
+ }
- /* Transform gst error code to media streamer error code.
- * then post it to application if needed */
- __ms_parse_gst_error(ms_streamer, message, err);
+ switch (GST_MESSAGE_TYPE(message)) {
+ case GST_MESSAGE_ERROR:
+ gst_message_parse_error(message, &err, &debug);
- ms_error("[Source: %s] Error: %s", GST_OBJECT_NAME(GST_OBJECT_CAST(GST_ELEMENT(GST_MESSAGE_SRC(message)))), err->message);
+ /* Transform gst error code to media streamer error code.
+ * then post it to application if needed */
+ __ms_parse_gst_error(ms_streamer, message, err);
- g_error_free(err);
- MS_SAFE_GFREE(debug);
- break;
- }
+ ms_error("Error from [%s]: %s", GST_OBJECT_NAME(GST_OBJECT_CAST(GST_ELEMENT(GST_MESSAGE_SRC(message)))), err->message);
- case GST_MESSAGE_STATE_CHANGED:{
- if (GST_MESSAGE_SRC(message) == GST_OBJECT(ms_streamer->pipeline)) {
- gst_message_parse_state_changed(message, &state_old, &state_new, &state_pending);
- 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) {
- if(__ms_skip_set_state(ms_streamer)){
- ms_info("Skip set state, state is set after connecting ICE connection.");
- break;
- }
-
- 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;
- }
+ g_error_free(err);
+ MS_SAFE_GFREE(debug);
+ break;
- case GST_MESSAGE_ASYNC_DONE:{
- ms_debug("GST_MESSAGE_ASYNC_DONE");
- if (GST_MESSAGE_SRC(message) == GST_OBJECT(ms_streamer->pipeline)
- && ms_streamer->is_seeking) {
+ case GST_MESSAGE_STATE_CHANGED:
+ if (GST_MESSAGE_SRC(message) != GST_OBJECT(ms_streamer->pipeline))
+ return TRUE;
- g_mutex_lock(&ms_streamer->mutex_lock);
- ms_streamer->pend_state = MEDIA_STREAMER_STATE_SEEKING;
- g_mutex_unlock(&ms_streamer->mutex_lock);
+ gst_message_parse_state_changed(message, &gst_state_old, &gst_state_new, &gst_state_pending);
+ state_transition_name = g_strdup_printf("Old[GST_STATE_%s] New[GST_STATE_%s] Pending[GST_STATE_%s]",
+ gst_element_state_get_name(gst_state_old), gst_element_state_get_name(gst_state_new),
+ gst_element_state_get_name(gst_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);
- 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);
- }
+ if (gst_state_new < GST_STATE_PAUSED)
+ break;
- 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;
- }
- case GST_MESSAGE_EOS:{
- ms_info("GST_MESSAGE_EOS end-of-stream");
- ret = ms_element_set_state(ms_streamer->pipeline, GST_STATE_PAUSED);
- if (ret != MEDIA_STREAMER_ERROR_NONE) {
- ms_error("ERROR - Pause Pipeline");
- return FALSE;
- }
- break;
- }
- default:
+ if (ms_streamer->pend_state == ms_streamer->state) {
+ ms_info("pend_state(%d) is same with current state(%d), skip triggering callback.",
+ ms_streamer->pend_state, ms_streamer->state);
break;
}
+
+ if(__ms_skip_set_state(ms_streamer)) {
+ ms_info("Skip set state, state is set after connecting ICE connection.");
+ break;
+ }
+
+ old_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 [%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;
+
+ case GST_MESSAGE_ASYNC_DONE:
+ ms_debug("GST_MESSAGE_ASYNC_DONE");
+
+ if (GST_MESSAGE_SRC(message) != GST_OBJECT(ms_streamer->pipeline))
+ return TRUE;
+
+ if (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;
+
+ case GST_MESSAGE_EOS:
+ ms_info("GST_MESSAGE_EOS end-of-stream");
+ ret = ms_element_set_state(ms_streamer->pipeline, GST_STATE_PAUSED);
+ ms_retvm_if(ret != MEDIA_STREAMER_ERROR_NONE, FALSE, "Failed to pause pipeline");
+ break;
+
+ default:
+ break;
}
return TRUE;