[0.6.125] improve the complexity issue of gst_callback 48/187348/1
authorEunhae Choi <eunhae1.choi@samsung.com>
Wed, 22 Aug 2018 06:55:34 +0000 (15:55 +0900)
committerEunhae Choi <eunhae1.choi@samsung.com>
Wed, 22 Aug 2018 06:55:34 +0000 (15:55 +0900)
Change-Id: I2a62f27989d628272358f0fe14a42ba7ef2f4a6f

packaging/libmm-player.spec
src/include/mm_player_gst.h
src/mm_player_gst.c
src/mm_player_priv.c

index 00ebf7ab8afda135312b607a7198d62f432a4826..446a356df506f4ce8d5f2fb5b2dd7d8cc2a3ac3e 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-player
 Summary:    Multimedia Framework Player Library
-Version:    0.6.124
+Version:    0.6.125
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index 11af80bd824b40a7a1ffd4a63c1f870d26704efa..ca3d48a283b2ebb731cb2f13edd17f01af362cd8 100644 (file)
@@ -45,8 +45,8 @@ gint __mmplayer_gst_handle_stream_error(mm_player_t* player, GError* error, GstM
 
 gboolean __mmplayer_handle_gst_error(mm_player_t* player, GstMessage * message, GError* error);
 int __mmplayer_gst_set_state(mm_player_t* player, GstElement * element,  GstState state, gboolean async, gint timeout);
-void __mmplayer_gst_callback(GstMessage *msg, gpointer data);
-GstBusSyncReply __mmplayer_bus_sync_callback(GstBus * bus, GstMessage * message, gpointer data);
+void __mmplayer_gst_bus_msg_callback(GstMessage *msg, gpointer data);
+GstBusSyncReply __mmplayer_gst_bus_sync_callback(GstBus * bus, GstMessage * message, gpointer data);
 
 int __mmplayer_gst_start(mm_player_t* player);
 int __mmplayer_gst_stop(mm_player_t* player);
index 2de93e6e374b7898847314483c030ba65f9e4c07..c509f1b61db2cba0bca92bb7624a9b838caa7b21 100644 (file)
@@ -654,9 +654,9 @@ __mmplayer_handle_streaming_error(mm_player_t* player, GstMessage * message)
                LOGD("skip error post because it's sent already.\n");
 
        gst_structure_free(s);
-       MMPLAYER_FLEAVE();
        g_free(error_string);
 
+       MMPLAYER_FLEAVE();
        return TRUE;
 
 }
@@ -1045,7 +1045,7 @@ __mmplayer_update_buffer_setting(mm_player_t *player, GstMessage *buffering_msg)
 }
 
 static int
-__mmplayer_handle_buffering_message(mm_player_t* player)
+__mmplayer_handle_buffering_playback(mm_player_t* player)
 {
        int ret = MM_ERROR_NONE;
        MMPlayerStateType prev_state = MM_PLAYER_STATE_NONE;
@@ -1379,488 +1379,739 @@ __mmplayer_drop_subtitle(mm_player_t* player, gboolean is_drop)
        }
 }
 
-
-#if 0
-#endif
-
-int
-__mmplayer_gst_set_state(mm_player_t* player, GstElement * element,  GstState state, gboolean async, gint timeout)
+static void
+__mmplayer_gst_handle_eos_message(mm_player_t* player, GstMessage *msg)
 {
-       GstState element_state = GST_STATE_VOID_PENDING;
-       GstState element_pending_state = GST_STATE_VOID_PENDING;
-       GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
+       MMHandleType attrs = 0;
+       gint count = 0;
 
        MMPLAYER_FENTER();
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(element, MM_ERROR_INVALID_ARGUMENT);
+       /* NOTE : EOS event is comming multiple time. watch out it */
+       /* check state. we only process EOS when pipeline state goes to PLAYING */
+       if (!(player->cmd == MMPLAYER_COMMAND_START || player->cmd == MMPLAYER_COMMAND_RESUME)) {
+               LOGD("EOS received on non-playing state. ignoring it");
+               return;
+       }
 
-       LOGD("setting [%s] element state to : %s\n", GST_ELEMENT_NAME(element), gst_element_state_get_name(state));
+       if (player->pipeline) {
+               if (player->pipeline->textbin)
+                       __mmplayer_drop_subtitle(player, TRUE);
 
-       /* set state */
-       ret = gst_element_set_state(element, state);
+               if ((player->audio_stream_cb) && (player->set_mode.pcm_extraction) && (!player->audio_stream_render_cb_ex)) {
+                       GstPad *pad = NULL;
 
-       if (ret == GST_STATE_CHANGE_FAILURE) {
-               LOGE("failed to set [%s] state\n", GST_ELEMENT_NAME(element));
+                       pad = gst_element_get_static_pad(player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
 
-               /* dump state of all element */
-               __mmplayer_dump_pipeline_state(player);
+                       LOGD("release audio callback");
 
-               return MM_ERROR_PLAYER_INTERNAL;
+                       /* release audio callback */
+                       gst_pad_remove_probe(pad, player->audio_cb_probe_id);
+                       player->audio_cb_probe_id = 0;
+                       /* audio callback should be free because it can be called even though probe remove.*/
+                       player->audio_stream_cb = NULL;
+                       player->audio_stream_cb_user_param = NULL;
+
+               }
        }
+       if ((player->audio_stream_render_cb_ex) && (!player->audio_stream_sink_sync))
+               __mmplayer_audio_stream_clear_buffer(player, TRUE);
 
-       /* return here so state transition to be done in async mode */
-       if (async) {
-               LOGD("async state transition. not waiting for state complete.\n");
-               return MM_ERROR_NONE;
+       /* rewind if repeat count is greater then zero */
+       /* get play count */
+       attrs = MMPLAYER_GET_ATTRS(player);
+
+       if (attrs) {
+               mm_attrs_get_int_by_name(attrs, "profile_play_count", &count);
+
+               LOGD("play count: %d, playback rate: %f", count, player->playback_rate);
+
+               if (count == -1 || player->playback_rate < 0.0) /* default value is 1 */ {
+                       if (player->playback_rate < 0.0) {
+                               player->resumed_by_rewind = TRUE;
+                               _mmplayer_set_mute((MMHandleType)player, 0);
+                               MMPLAYER_POST_MSG(player, MM_MESSAGE_RESUMED_BY_REW, NULL);
+                       }
+
+                       __mmplayer_handle_eos_delay(player, player->ini.delay_before_repeat);
+
+                       /* initialize */
+                       player->sent_bos = FALSE;
+
+                       LOGD("do not post eos msg for repeating");
+                       return;
+               }
        }
 
-       /* wait for state transition */
-       ret = gst_element_get_state(element, &element_state, &element_pending_state, timeout * GST_SECOND);
+       if (player->pipeline)
+               MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-eos");
 
-       if (ret == GST_STATE_CHANGE_FAILURE || (state != element_state)) {
-               LOGE("failed to change [%s] element state to [%s] within %d sec\n",
-                       GST_ELEMENT_NAME(element),
-                       gst_element_state_get_name(state), timeout);
+       /* post eos message to application */
+       __mmplayer_handle_eos_delay(player, player->ini.eos_delay);
 
-               LOGE(" [%s] state : %s   pending : %s \n",
-                       GST_ELEMENT_NAME(element),
-                       gst_element_state_get_name(element_state),
-                       gst_element_state_get_name(element_pending_state));
+       /* reset last position */
+       player->last_position = 0;
+
+       MMPLAYER_FLEAVE();
+       return;
+}
+
+static void
+__mmplayer_gst_handle_error_message(mm_player_t* player, GstMessage *msg)
+{
+       GError *error = NULL;
+       gchar* debug = NULL;
+
+       MMPLAYER_FENTER();
+
+       /* generating debug info before returning error */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-error");
+
+       /* get error code */
+       gst_message_parse_error(msg, &error, &debug);
+
+       if (gst_structure_has_name(gst_message_get_structure(msg), "streaming_error")) {
+               /* Note : the streaming error from the streaming source is handled
+                *       using __mmplayer_handle_streaming_error.
+                */
+               __mmplayer_handle_streaming_error(player, msg);
 
                /* dump state of all element */
                __mmplayer_dump_pipeline_state(player);
+       } else {
+               /* traslate gst error code to msl error code. then post it
+                * to application if needed
+                */
+               __mmplayer_handle_gst_error(player, msg, error);
 
-               return MM_ERROR_PLAYER_INTERNAL;
+               if (debug)
+                       LOGE("error debug : %s", debug);
        }
 
-       LOGD("[%s] element state has changed\n", GST_ELEMENT_NAME(element));
+       if (MMPLAYER_IS_HTTP_PD(player))
+               _mmplayer_unrealize_pd_downloader((MMHandleType)player);
 
-       MMPLAYER_FLEAVE();
+       MMPLAYER_FREEIF(debug);
+       g_error_free(error);
 
-       return MM_ERROR_NONE;
+       MMPLAYER_FLEAVE();
+       return;
 }
 
-void
-__mmplayer_gst_callback(GstMessage *msg, gpointer data)
+static void
+__mmplayer_gst_handle_buffering_message(mm_player_t* player, GstMessage *msg)
 {
-       mm_player_t* player = (mm_player_t*)(data);
+       MMMessageParamType msg_param = {0, };
+       int bRet = MM_ERROR_NONE;
 
-       MMPLAYER_RETURN_IF_FAIL(player);
-       MMPLAYER_RETURN_IF_FAIL(msg && GST_IS_MESSAGE(msg));
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
 
-       switch (GST_MESSAGE_TYPE(msg)) {
-       case GST_MESSAGE_UNKNOWN:
-               LOGD("unknown message received\n");
-               break;
+       if (!MMPLAYER_IS_STREAMING(player)) {
+               LOGW("this is not streaming playback.");
+               return;
+       }
 
-       case GST_MESSAGE_EOS:
-               {
-                       MMHandleType attrs = 0;
-                       gint count = 0;
+       if (player->pd_mode == MM_PLAYER_PD_MODE_URI) {
+               if (!MMPLAYER_CMD_TRYLOCK(player)) {
+                       /* skip the playback control by buffering msg while user request is handled. */
+                       gint per = 0;
 
-                       LOGD("GST_MESSAGE_EOS received\n");
+                       LOGW("[PD mode] can't get cmd lock, only post buffering msg");
 
-                       /* NOTE : EOS event is comming multiple time. watch out it */
-                       /* check state. we only process EOS when pipeline state goes to PLAYING */
-                       if (!(player->cmd == MMPLAYER_COMMAND_START || player->cmd == MMPLAYER_COMMAND_RESUME)) {
-                               LOGD("EOS received on non-playing state. ignoring it\n");
-                               break;
-                       }
+                       gst_message_parse_buffering(msg, &per);
+                       LOGD("[PD mode][%s] buffering %d %%....", GST_OBJECT_NAME(GST_MESSAGE_SRC(msg)), per);
+
+                       msg_param.connection.buffering = per;
+                       MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
+                       return;
+               }
+       } else {
+               MMPLAYER_CMD_LOCK(player);
+       }
+
+       if (!player->streamer) {
+               LOGW("Pipeline is shutting down");
+               MMPLAYER_CMD_UNLOCK(player);
+               return;
+       }
 
-                       if (player->pipeline) {
-                               if (player->pipeline->textbin)
-                                       __mmplayer_drop_subtitle(player, TRUE);
+       /* ignore the remained buffering message till getting 100% msg */
+       if (player->streamer->buffering_state == MM_PLAYER_BUFFERING_COMPLETE) {
+               gint buffer_percent = 0;
 
-                               if ((player->audio_stream_cb) && (player->set_mode.pcm_extraction) && (!player->audio_stream_render_cb_ex)) {
-                                       GstPad *pad = NULL;
+               gst_message_parse_buffering(msg, &buffer_percent);
 
-                                       pad = gst_element_get_static_pad(player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
+               if (buffer_percent == MAX_BUFFER_PERCENT) {
+                       LOGD("Ignored all the previous buffering msg!(got %d%%)\n", buffer_percent);
+                       player->streamer->buffering_state = MM_PLAYER_BUFFERING_DEFAULT;
+               }
+               MMPLAYER_CMD_UNLOCK(player);
+               return;
+       }
 
-                                       LOGD("release audio callback\n");
+       /* ignore the remained buffering message */
+       if (player->streamer->buffering_state == MM_PLAYER_BUFFERING_ABORT) {
+               gint buffer_percent = 0;
 
-                                       /* release audio callback */
-                                       gst_pad_remove_probe(pad, player->audio_cb_probe_id);
-                                       player->audio_cb_probe_id = 0;
-                                       /* audio callback should be free because it can be called even though probe remove.*/
-                                       player->audio_stream_cb = NULL;
-                                       player->audio_stream_cb_user_param = NULL;
+               gst_message_parse_buffering(msg, &buffer_percent);
 
-                               }
-                       }
-                       if ((player->audio_stream_render_cb_ex) && (!player->audio_stream_sink_sync))
-                               __mmplayer_audio_stream_clear_buffer(player, TRUE);
+               LOGD("interrupted buffering -last posted %d %%, new per %d %%",
+                                       player->streamer->buffering_percent, buffer_percent);
 
-                       /* rewind if repeat count is greater then zero */
-                       /* get play count */
-                       attrs = MMPLAYER_GET_ATTRS(player);
+               if (player->streamer->buffering_percent > buffer_percent || buffer_percent <= 0) {
+                       player->streamer->buffering_state = MM_PLAYER_BUFFERING_DEFAULT;
+                       player->streamer->buffering_req.is_pre_buffering = FALSE;
 
-                       if (attrs) {
-                               mm_attrs_get_int_by_name(attrs, "profile_play_count", &count);
+                       LOGD("interrupted buffering - need to enter the buffering mode again - %d %%", buffer_percent);
+               } else {
+                       LOGD("interrupted buffering - ignored the remained buffering msg!");
+                       MMPLAYER_CMD_UNLOCK(player);
+                       return;
+               }
+       }
 
-                               LOGD("play count: %d, playback rate: %f\n", count, player->playback_rate);
+       __mmplayer_update_buffer_setting(player, msg);
 
-                               if (count == -1 || player->playback_rate < 0.0) /* default value is 1 */ {
-                                       if (player->playback_rate < 0.0) {
-                                               player->resumed_by_rewind = TRUE;
-                                               _mmplayer_set_mute((MMHandleType)player, 0);
-                                               MMPLAYER_POST_MSG(player, MM_MESSAGE_RESUMED_BY_REW, NULL);
-                                       }
+       bRet = __mmplayer_handle_buffering_playback(player); /* playback control */
 
-                                       __mmplayer_handle_eos_delay(player, player->ini.delay_before_repeat);
+       if (bRet == MM_ERROR_NONE) {
+               msg_param.connection.buffering = player->streamer->buffering_percent;
+               MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
 
-                                       /* initialize */
-                                       player->sent_bos = FALSE;
+               if (MMPLAYER_IS_RTSP_STREAMING(player) &&
+                       player->pending_resume &&
+                       (player->streamer->buffering_percent >= MAX_BUFFER_PERCENT)) {
 
-                                       /* not posting eos when repeating */
-                                       break;
+                       player->is_external_subtitle_added_now = FALSE;
+                       player->pending_resume = FALSE;
+                       _mmplayer_resume((MMHandleType)player);
+               }
+
+               if (MMPLAYER_IS_RTSP_STREAMING(player) &&
+                       (player->streamer->buffering_percent >= MAX_BUFFER_PERCENT)) {
+
+                       if (player->seek_state == MMPLAYER_SEEK_IN_PROGRESS) {
+                               if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PAUSED) {
+                                       player->seek_state = MMPLAYER_SEEK_NONE;
+                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_SEEK_COMPLETED, NULL);
+                               } else if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PLAYING) {
+                                       /* Considering the async state trasition in case of RTSP.
+                                          After getting state change gst msg, seek cmpleted msg will be posted. */
+                                       player->seek_state = MMPLAYER_SEEK_COMPLETED;
                                }
                        }
+               }
+       } else if (bRet == MM_ERROR_PLAYER_INVALID_STATE) {
+               if (!player->streamer) {
+                       LOGW("player->streamer is NULL, so discarding the buffering percent update\n");
+                       MMPLAYER_CMD_UNLOCK(player);
+                       return;
+               }
 
-                       if (player->pipeline)
-                               MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-eos");
+               if ((MMPLAYER_IS_LIVE_STREAMING(player)) && (MMPLAYER_IS_RTSP_STREAMING(player))) {
 
-                       /* post eos message to application */
-                       __mmplayer_handle_eos_delay(player, player->ini.eos_delay);
+                       LOGD("player->last_position=%"G_GINT64_FORMAT" , player->streamer->buffering_percent=%d \n",
+                                       GST_TIME_AS_SECONDS(player->last_position), player->streamer->buffering_percent);
 
-                       /* reset last position */
-                       player->last_position = 0;
+                       if ((GST_TIME_AS_SECONDS(player->last_position) <= 0) && (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PAUSED)) {
+                               msg_param.connection.buffering = player->streamer->buffering_percent;
+                               MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
+                       } else {
+                               LOGD("Not updating Buffering Message for Live RTSP case !!!\n");
+                       }
+               } else {
+                       msg_param.connection.buffering = player->streamer->buffering_percent;
+                       MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
                }
-               break;
+       }
+       MMPLAYER_CMD_UNLOCK(player);
 
-       case GST_MESSAGE_ERROR:
-               {
-                       GError *error = NULL;
-                       gchar* debug = NULL;
+       MMPLAYER_FLEAVE();
+       return;
+
+}
+
+static void
+__mmplayer_gst_handle_state_message(mm_player_t* player, GstMessage *msg)
+{
+       MMPlayerGstElement *mainbin;
+       const GValue *voldstate, *vnewstate, *vpending;
+       GstState oldstate = GST_STATE_NULL;
+       GstState newstate = GST_STATE_NULL;
+       GstState pending = GST_STATE_NULL;
 
-                       /* generating debug info before returning error */
-                       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-error");
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
 
-                       /* get error code */
-                       gst_message_parse_error(msg, &error, &debug);
+       mainbin = player->pipeline->mainbin;
 
-                       if (gst_structure_has_name(gst_message_get_structure(msg), "streaming_error")) {
-                               /* Note : the streaming error from the streaming source is handled
-                                *   using __mmplayer_handle_streaming_error.
-                                */
-                               __mmplayer_handle_streaming_error(player, msg);
+       /* we only handle messages from pipeline */
+       if (msg->src != (GstObject *)mainbin[MMPLAYER_M_PIPE].gst)
+               return;
 
-                               /* dump state of all element */
-                               __mmplayer_dump_pipeline_state(player);
-                       } else {
-                               /* traslate gst error code to msl error code. then post it
-                                * to application if needed
-                                */
-                               __mmplayer_handle_gst_error(player, msg, error);
+       /* get state info from msg */
+       voldstate = gst_structure_get_value(gst_message_get_structure(msg), "old-state");
+       vnewstate = gst_structure_get_value(gst_message_get_structure(msg), "new-state");
+       vpending = gst_structure_get_value(gst_message_get_structure(msg), "pending-state");
 
-                               if (debug)
-                                       LOGE("error debug : %s", debug);
-                       }
+       if (!voldstate || !vnewstate) {
+               LOGE("received msg has wrong format.");
+               return;
+       }
 
-                       if (MMPLAYER_IS_HTTP_PD(player))
-                               _mmplayer_unrealize_pd_downloader((MMHandleType)player);
+       oldstate = (GstState)voldstate->data[0].v_int;
+       newstate = (GstState)vnewstate->data[0].v_int;
+       if (vpending)
+               pending = (GstState)vpending->data[0].v_int;
 
-                       MMPLAYER_FREEIF(debug);
-                       g_error_free(error);
+       LOGD("state changed [%s] : %s ---> %s     final : %s",
+               GST_OBJECT_NAME(GST_MESSAGE_SRC(msg)),
+               gst_element_state_get_name((GstState)oldstate),
+               gst_element_state_get_name((GstState)newstate),
+               gst_element_state_get_name((GstState)pending));
+
+       if (newstate == GST_STATE_PLAYING) {
+               if ((MMPLAYER_IS_RTSP_STREAMING(player)) && (player->pending_seek.is_pending)) {
+
+                       int retVal = MM_ERROR_NONE;
+                       LOGD("trying to play from (%"G_GINT64_FORMAT") pending position", player->pending_seek.pos);
+
+                       retVal = __mmplayer_gst_set_position(player, player->pending_seek.format, player->pending_seek.pos, TRUE);
+
+                       if (MM_ERROR_NONE != retVal)
+                               LOGE("failed to seek pending postion. just keep staying current position.");
+
+                       player->pending_seek.is_pending = FALSE;
                }
-               break;
+       }
 
-       case GST_MESSAGE_WARNING:
+       if (oldstate == newstate) {
+               LOGD("pipeline reports state transition to old state");
+               return;
+       }
+
+       switch (newstate) {
+       case GST_STATE_PAUSED:
                {
-                       char* debug = NULL;
-                       GError* error = NULL;
+                       gboolean prepare_async = FALSE;
 
-                       gst_message_parse_warning(msg, &error, &debug);
+                       if (!player->audio_cb_probe_id && player->set_mode.pcm_extraction && !player->audio_stream_render_cb_ex)
+                               __mmplayer_configure_audio_callback(player);
 
-                       LOGD("warning : %s\n", error->message);
-                       LOGD("debug : %s\n", debug);
+                       if (!player->sent_bos && oldstate == GST_STATE_READY) {
+                               // managed prepare async case
+                               mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &prepare_async);
+                               LOGD("checking prepare mode for async transition - %d", prepare_async);
+                       }
 
-                       MMPLAYER_POST_MSG(player, MM_MESSAGE_WARNING, NULL);
+                       if (MMPLAYER_IS_STREAMING(player) || MMPLAYER_IS_MS_BUFF_SRC(player) || prepare_async) {
+                               MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PAUSED);
 
-                       MMPLAYER_FREEIF(debug);
-                       g_error_free(error);
+                               if (MMPLAYER_IS_STREAMING(player) && (player->streamer))
+                                       __mm_player_streaming_set_content_bitrate(player->streamer,
+                                               player->total_maximum_bitrate, player->total_bitrate);
+
+                               if (player->pending_seek.is_pending) {
+                                       LOGW("trying to do pending seek");
+                                       MMPLAYER_CMD_LOCK(player);
+                                       __mmplayer_gst_pending_seek(player);
+                                       MMPLAYER_CMD_UNLOCK(player);
+                               }
+                       }
                }
                break;
 
-       case GST_MESSAGE_TAG:
+       case GST_STATE_PLAYING:
                {
-                       LOGD("GST_MESSAGE_TAG\n");
-                       if (!__mmplayer_gst_extract_tag_from_msg(player, msg))
-                               LOGW("failed to extract tags from gstmessage\n");
+                       if (MMPLAYER_IS_STREAMING(player)) {
+                               // managed prepare async case when buffering is completed
+                               // pending state should be reset otherwise, it's still playing even though it's resumed after bufferging.
+                               if ((MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING) ||
+                                       (MMPLAYER_PENDING_STATE(player) == MM_PLAYER_STATE_PLAYING))
+                                       MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PLAYING);
+
+                               if (MMPLAYER_IS_RTSP_STREAMING(player) && (MMPLAYER_IS_LIVE_STREAMING(player))) {
+
+                                       LOGD("Current Buffering Percent = %d", player->streamer->buffering_percent);
+                                       if (player->streamer->buffering_percent < 100) {
+
+                                               MMMessageParamType msg_param = {0, };
+                                               LOGW("Posting Buffering Completed Message to Application !!!");
+
+                                               msg_param.connection.buffering = 100;
+                                               MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
+                                       }
+                               }
+                       }
+
+                       if (player->gapless.stream_changed) {
+                               __mmplayer_update_content_attrs(player, ATTR_ALL);
+                               player->gapless.stream_changed = FALSE;
+                       }
+
+                       if (player->seek_state == MMPLAYER_SEEK_COMPLETED) {
+                               player->seek_state = MMPLAYER_SEEK_NONE;
+                               MMPLAYER_POST_MSG(player, MM_MESSAGE_SEEK_COMPLETED, NULL);
+                       }
                }
                break;
+       case GST_STATE_VOID_PENDING:
+       case GST_STATE_NULL:
+       case GST_STATE_READY:
+       default:
+               break;
+       }
 
-       case GST_MESSAGE_BUFFERING:
-               {
-                       MMMessageParamType msg_param = {0, };
-                       int bRet = MM_ERROR_NONE;
+       MMPLAYER_FLEAVE();
+       return;
+}
 
-                       if (!(player->pipeline && player->pipeline->mainbin)) {
-                               LOGE("Pipeline is not initialized");
-                               break;
-                       }
+static void
+__mmplayer_gst_handle_element_message(mm_player_t* player, GstMessage *msg)
+{
+       const gchar *structure_name;
+       gint count = 0, idx = 0;
+       MMHandleType attrs = 0;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
 
-                       if (!MMPLAYER_IS_STREAMING(player))
-                               break;
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if (!attrs) {
+               LOGE("Failed to get content attribute");
+               return;
+       }
 
-                       if (player->pd_mode == MM_PLAYER_PD_MODE_URI) {
-                               if (!MMPLAYER_CMD_TRYLOCK(player)) {
-                                       /* skip the playback control by buffering msg while user request is handled. */
-                                       gint per = 0;
+       if (gst_message_get_structure(msg) == NULL)
+               return;
 
-                                       LOGW("[PD mode] can't get cmd lock, only post buffering msg");
+       structure_name = gst_structure_get_name(gst_message_get_structure(msg));
+       if (!structure_name)
+               return;
 
-                                       gst_message_parse_buffering(msg, &per);
-                                       LOGD("[PD mode][%s] buffering %d %%....", GST_OBJECT_NAME(GST_MESSAGE_SRC(msg)), per);
+       LOGD("GST_MESSAGE_ELEMENT %s from %s", structure_name, GST_OBJECT_NAME(GST_MESSAGE_SRC(msg)));
 
-                                       msg_param.connection.buffering = per;
-                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
-                                       break;
-                               }
-                       } else {
-                               MMPLAYER_CMD_LOCK(player);
-                       }
+       if (!strcmp(structure_name, "adaptive-streaming-variant")) {
+               const GValue *var_info = NULL;
 
-                       if (!player->streamer) {
-                               LOGW("Pipeline is shutting down");
-                               MMPLAYER_CMD_UNLOCK(player);
-                               break;
-                       }
+               var_info = gst_structure_get_value(gst_message_get_structure(msg), "video-variant-info");
+               if (var_info != NULL) {
+                       if (player->adaptive_info.var_list)
+                               g_list_free_full(player->adaptive_info.var_list, g_free);
 
-                       /* ignore the remained buffering message till getting 100% msg */
-                       if (player->streamer->buffering_state == MM_PLAYER_BUFFERING_COMPLETE) {
-                               gint buffer_percent = 0;
+                       /* share addr or copy the list */
+                       player->adaptive_info.var_list =
+                               g_list_copy_deep((GList *)g_value_get_pointer(var_info), (GCopyFunc)__mmplayer_adaptive_var_info, NULL);
 
-                               gst_message_parse_buffering(msg, &buffer_percent);
+                       count = g_list_length(player->adaptive_info.var_list);
+                       if (count > 0) {
+                               VariantData *temp = NULL;
 
-                               if (buffer_percent == MAX_BUFFER_PERCENT) {
-                                       LOGD("Ignored all the previous buffering msg!(got %d%%)\n", buffer_percent);
-                                       player->streamer->buffering_state = MM_PLAYER_BUFFERING_DEFAULT;
+                               /* print out for debug */
+                               LOGD("num of variant_info %d", count);
+                               for (idx = 0; idx < count; idx++) {
+                                       temp = g_list_nth_data(player->adaptive_info.var_list, idx);
+                                       if (temp)
+                                               LOGD("variant(%d) [b]%d [w]%d [h]%d ", idx, temp->bandwidth, temp->width, temp->height);
                                }
-                               MMPLAYER_CMD_UNLOCK(player);
-                               break;
                        }
+               }
+       }
 
-                       /* ignore the remained buffering message */
-                       if (player->streamer->buffering_state == MM_PLAYER_BUFFERING_ABORT) {
-                               gint buffer_percent = 0;
+       if (!strcmp(structure_name, "prepare-decode-buffers")) {
+               gint num_buffers = 0;
+               gint extra_num_buffers = 0;
 
-                               gst_message_parse_buffering(msg, &buffer_percent);
+               if (gst_structure_get_int(gst_message_get_structure(msg), "num_buffers", &num_buffers)) {
+                       player->video_num_buffers = num_buffers;
+                       LOGD("video_num_buffers : %d", player->video_num_buffers);
+               }
 
-                               LOGD("interrupted buffering -last posted %d %%, new per %d %%",
-                                                       player->streamer->buffering_percent, buffer_percent);
+               if (gst_structure_get_int(gst_message_get_structure(msg), "extra_num_buffers", &extra_num_buffers)) {
+                       player->video_extra_num_buffers = extra_num_buffers;
+                       LOGD("num_of_vout_extra num buffers : %d", extra_num_buffers);
+               }
+               return;
+       }
 
-                               if (player->streamer->buffering_percent > buffer_percent || buffer_percent <= 0) {
-                                       player->streamer->buffering_state = MM_PLAYER_BUFFERING_DEFAULT;
-                                       player->streamer->buffering_req.is_pre_buffering = FALSE;
+       if (!strcmp(structure_name, "Language_list")) {
+               const GValue *lang_list = NULL;
+               lang_list = gst_structure_get_value(gst_message_get_structure(msg), "lang_list");
+               if (lang_list != NULL) {
+                       count = g_list_length((GList *)g_value_get_pointer(lang_list));
+                       if (count > 1)
+                               LOGD("Total audio tracks(from parser) = %d \n", count);
+               }
+       }
 
-                                       LOGD("interrupted buffering - need to enter the buffering mode again - %d %%", buffer_percent);
-                               } else {
-                                       LOGD("interrupted buffering - ignored the remained buffering msg!");
-                                       MMPLAYER_CMD_UNLOCK(player);
-                                       break;
+       if (!strcmp(structure_name, "Ext_Sub_Language_List")) {
+               const GValue *lang_list = NULL;
+               MMPlayerLangStruct *temp = NULL;
+
+               lang_list = gst_structure_get_value(gst_message_get_structure(msg), "lang_list");
+               if (lang_list != NULL) {
+                       count = g_list_length((GList *)g_value_get_pointer(lang_list));
+                       if (count) {
+                               MMPLAYER_SUBTITLE_INFO_LOCK(player);
+                               player->subtitle_language_list = (GList *)g_value_get_pointer(lang_list);
+                               mm_attrs_set_int_by_name(attrs, "content_text_track_num", (gint)count);
+                               if (mmf_attrs_commit(attrs))
+                                       LOGE("failed to commit.\n");
+                               LOGD("Total subtitle tracks = %d \n", count);
+
+                               while (count) {
+                                       temp = g_list_nth_data(player->subtitle_language_list, count - 1);
+                                       if (temp)
+                                               LOGD("value of lang_key is %s and lang_code is %s",
+                                                                       temp->language_key, temp->language_code);
+                                       count--;
                                }
+                               MMPLAYER_SUBTITLE_INFO_SIGNAL(player);
+                               MMPLAYER_SUBTITLE_INFO_UNLOCK(player);
                        }
+               }
+       }
 
-                       __mmplayer_update_buffer_setting(player, msg);
+       /* custom message */
+       if (!strcmp(structure_name, "audio_codec_not_supported")) {
+               MMMessageParamType msg_param = {0,};
+               msg_param.code = MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
+               MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
+       }
 
-                       bRet = __mmplayer_handle_buffering_message(player); /* playback control */
+       /* custom message for RTSP attribute :
+               RTSP case, buffer is not come from server before PLAYING state. However,we have to get attribute after PAUSE state chaged.
+               sdp which has contents info is received when rtsp connection is opened.
+               extract duration ,codec info , resolution from sdp and get it by GstMessage */
+       if (!strcmp(structure_name, "rtspsrc_properties")) {
 
-                       if (bRet == MM_ERROR_NONE) {
-                               msg_param.connection.buffering = player->streamer->buffering_percent;
-                               MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
+               gchar *audio_codec = NULL;
+               gchar *video_codec = NULL;
+               gchar *video_frame_size = NULL;
 
-                               if (MMPLAYER_IS_RTSP_STREAMING(player) &&
-                                       player->pending_resume &&
-                                       (player->streamer->buffering_percent >= MAX_BUFFER_PERCENT)) {
+               gst_structure_get(gst_message_get_structure(msg), "rtsp_duration", G_TYPE_UINT64, &player->duration, NULL);
+               LOGD("rtsp duration : %"G_GINT64_FORMAT" msec", GST_TIME_AS_MSECONDS(player->duration));
+               player->streaming_type = __mmplayer_get_stream_service_type(player);
 
-                                       player->is_external_subtitle_added_now = FALSE;
-                                       player->pending_resume = FALSE;
-                                       _mmplayer_resume((MMHandleType)player);
-                               }
+               gst_structure_get(gst_message_get_structure(msg), "rtsp_audio_codec", G_TYPE_STRING, &audio_codec, NULL);
+               LOGD("rtsp_audio_codec : %s", audio_codec);
+               if (audio_codec)
+                       mm_attrs_set_string_by_name(player->attrs, "content_audio_codec", audio_codec);
 
-                               if (MMPLAYER_IS_RTSP_STREAMING(player) &&
-                                       (player->streamer->buffering_percent >= MAX_BUFFER_PERCENT)) {
+               gst_structure_get(gst_message_get_structure(msg), "rtsp_video_codec", G_TYPE_STRING, &video_codec, NULL);
+               LOGD("rtsp_video_codec : %s", video_codec);
+               if (video_codec)
+                       mm_attrs_set_string_by_name(player->attrs, "content_video_codec", video_codec);
 
-                                       if (player->seek_state == MMPLAYER_SEEK_IN_PROGRESS) {
-                                               if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PAUSED) {
-                                                       player->seek_state = MMPLAYER_SEEK_NONE;
-                                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_SEEK_COMPLETED, NULL);
-                                               } else if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PLAYING) {
-                                                       /* Considering the async state trasition in case of RTSP.
-                                                          After getting state change gst msg, seek cmpleted msg will be posted. */
-                                                       player->seek_state = MMPLAYER_SEEK_COMPLETED;
-                                               }
-                                       }
-                               }
-                       } else if (bRet == MM_ERROR_PLAYER_INVALID_STATE) {
-                               if (!player->streamer) {
-                                       LOGW("player->streamer is NULL, so discarding the buffering percent update\n");
-                                       MMPLAYER_CMD_UNLOCK(player);
-                                       break;
-                               }
+               gst_structure_get(gst_message_get_structure(msg), "rtsp_video_frame_size", G_TYPE_STRING, &video_frame_size, NULL);
+               LOGD("rtsp_video_frame_size : %s", video_frame_size);
+               if (video_frame_size) {
 
-                               if ((MMPLAYER_IS_LIVE_STREAMING(player)) && (MMPLAYER_IS_RTSP_STREAMING(player))) {
+                       char *seperator = strchr(video_frame_size, '-');
+                       if (seperator) {
 
-                                       LOGD("player->last_position=%"G_GINT64_FORMAT" , player->streamer->buffering_percent=%d \n",
-                                                       GST_TIME_AS_SECONDS(player->last_position), player->streamer->buffering_percent);
+                               char video_width[10] = {0,};
+                               int frame_size_len = strlen(video_frame_size);
+                               int separtor_len = strlen(seperator);
 
-                                       if ((GST_TIME_AS_SECONDS(player->last_position) <= 0) && (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PAUSED)) {
-                                               msg_param.connection.buffering = player->streamer->buffering_percent;
-                                               MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
-                                       } else {
-                                               LOGD("Not updating Buffering Message for Live RTSP case !!!\n");
-                                       }
-                               } else {
-                                       msg_param.connection.buffering = player->streamer->buffering_percent;
-                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
-                               }
+                               strncpy(video_width, video_frame_size, (frame_size_len - separtor_len));
+                               mm_attrs_set_int_by_name(attrs, "content_video_width", atoi(video_width));
+
+                               seperator++;
+                               mm_attrs_set_int_by_name(attrs, "content_video_height", atoi(seperator));
                        }
-                       MMPLAYER_CMD_UNLOCK(player);
                }
-               break;
 
-       case GST_MESSAGE_STATE_CHANGED:
-               {
-                       MMPlayerGstElement *mainbin;
-                       const GValue *voldstate, *vnewstate, *vpending;
-                       GstState oldstate = GST_STATE_NULL;
-                       GstState newstate = GST_STATE_NULL;
-                       GstState pending = GST_STATE_NULL;
-
-                       if (!(player->pipeline && player->pipeline->mainbin)) {
-                               LOGE("player pipeline handle is null");
-                               break;
-                       }
+               if (mmf_attrs_commit(attrs))
+                       LOGE("failed to commit.\n");
+       }
+
+       MMPLAYER_FLEAVE();
+       return;
+}
+
+static void
+__mmplayer_gst_handle_async_done_message(mm_player_t* player, GstMessage *msg)
+{
+       MMPlayerGstElement *mainbin;
 
-                       mainbin = player->pipeline->mainbin;
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
 
-                       /* we only handle messages from pipeline */
-                       if (msg->src != (GstObject *)mainbin[MMPLAYER_M_PIPE].gst)
-                               break;
+       mainbin = player->pipeline->mainbin;
+
+       LOGD("GST_MESSAGE_ASYNC_DONE : %s", GST_ELEMENT_NAME(GST_MESSAGE_SRC(msg)));
 
-                       /* get state info from msg */
-                       voldstate = gst_structure_get_value(gst_message_get_structure(msg), "old-state");
-                       vnewstate = gst_structure_get_value(gst_message_get_structure(msg), "new-state");
-                       vpending = gst_structure_get_value(gst_message_get_structure(msg), "pending-state");
+       /* we only handle messages from pipeline */
+       if (msg->src != (GstObject *)mainbin[MMPLAYER_M_PIPE].gst)
+               return;
 
-                       if (!voldstate || !vnewstate) {
-                               LOGE("received msg has wrong format.");
-                               break;
+       if (player->seek_state == MMPLAYER_SEEK_IN_PROGRESS) {
+               if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PAUSED) {
+                       player->seek_state = MMPLAYER_SEEK_NONE;
+                       MMPLAYER_POST_MSG(player, MM_MESSAGE_SEEK_COMPLETED, NULL);
+               } else if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PLAYING) {
+                       if (mainbin[MMPLAYER_M_AUTOPLUG].gst) {
+                               LOGD("sync %s state(%s) with parent state(%s)",
+                                       GST_ELEMENT_NAME(mainbin[MMPLAYER_M_AUTOPLUG].gst),
+                                       gst_element_state_get_name(GST_STATE(mainbin[MMPLAYER_M_AUTOPLUG].gst)),
+                                       gst_element_state_get_name(GST_STATE(mainbin[MMPLAYER_M_PIPE].gst)));
+
+                               /* In case of streaming, pause is required before finishing seeking by buffering.
+                                  After completing the seek(during buffering), the player and sink elems has paused state but others in playing state.
+                                  Because the buffering state is controlled according to the state transition for force resume,
+                                  the decodebin state should be paused as player state. */
+                               gst_element_sync_state_with_parent(mainbin[MMPLAYER_M_AUTOPLUG].gst);
                        }
 
-                       oldstate = (GstState)voldstate->data[0].v_int;
-                       newstate = (GstState)vnewstate->data[0].v_int;
-                       if (vpending)
-                               pending = (GstState)vpending->data[0].v_int;
+                       if ((MMPLAYER_IS_HTTP_STREAMING(player)) &&
+                               (player->streamer) &&
+                               (player->streamer->streaming_buffer_type == BUFFER_TYPE_MUXED) &&
+                               !(player->streamer->buffering_state & MM_PLAYER_BUFFERING_IN_PROGRESS)) {
+                               GstQuery *query = NULL;
+                               gboolean busy = FALSE;
+                               gint percent = 0;
+
+                               if (player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer) {
+                                       query = gst_query_new_buffering(GST_FORMAT_PERCENT);
+                                       if (gst_element_query(player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer, query))
+                                               gst_query_parse_buffering_percent(query, &busy, &percent);
+                                       gst_query_unref(query);
+
+                                       LOGD("buffered percent(%s): %d\n",
+                                               GST_ELEMENT_NAME(player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer), percent);
+                               }
 
-                       LOGD("state changed [%s] : %s ---> %s     final : %s\n",
-                               GST_OBJECT_NAME(GST_MESSAGE_SRC(msg)),
-                               gst_element_state_get_name((GstState)oldstate),
-                               gst_element_state_get_name((GstState)newstate),
-                               gst_element_state_get_name((GstState)pending));
+                               if (percent >= 100)
+                                       __mmplayer_handle_buffering_playback(player);
+                       }
 
-                       if (newstate == GST_STATE_PLAYING) {
-                               if ((MMPLAYER_IS_RTSP_STREAMING(player)) && (player->pending_seek.is_pending)) {
+                       player->seek_state = MMPLAYER_SEEK_COMPLETED;
+               }
+       }
 
-                                       int retVal = MM_ERROR_NONE;
-                                       LOGD("trying to play from (%"G_GINT64_FORMAT") pending position\n", player->pending_seek.pos);
+       MMPLAYER_FLEAVE();
+       return;
+}
 
-                                       retVal = __mmplayer_gst_set_position(player, player->pending_seek.format, player->pending_seek.pos, TRUE);
 
-                                       if (MM_ERROR_NONE != retVal)
-                                               LOGE("failed to seek pending postion. just keep staying current position.\n");
+#if 0
+#endif
 
-                                       player->pending_seek.is_pending = FALSE;
-                               }
-                       }
+int
+__mmplayer_gst_set_state(mm_player_t* player, GstElement * element,  GstState state, gboolean async, gint timeout)
+{
+       GstState element_state = GST_STATE_VOID_PENDING;
+       GstState element_pending_state = GST_STATE_VOID_PENDING;
+       GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
 
-                       if (oldstate == newstate) {
-                               LOGD("pipeline reports state transition to old state");
-                               break;
-                       }
+       MMPLAYER_FENTER();
 
-                       switch (newstate) {
-                       case GST_STATE_VOID_PENDING:
-                               break;
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(element, MM_ERROR_INVALID_ARGUMENT);
 
-                       case GST_STATE_NULL:
-                               break;
+       LOGD("setting [%s] element state to : %s\n", GST_ELEMENT_NAME(element), gst_element_state_get_name(state));
 
-                       case GST_STATE_READY:
-                               break;
+       /* set state */
+       ret = gst_element_set_state(element, state);
 
-                       case GST_STATE_PAUSED:
-                               {
-                                       gboolean prepare_async = FALSE;
+       if (ret == GST_STATE_CHANGE_FAILURE) {
+               LOGE("failed to set [%s] state\n", GST_ELEMENT_NAME(element));
 
-                                       if (!player->audio_cb_probe_id && player->set_mode.pcm_extraction && !player->audio_stream_render_cb_ex)
-                                               __mmplayer_configure_audio_callback(player);
+               /* dump state of all element */
+               __mmplayer_dump_pipeline_state(player);
 
-                                       if (!player->sent_bos && oldstate == GST_STATE_READY) {
-                                               // managed prepare async case
-                                               mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &prepare_async);
-                                               LOGD("checking prepare mode for async transition - %d", prepare_async);
-                                       }
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-                                       if (MMPLAYER_IS_STREAMING(player) || MMPLAYER_IS_MS_BUFF_SRC(player) || prepare_async) {
-                                               MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PAUSED);
+       /* return here so state transition to be done in async mode */
+       if (async) {
+               LOGD("async state transition. not waiting for state complete.\n");
+               return MM_ERROR_NONE;
+       }
 
-                                               if (MMPLAYER_IS_STREAMING(player) && (player->streamer))
-                                                       __mm_player_streaming_set_content_bitrate(player->streamer,
-                                                               player->total_maximum_bitrate, player->total_bitrate);
+       /* wait for state transition */
+       ret = gst_element_get_state(element, &element_state, &element_pending_state, timeout * GST_SECOND);
 
-                                               if (player->pending_seek.is_pending) {
-                                                       LOGW("trying to do pending seek");
-                                                       MMPLAYER_CMD_LOCK(player);
-                                                       __mmplayer_gst_pending_seek(player);
-                                                       MMPLAYER_CMD_UNLOCK(player);
-                                               }
-                                       }
-                               }
-                               break;
+       if (ret == GST_STATE_CHANGE_FAILURE || (state != element_state)) {
+               LOGE("failed to change [%s] element state to [%s] within %d sec\n",
+                       GST_ELEMENT_NAME(element),
+                       gst_element_state_get_name(state), timeout);
 
-                       case GST_STATE_PLAYING:
-                               {
-                                       if (MMPLAYER_IS_STREAMING(player)) {
-                                               // managed prepare async case when buffering is completed
-                                               // pending state should be reset otherwise, it's still playing even though it's resumed after bufferging.
-                                               if ((MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING) ||
-                                                       (MMPLAYER_PENDING_STATE(player) == MM_PLAYER_STATE_PLAYING))
-                                                       MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PLAYING);
+               LOGE(" [%s] state : %s   pending : %s \n",
+                       GST_ELEMENT_NAME(element),
+                       gst_element_state_get_name(element_state),
+                       gst_element_state_get_name(element_pending_state));
 
-                                               if (MMPLAYER_IS_RTSP_STREAMING(player) && (MMPLAYER_IS_LIVE_STREAMING(player))) {
+               /* dump state of all element */
+               __mmplayer_dump_pipeline_state(player);
 
-                                                       LOGD("Current Buffering Percent = %d", player->streamer->buffering_percent);
-                                                       if (player->streamer->buffering_percent < 100) {
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-                                                               MMMessageParamType msg_param = {0, };
-                                                               LOGW("Posting Buffering Completed Message to Application !!!");
+       LOGD("[%s] element state has changed\n", GST_ELEMENT_NAME(element));
 
-                                                               msg_param.connection.buffering = 100;
-                                                               MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
-                                                       }
-                                               }
-                                       }
+       MMPLAYER_FLEAVE();
 
-                                       if (player->gapless.stream_changed) {
-                                               __mmplayer_update_content_attrs(player, ATTR_ALL);
-                                               player->gapless.stream_changed = FALSE;
-                                       }
+       return MM_ERROR_NONE;
+}
 
-                                       if (player->seek_state == MMPLAYER_SEEK_COMPLETED) {
-                                               player->seek_state = MMPLAYER_SEEK_NONE;
-                                               MMPLAYER_POST_MSG(player, MM_MESSAGE_SEEK_COMPLETED, NULL);
-                                       }
-                               }
-                               break;
+void
+__mmplayer_gst_bus_msg_callback(GstMessage *msg, gpointer data)
+{
+       mm_player_t* player = (mm_player_t*)(data);
 
-                       default:
-                               break;
-                       }
+       MMPLAYER_RETURN_IF_FAIL(player);
+       MMPLAYER_RETURN_IF_FAIL(msg && GST_IS_MESSAGE(msg));
+
+       switch (GST_MESSAGE_TYPE(msg)) {
+       case GST_MESSAGE_UNKNOWN:
+               LOGD("unknown message received\n");
+               break;
+
+       case GST_MESSAGE_EOS:
+               LOGD("GST_MESSAGE_EOS received");
+               __mmplayer_gst_handle_eos_message(player, msg);
+               break;
+
+       case GST_MESSAGE_ERROR:
+               __mmplayer_gst_handle_error_message(player, msg);
+               break;
+
+       case GST_MESSAGE_WARNING:
+               {
+                       char* debug = NULL;
+                       GError* error = NULL;
+
+                       gst_message_parse_warning(msg, &error, &debug);
+
+                       LOGD("warning : %s\n", error->message);
+                       LOGD("debug : %s\n", debug);
+
+                       MMPLAYER_POST_MSG(player, MM_MESSAGE_WARNING, NULL);
+
+                       MMPLAYER_FREEIF(debug);
+                       g_error_free(error);
+               }
+               break;
+
+       case GST_MESSAGE_TAG:
+               {
+                       LOGD("GST_MESSAGE_TAG\n");
+                       if (!__mmplayer_gst_extract_tag_from_msg(player, msg))
+                               LOGW("failed to extract tags from gstmessage\n");
                }
                break;
 
+       case GST_MESSAGE_BUFFERING:
+               __mmplayer_gst_handle_buffering_message(player, msg);
+               break;
+
+       case GST_MESSAGE_STATE_CHANGED:
+               __mmplayer_gst_handle_state_message(player, msg);
+               break;
+
        case GST_MESSAGE_CLOCK_LOST:
                        {
                                GstClock *clock = NULL;
@@ -1891,161 +2142,7 @@ __mmplayer_gst_callback(GstMessage *msg, gpointer data)
                        break;
 
        case GST_MESSAGE_ELEMENT:
-                       {
-                               const gchar *structure_name;
-                               gint count = 0, idx = 0;
-                               MMHandleType attrs = 0;
-
-                               attrs = MMPLAYER_GET_ATTRS(player);
-                               if (!attrs) {
-                                       LOGE("cannot get content attribute");
-                                       break;
-                               }
-
-                               if (gst_message_get_structure(msg) == NULL)
-                                       break;
-
-                               structure_name = gst_structure_get_name(gst_message_get_structure(msg));
-                               if (!structure_name)
-                                       break;
-
-                               LOGD("GST_MESSAGE_ELEMENT %s from %s", structure_name, GST_OBJECT_NAME(GST_MESSAGE_SRC(msg)));
-
-                               if (!strcmp(structure_name, "adaptive-streaming-variant")) {
-                                       const GValue *var_info = NULL;
-
-                                       var_info = gst_structure_get_value(gst_message_get_structure(msg), "video-variant-info");
-                                       if (var_info != NULL) {
-                                               if (player->adaptive_info.var_list)
-                                                       g_list_free_full(player->adaptive_info.var_list, g_free);
-
-                                               /* share addr or copy the list */
-                                               player->adaptive_info.var_list =
-                                                       g_list_copy_deep((GList *)g_value_get_pointer(var_info), (GCopyFunc)__mmplayer_adaptive_var_info, NULL);
-
-                                               count = g_list_length(player->adaptive_info.var_list);
-                                               if (count > 0) {
-                                                       VariantData *temp = NULL;
-
-                                                       /* print out for debug */
-                                                       LOGD("num of variant_info %d", count);
-                                                       for (idx = 0; idx < count; idx++) {
-                                                               temp = g_list_nth_data(player->adaptive_info.var_list, idx);
-                                                               if (temp)
-                                                                       LOGD("variant(%d) [b]%d [w]%d [h]%d ", idx, temp->bandwidth, temp->width, temp->height);
-                                                       }
-                                               }
-                                       }
-                               }
-
-                               if (!strcmp(structure_name, "prepare-decode-buffers")) {
-                                       gint num_buffers = 0;
-                                       gint extra_num_buffers = 0;
-
-                                       if (gst_structure_get_int(gst_message_get_structure(msg), "num_buffers", &num_buffers)) {
-                                               player->video_num_buffers = num_buffers;
-                                               LOGD("video_num_buffers : %d", player->video_num_buffers);
-                                       }
-
-                                       if (gst_structure_get_int(gst_message_get_structure(msg), "extra_num_buffers", &extra_num_buffers)) {
-                                               player->video_extra_num_buffers = extra_num_buffers;
-                                               LOGD("num_of_vout_extra num buffers : %d", extra_num_buffers);
-                                       }
-                                       break;
-                               }
-
-                               if (!strcmp(structure_name, "Language_list")) {
-                                       const GValue *lang_list = NULL;
-                                       lang_list = gst_structure_get_value(gst_message_get_structure(msg), "lang_list");
-                                       if (lang_list != NULL) {
-                                               count = g_list_length((GList *)g_value_get_pointer(lang_list));
-                                               if (count > 1)
-                                                       LOGD("Total audio tracks(from parser) = %d \n", count);
-                                       }
-                               }
-
-                               if (!strcmp(structure_name, "Ext_Sub_Language_List")) {
-                                       const GValue *lang_list = NULL;
-                                       MMPlayerLangStruct *temp = NULL;
-
-                                       lang_list = gst_structure_get_value(gst_message_get_structure(msg), "lang_list");
-                                       if (lang_list != NULL) {
-                                               count = g_list_length((GList *)g_value_get_pointer(lang_list));
-                                               if (count) {
-                                                       MMPLAYER_SUBTITLE_INFO_LOCK(player);
-                                                       player->subtitle_language_list = (GList *)g_value_get_pointer(lang_list);
-                                                       mm_attrs_set_int_by_name(attrs, "content_text_track_num", (gint)count);
-                                                       if (mmf_attrs_commit(attrs))
-                                                               LOGE("failed to commit.\n");
-                                                       LOGD("Total subtitle tracks = %d \n", count);
-
-                                                       while (count) {
-                                                               temp = g_list_nth_data(player->subtitle_language_list, count - 1);
-                                                               if (temp)
-                                                                       LOGD("value of lang_key is %s and lang_code is %s",
-                                                                                               temp->language_key, temp->language_code);
-                                                               count--;
-                                                       }
-                                                       MMPLAYER_SUBTITLE_INFO_SIGNAL(player);
-                                                       MMPLAYER_SUBTITLE_INFO_UNLOCK(player);
-                                               }
-                                       }
-                               }
-
-                               /* custom message */
-                               if (!strcmp(structure_name, "audio_codec_not_supported")) {
-                                       MMMessageParamType msg_param = {0,};
-                                       msg_param.code = MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
-                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
-                               }
-
-                               /* custom message for RTSP attribute :
-                                   RTSP case, buffer is not come from server before PLAYING state. However,we have to get attribute after PAUSE state chaged.
-                                   sdp which has contents info is received when rtsp connection is opened.
-                                   extract duration ,codec info , resolution from sdp and get it by GstMessage */
-                               if (!strcmp(structure_name, "rtspsrc_properties")) {
-
-                                       gchar *audio_codec = NULL;
-                                       gchar *video_codec = NULL;
-                                       gchar *video_frame_size = NULL;
-
-                                       gst_structure_get(gst_message_get_structure(msg), "rtsp_duration", G_TYPE_UINT64, &player->duration, NULL);
-                                       LOGD("rtsp duration : %"G_GINT64_FORMAT" msec", GST_TIME_AS_MSECONDS(player->duration));
-                                       player->streaming_type = __mmplayer_get_stream_service_type(player);
-
-                                       gst_structure_get(gst_message_get_structure(msg), "rtsp_audio_codec", G_TYPE_STRING, &audio_codec, NULL);
-                                       LOGD("rtsp_audio_codec : %s", audio_codec);
-                                       if (audio_codec)
-                                               mm_attrs_set_string_by_name(player->attrs, "content_audio_codec", audio_codec);
-
-                                       gst_structure_get(gst_message_get_structure(msg), "rtsp_video_codec", G_TYPE_STRING, &video_codec, NULL);
-                                       LOGD("rtsp_video_codec : %s", video_codec);
-                                       if (video_codec)
-                                               mm_attrs_set_string_by_name(player->attrs, "content_video_codec", video_codec);
-
-                                       gst_structure_get(gst_message_get_structure(msg), "rtsp_video_frame_size", G_TYPE_STRING, &video_frame_size, NULL);
-                                       LOGD("rtsp_video_frame_size : %s", video_frame_size);
-                                       if (video_frame_size) {
-
-                                               char *seperator = strchr(video_frame_size, '-');
-                                               if (seperator) {
-
-                                                       char video_width[10] = {0,};
-                                                       int frame_size_len = strlen(video_frame_size);
-                                                       int separtor_len = strlen(seperator);
-
-                                                       strncpy(video_width, video_frame_size, (frame_size_len - separtor_len));
-                                                       mm_attrs_set_int_by_name(attrs, "content_video_width", atoi(video_width));
-
-                                                       seperator++;
-                                                       mm_attrs_set_int_by_name(attrs, "content_video_height", atoi(seperator));
-                                               }
-                                       }
-
-                                       if (mmf_attrs_commit(attrs))
-                                               LOGE("failed to commit.\n");
-                               }
-                       }
+               __mmplayer_gst_handle_element_message(player, msg);
                        break;
 
        case GST_MESSAGE_DURATION_CHANGED:
@@ -2054,7 +2151,6 @@ __mmplayer_gst_callback(GstMessage *msg, gpointer data)
                        if (!__mmplayer_gst_handle_duration(player, msg))
                                LOGW("failed to update duration");
                }
-
                break;
 
        case GST_MESSAGE_ASYNC_START:
@@ -2062,66 +2158,7 @@ __mmplayer_gst_callback(GstMessage *msg, gpointer data)
                break;
 
        case GST_MESSAGE_ASYNC_DONE:
-               {
-                       MMPlayerGstElement *mainbin;
-
-                       if (!(player->pipeline && player->pipeline->mainbin)) {
-                               LOGE("player pipeline handle is null");
-                               break;
-                       }
-
-                       mainbin = player->pipeline->mainbin;
-
-                       LOGD("GST_MESSAGE_ASYNC_DONE : %s\n", GST_ELEMENT_NAME(GST_MESSAGE_SRC(msg)));
-
-                       /* we only handle messages from pipeline */
-                       if (msg->src != (GstObject *)mainbin[MMPLAYER_M_PIPE].gst)
-                               break;
-
-                       if (player->seek_state == MMPLAYER_SEEK_IN_PROGRESS) {
-                               if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PAUSED) {
-                                       player->seek_state = MMPLAYER_SEEK_NONE;
-                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_SEEK_COMPLETED, NULL);
-                               } else if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PLAYING) {
-                                       if (mainbin[MMPLAYER_M_AUTOPLUG].gst) {
-                                               LOGD("sync %s state(%s) with parent state(%s)",
-                                                       GST_ELEMENT_NAME(mainbin[MMPLAYER_M_AUTOPLUG].gst),
-                                                       gst_element_state_get_name(GST_STATE(mainbin[MMPLAYER_M_AUTOPLUG].gst)),
-                                                       gst_element_state_get_name(GST_STATE(mainbin[MMPLAYER_M_PIPE].gst)));
-
-                                               /* In case of streaming, pause is required before finishing seeking by buffering.
-                                                  After completing the seek(during buffering), the player and sink elems has paused state but others in playing state.
-                                                  Because the buffering state is controlled according to the state transition for force resume,
-                                                  the decodebin state should be paused as player state. */
-                                               gst_element_sync_state_with_parent(mainbin[MMPLAYER_M_AUTOPLUG].gst);
-                                       }
-
-                                       if ((MMPLAYER_IS_HTTP_STREAMING(player)) &&
-                                               (player->streamer) &&
-                                               (player->streamer->streaming_buffer_type == BUFFER_TYPE_MUXED) &&
-                                               !(player->streamer->buffering_state & MM_PLAYER_BUFFERING_IN_PROGRESS)) {
-                                               GstQuery *query = NULL;
-                                               gboolean busy = FALSE;
-                                               gint percent = 0;
-
-                                               if (player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer) {
-                                                       query = gst_query_new_buffering(GST_FORMAT_PERCENT);
-                                                       if (gst_element_query(player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer, query))
-                                                               gst_query_parse_buffering_percent(query, &busy, &percent);
-                                                       gst_query_unref(query);
-
-                                                       LOGD("buffered percent(%s): %d\n",
-                                                               GST_ELEMENT_NAME(player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer), percent);
-                                               }
-
-                                               if (percent >= 100)
-                                                       __mmplayer_handle_buffering_message(player);
-                                       }
-
-                                       player->seek_state = MMPLAYER_SEEK_COMPLETED;
-                               }
-                       }
-               }
+               __mmplayer_gst_handle_async_done_message(player, msg);
                break;
 
        #if 0 /* delete unnecessary logs */
@@ -2151,7 +2188,7 @@ __mmplayer_gst_callback(GstMessage *msg, gpointer data)
 }
 
 GstBusSyncReply
-__mmplayer_bus_sync_callback(GstBus * bus, GstMessage * message, gpointer data)
+__mmplayer_gst_bus_sync_callback(GstBus * bus, GstMessage * message, gpointer data)
 {
        mm_player_t *player = (mm_player_t *)data;
        GstBusSyncReply reply = GST_BUS_DROP;
@@ -2170,7 +2207,7 @@ __mmplayer_bus_sync_callback(GstBus * bus, GstMessage * message, gpointer data)
        case GST_MESSAGE_STATE_CHANGED:
                /* post directly for fast launch */
                if (player->sync_handler) {
-                       __mmplayer_gst_callback(message, player);
+                       __mmplayer_gst_bus_msg_callback(message, player);
                        reply = GST_BUS_DROP;
                } else
                        reply = GST_BUS_PASS;
index af503cfd5ff11bd46e880dff756e037f97ac606d..16dbe4939b7840e88f8d70a7a11a296aff296eaa 100644 (file)
@@ -975,7 +975,7 @@ static gpointer __mmplayer_gst_bus_msg_thread(gpointer data)
                }
                MMPLAYER_BUS_MSG_THREAD_UNLOCK(player);
                /* handle the gst msg */
-               __mmplayer_gst_callback(msg, player);
+               __mmplayer_gst_bus_msg_callback(msg, player);
                MMPLAYER_BUS_MSG_THREAD_LOCK(player);
                gst_message_unref(msg);
        }
@@ -5801,7 +5801,7 @@ __mmplayer_gst_create_pipeline(mm_player_t* player)
        LOGW("bus watcher thread context = %p, watcher : %d", player->context.thread_default, player->bus_watcher);
 
        /* set sync handler to get tag synchronously */
-       gst_bus_set_sync_handler(bus, __mmplayer_bus_sync_callback, player, NULL);
+       gst_bus_set_sync_handler(bus, __mmplayer_gst_bus_sync_callback, player, NULL);
 
        /* finished */
        gst_object_unref(GST_OBJECT(bus));
@@ -7298,7 +7298,7 @@ _mmplayer_start(MMHandleType hplayer)
 
 /* NOTE: post "not supported codec message" to application
  * when one codec is not found during AUTOPLUGGING in MSL.
- * So, it's separated with error of __mmplayer_gst_callback().
+ * So, it's separated with error of __mmplayer_gst_bus_msg_callback().
  * And, if any codec is not found, don't send message here.
  * Because GST_ERROR_MESSAGE is posted by other plugin internally.
  */
@@ -9700,7 +9700,7 @@ __mmplayer_check_subtitle(mm_player_t* player)
        if (!subtitle_uri || !strlen(subtitle_uri))
                return FALSE;
 
-       LOGD("subtite uri is %s[%d]\n", subtitle_uri, strlen(subtitle_uri));
+       SECURE_LOGD("subtitle uri is %s[%d]", subtitle_uri, strlen(subtitle_uri));
        player->is_external_subtitle_present = TRUE;
 
        MMPLAYER_FLEAVE();