LOGD("skip error post because it's sent already.\n");
gst_structure_free(s);
- MMPLAYER_FLEAVE();
g_free(error_string);
+ MMPLAYER_FLEAVE();
return TRUE;
}
}
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;
}
}
-
-#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;
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:
if (!__mmplayer_gst_handle_duration(player, msg))
LOGW("failed to update duration");
}
-
break;
case GST_MESSAGE_ASYNC_START:
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 */
}
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;
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;