X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmm_player_gst.c;h=de2a740d89e1b489482ef068fa0a35aaca785adf;hb=1a6379fe9aa85fc0d6fc948c0658bbec6fd6e9a9;hp=03411a73436fa62b6f80ab81b695c4a000f9d174;hpb=cc16a2341a41f2501816181b051e825e29e71a25;p=platform%2Fcore%2Fmultimedia%2Flibmm-player.git diff --git a/src/mm_player_gst.c b/src/mm_player_gst.c index 03411a7..de2a740 100644 --- a/src/mm_player_gst.c +++ b/src/mm_player_gst.c @@ -243,9 +243,6 @@ __mmplayer_gst_transform_gsterror(mmplayer_t *player, GstMessage *message, GErro player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED); src_element = GST_ELEMENT_CAST(message->src); - if (!src_element) - return MM_ERROR_PLAYER_INTERNAL; - src_element_name = GST_ELEMENT_NAME(src_element); if (!src_element_name) return MM_ERROR_PLAYER_INTERNAL; @@ -687,7 +684,7 @@ __mmplayer_handle_streaming_error(mmplayer_t *player, GstMessage *message) if (message->src) { msg_src_element = GST_ELEMENT_NAME(GST_ELEMENT_CAST(message->src)); - LOGE("-Msg src : [%s] Code : [%x] Error : [%s]", + LOGE("-Msg src : [%s] Code : [0x%x] Error : [%s]", msg_src_element, msg_param.code, (char *)msg_param.data); } @@ -746,7 +743,7 @@ __mmplayer_gst_extract_tag_from_msg(mmplayer_t *player, GstMessage *msg) { /* macro for better code readability */ -#define MMPLAYER_UPDATE_TAG_STRING(gsttag, attribute, playertag) \ +#define MMPLAYER_UPDATE_TAG_STRING(gsttag, player, playertag) \ do { \ if (gst_tag_list_get_string(tag_list, gsttag, &string)) {\ if (string != NULL) { \ @@ -755,17 +752,19 @@ __mmplayer_gst_extract_tag_from_msg(mmplayer_t *player, GstMessage *msg) char *new_string = g_malloc(MM_MAX_STRING_LENGTH); \ strncpy(new_string, string, MM_MAX_STRING_LENGTH - 1); \ new_string[MM_MAX_STRING_LENGTH - 1] = '\0'; \ - mm_attrs_set_string_by_name(attribute, playertag, new_string); \ + mm_player_set_attribute((MMHandleType)player, NULL,\ + playertag, new_string, strlen(new_string), NULL); \ MMPLAYER_FREEIF(new_string); \ } else { \ - mm_attrs_set_string_by_name(attribute, playertag, string); \ + mm_player_set_attribute((MMHandleType)player, NULL,\ + playertag, string, strlen(string), NULL); \ } \ MMPLAYER_FREEIF(string); \ } \ } \ } while (0) -#define MMPLAYER_UPDATE_TAG_IMAGE(gsttag, attribute, playertag) \ +#define MMPLAYER_UPDATE_TAG_IMAGE(gsttag, player, playertag) \ do { \ GstSample *sample = NULL;\ if (gst_tag_list_get_sample_index(tag_list, gsttag, index, &sample)) {\ @@ -781,7 +780,8 @@ __mmplayer_gst_extract_tag_from_msg(mmplayer_t *player, GstMessage *msg) player->album_art = (gchar *)g_malloc(info.size);\ if (player->album_art) {\ memcpy(player->album_art, info.data, info.size);\ - mm_attrs_set_data_by_name(attribute, playertag, (void *)player->album_art, info.size);\ + mm_player_set_attribute((MMHandleType)player, NULL,\ + playertag, (void *)player->album_art, info.size, NULL); \ if (MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) {\ msg_param.data = (void *)player->album_art;\ msg_param.size = info.size;\ @@ -794,7 +794,7 @@ __mmplayer_gst_extract_tag_from_msg(mmplayer_t *player, GstMessage *msg) } \ } while (0) -#define MMPLAYER_UPDATE_TAG_UINT(gsttag, attribute, playertag) \ +#define MMPLAYER_UPDATE_TAG_UINT(gsttag, player, playertag) \ do { \ if (gst_tag_list_get_uint(tag_list, gsttag, &v_uint)) { \ if (v_uint) { \ @@ -808,34 +808,38 @@ __mmplayer_gst_extract_tag_from_msg(mmplayer_t *player, GstMessage *msg) track_type = MM_PLAYER_TRACK_TYPE_TEXT; \ if (!strncmp(gsttag, GST_TAG_BITRATE, strlen(GST_TAG_BITRATE))) { \ if (track_type == MM_PLAYER_TRACK_TYPE_AUDIO) \ - mm_attrs_set_int_by_name(attribute, "content_audio_bitrate", v_uint); \ + mm_player_set_attribute((MMHandleType)player, NULL,\ + "content_audio_bitrate", v_uint, NULL); \ player->bitrate[track_type] = v_uint; \ player->total_bitrate = 0; \ for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++) \ player->total_bitrate += player->bitrate[i]; \ - mm_attrs_set_int_by_name(attribute, playertag, player->total_bitrate); \ + mm_player_set_attribute((MMHandleType)player, NULL,\ + playertag, player->total_bitrate, NULL); \ SECURE_LOGD("update bitrate %d[bps] of stream #%d.", v_uint, (int)track_type); \ } else if (!strncmp(gsttag, GST_TAG_MAXIMUM_BITRATE, strlen(GST_TAG_MAXIMUM_BITRATE))) { \ player->maximum_bitrate[track_type] = v_uint; \ player->total_maximum_bitrate = 0; \ for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++) \ player->total_maximum_bitrate += player->maximum_bitrate[i]; \ - mm_attrs_set_int_by_name(attribute, playertag, player->total_maximum_bitrate);\ + mm_player_set_attribute((MMHandleType)player, NULL,\ + playertag, player->total_maximum_bitrate, NULL); \ SECURE_LOGD("update maximum bitrate %d[bps] of stream #%d", v_uint, (int)track_type);\ } else { \ - mm_attrs_set_int_by_name(attribute, playertag, v_uint); \ + mm_player_set_attribute((MMHandleType)player, NULL, playertag, v_uint, NULL); \ } \ v_uint = 0;\ } \ } \ } while (0) -#define MMPLAYER_UPDATE_TAG_DATE(gsttag, attribute, playertag) \ +#define MMPLAYER_UPDATE_TAG_DATE(gsttag, player, playertag) \ do { \ if (gst_tag_list_get_date(tag_list, gsttag, &date)) {\ if (date != NULL) {\ string = g_strdup_printf("%d", g_date_get_year(date));\ - mm_attrs_set_string_by_name(attribute, playertag, string);\ + mm_player_set_attribute((MMHandleType)player, NULL,\ + playertag, string, strlen(string), NULL); \ SECURE_LOGD("metainfo year : %s", string);\ MMPLAYER_FREEIF(string);\ g_date_free(date);\ @@ -843,12 +847,13 @@ __mmplayer_gst_extract_tag_from_msg(mmplayer_t *player, GstMessage *msg) } \ } while (0) -#define MMPLAYER_UPDATE_TAG_DATE_TIME(gsttag, attribute, playertag) \ +#define MMPLAYER_UPDATE_TAG_DATE_TIME(gsttag, player, playertag) \ do { \ if (gst_tag_list_get_date_time(tag_list, gsttag, &datetime)) {\ if (datetime != NULL) {\ string = g_strdup_printf("%d", gst_date_time_get_year(datetime));\ - mm_attrs_set_string_by_name(attribute, playertag, string);\ + mm_player_set_attribute((MMHandleType)player, NULL,\ + playertag, string, strlen(string), NULL); \ SECURE_LOGD("metainfo year : %s", string);\ MMPLAYER_FREEIF(string);\ gst_date_time_unref(datetime);\ @@ -856,33 +861,9 @@ __mmplayer_gst_extract_tag_from_msg(mmplayer_t *player, GstMessage *msg) } \ } while (0) -#define MMPLAYER_UPDATE_TAG_UINT64(gsttag, attribute, playertag) \ - do { \ - if (gst_tag_list_get_uint64(tag_list, gsttag, &v_uint64)) {\ - if (v_uint64) {\ - /* FIXIT : don't know how to store date */\ - g_assert(1);\ - v_uint64 = 0;\ - } \ - } \ - } while (0) - -#define MMPLAYER_UPDATE_TAG_DOUBLE(gsttag, attribute, playertag) \ - do { \ - if (gst_tag_list_get_double(tag_list, gsttag, &v_double)) {\ - if (v_double) {\ - /* FIXIT : don't know how to store date */\ - g_assert(1);\ - v_double = 0;\ - } \ - } \ - } while (0) - /* function start */ GstTagList *tag_list = NULL; - MMHandleType attrs = 0; - char *string = NULL; guint v_uint = 0; GDate *date = NULL; @@ -898,69 +879,34 @@ __mmplayer_gst_extract_tag_from_msg(mmplayer_t *player, GstMessage *msg) MMPLAYER_RETURN_VAL_IF_FAIL(player && msg, FALSE); - attrs = MMPLAYER_GET_ATTRS(player); - - MMPLAYER_RETURN_VAL_IF_FAIL(attrs, FALSE); - /* get tag list from gst message */ gst_message_parse_tag(msg, &tag_list); /* store tags to player attributes */ - MMPLAYER_UPDATE_TAG_STRING(GST_TAG_TITLE, attrs, "tag_title"); - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_TITLE_SORTNAME, ?, ?); */ - MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ARTIST, attrs, "tag_artist"); - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ARTIST_SORTNAME, ?, ?); */ - MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ALBUM, attrs, "tag_album"); - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ALBUM_SORTNAME, ?, ?); */ - MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COMPOSER, attrs, "tag_author"); - MMPLAYER_UPDATE_TAG_DATE(GST_TAG_DATE, attrs, "tag_date"); - MMPLAYER_UPDATE_TAG_DATE_TIME(GST_TAG_DATE_TIME, attrs, "tag_date"); - MMPLAYER_UPDATE_TAG_STRING(GST_TAG_GENRE, attrs, "tag_genre"); - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COMMENT, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_EXTENDED_COMMENT, ?, ?); */ - MMPLAYER_UPDATE_TAG_UINT(GST_TAG_TRACK_NUMBER, attrs, "tag_track_num"); - /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_TRACK_COUNT, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_ALBUM_VOLUME_NUMBER, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_ALBUM_VOLUME_COUNT, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LOCATION, ?, ?); */ - MMPLAYER_UPDATE_TAG_STRING(GST_TAG_DESCRIPTION, attrs, "tag_description"); - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_VERSION, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ISRC, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ORGANIZATION, ?, ?); */ - MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COPYRIGHT, attrs, "tag_copyright"); - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COPYRIGHT_URI, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_CONTACT, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LICENSE, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LICENSE_URI, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_PERFORMER, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_UINT64(GST_TAG_DURATION, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_CODEC, ?, ?); */ - MMPLAYER_UPDATE_TAG_STRING(GST_TAG_VIDEO_CODEC, attrs, "content_video_codec"); - MMPLAYER_UPDATE_TAG_STRING(GST_TAG_AUDIO_CODEC, attrs, "content_audio_codec"); - MMPLAYER_UPDATE_TAG_UINT(GST_TAG_BITRATE, attrs, "content_bitrate"); - MMPLAYER_UPDATE_TAG_UINT(GST_TAG_MAXIMUM_BITRATE, attrs, "content_max_bitrate"); + MMPLAYER_UPDATE_TAG_STRING(GST_TAG_TITLE, player, "tag_title"); + MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ARTIST, player, "tag_artist"); + MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ALBUM, player, "tag_album"); + MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COMPOSER, player, "tag_author"); + MMPLAYER_UPDATE_TAG_DATE(GST_TAG_DATE, player, "tag_date"); + MMPLAYER_UPDATE_TAG_DATE_TIME(GST_TAG_DATE_TIME, player, "tag_date"); + MMPLAYER_UPDATE_TAG_STRING(GST_TAG_GENRE, player, "tag_genre"); + MMPLAYER_UPDATE_TAG_UINT(GST_TAG_TRACK_NUMBER, player, "tag_track_num"); + MMPLAYER_UPDATE_TAG_STRING(GST_TAG_DESCRIPTION, player, "tag_description"); + MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COPYRIGHT, player, "tag_copyright"); + MMPLAYER_UPDATE_TAG_STRING(GST_TAG_VIDEO_CODEC, player, "content_video_codec"); + MMPLAYER_UPDATE_TAG_STRING(GST_TAG_AUDIO_CODEC, player, "content_audio_codec"); + MMPLAYER_UPDATE_TAG_UINT(GST_TAG_BITRATE, player, "content_bitrate"); + MMPLAYER_UPDATE_TAG_UINT(GST_TAG_MAXIMUM_BITRATE, player, "content_max_bitrate"); MMPLAYER_UPDATE_TAG_LOCK(player); - MMPLAYER_UPDATE_TAG_IMAGE(GST_TAG_IMAGE, attrs, "tag_album_cover"); + MMPLAYER_UPDATE_TAG_IMAGE(GST_TAG_IMAGE, player, "tag_album_cover"); MMPLAYER_UPDATE_TAG_UNLOCK(player); - /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_NOMINAL_BITRATE, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_MINIMUM_BITRATE, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_SERIAL, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ENCODER, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_ENCODER_VERSION, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_TRACK_GAIN, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_TRACK_PEAK, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_ALBUM_GAIN, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_ALBUM_PEAK, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_REFERENCE_LEVEL, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LANGUAGE_CODE, ?, ?); */ - /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_BEATS_PER_MINUTE, ?, ?); */ - MMPLAYER_UPDATE_TAG_STRING(GST_TAG_IMAGE_ORIENTATION, attrs, "content_video_orientation"); + MMPLAYER_UPDATE_TAG_STRING(GST_TAG_IMAGE_ORIENTATION, player, "content_video_orientation"); if (strstr(GST_OBJECT_NAME(msg->src), "demux")) { if (player->video360_metadata.is_spherical == -1) { __mmplayer_get_metadata_360_from_tags(tag_list, &player->video360_metadata); - mm_attrs_set_int_by_name(attrs, "content_video_is_spherical", - player->video360_metadata.is_spherical); + mm_player_set_attribute((MMHandleType)player, NULL, + "content_video_is_spherical", player->video360_metadata.is_spherical, NULL); if (player->video360_metadata.is_spherical == 1) { LOGD("This is spherical content for 360 playback."); player->is_content_spherical = TRUE; @@ -993,9 +939,6 @@ __mmplayer_gst_extract_tag_from_msg(mmplayer_t *player, GstMessage *msg) } } - if (mm_attrs_commit_all(attrs)) - LOGE("failed to commit."); - gst_tag_list_unref(tag_list); return TRUE; @@ -1022,6 +965,7 @@ __mmplayer_gst_check_useful_message(mmplayer_t *player, GstMessage *message) case GST_MESSAGE_ELEMENT: case GST_MESSAGE_DURATION_CHANGED: case GST_MESSAGE_ASYNC_START: + case GST_MESSAGE_STREAM_COLLECTION: retval = TRUE; break; case GST_MESSAGE_ASYNC_DONE: @@ -1057,6 +1001,35 @@ __mmplayer_gst_check_useful_message(mmplayer_t *player, GstMessage *message) break; } + case GST_MESSAGE_STREAMS_SELECTED: + { + if (!MMPLAYER_USE_URIDECODEBIN3(player)) + break; /* drop msg */ + + if ((MMPLAYER_IS_HTTP_STREAMING(player)) && + (!player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst) && + (player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst)) { + + gint64 dur_bytes = 0L; + + if (!gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes)) + LOGE("fail to get duration."); + + /* there is no mq, enable use-buffering on queue2 (ex) wav streaming + * use file information was already set on Q2 when it was created. */ + _mm_player_streaming_set_queue2(player->streamer, + player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst, + TRUE, /* use_buffering */ + MUXED_BUFFER_TYPE_MAX, /* use previous buffer type setting */ + ((dur_bytes > 0) ? ((guint64)dur_bytes) : 0)); + } + + LOGD("GST_MESSAGE_STREAMS_SELECTED"); + player->no_more_pad = TRUE; + _mmplayer_pipeline_complete(NULL, player); + retval = TRUE; + break; + } default: retval = FALSE; break; @@ -1774,17 +1747,10 @@ __mmplayer_gst_handle_element_message(mmplayer_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); - attrs = MMPLAYER_GET_ATTRS(player); - if (!attrs) { - LOGE("Failed to get content attribute"); - return; - } - if (gst_message_get_structure(msg) == NULL) return; @@ -1827,12 +1793,14 @@ __mmplayer_gst_handle_element_message(mmplayer_t *player, GstMessage *msg) if (gst_structure_get_int(gst_message_get_structure(msg), "num_buffers", &num_buffers)) { LOGD("video_num_buffers : %d", num_buffers); - mm_attrs_set_int_by_name(player->attrs, MM_PLAYER_VIDEO_BUFFER_TOTAL_SIZE, num_buffers); + mm_player_set_attribute((MMHandleType)player, NULL, + MM_PLAYER_VIDEO_BUFFER_TOTAL_SIZE, num_buffers, NULL); } if (gst_structure_get_int(gst_message_get_structure(msg), "extra_num_buffers", &extra_num_buffers)) { LOGD("num_of_vout_extra num buffers : %d", extra_num_buffers); - mm_attrs_set_int_by_name(player->attrs, MM_PLAYER_VIDEO_BUFFER_EXTRA_SIZE, extra_num_buffers); + mm_player_set_attribute((MMHandleType)player, NULL, + MM_PLAYER_VIDEO_BUFFER_EXTRA_SIZE, extra_num_buffers, NULL); } return; } @@ -1856,39 +1824,36 @@ __mmplayer_gst_handle_element_message(mmplayer_t *player, GstMessage *msg) 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); + 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); + 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(attrs, "content_audio_codec", audio_codec); + mm_player_set_attribute((MMHandleType)player, NULL, + "content_audio_codec", audio_codec, strlen(audio_codec), NULL); - gst_structure_get(gst_message_get_structure(msg), "rtsp_video_codec", G_TYPE_STRING, &video_codec, NULL); + 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(attrs, "content_video_codec", video_codec); + mm_player_set_attribute((MMHandleType)player, NULL, + "content_video_codec", video_codec, strlen(video_codec), NULL); - gst_structure_get(gst_message_get_structure(msg), "rtsp_video_frame_size", G_TYPE_STRING, &video_frame_size, NULL); + 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, MM_PLAYER_VIDEO_WIDTH, atoi(video_width)); - - seperator++; - mm_attrs_set_int_by_name(attrs, MM_PLAYER_VIDEO_HEIGHT, atoi(seperator)); - } + gchar **res_str = g_strsplit(video_frame_size, "-", 0); + mm_player_set_attribute((MMHandleType)player, NULL, + MM_PLAYER_VIDEO_WIDTH, atoi(res_str[0]), + MM_PLAYER_VIDEO_HEIGHT, atoi(res_str[1]), + NULL); + g_strfreev(res_str); } - - if (mm_attrs_commit_all(attrs)) - LOGE("failed to commit."); } MMPLAYER_FLEAVE(); @@ -1978,6 +1943,7 @@ __mmplayer_gst_bus_msg_callback(GstMessage *msg, gpointer data) break; case GST_MESSAGE_ERROR: + _mmplayer_set_reconfigure_state(player, FALSE); __mmplayer_gst_handle_error_message(player, msg); break; @@ -2062,6 +2028,12 @@ __mmplayer_gst_bus_msg_callback(GstMessage *msg, gpointer data) case GST_MESSAGE_ASYNC_DONE: __mmplayer_gst_handle_async_done_message(player, msg); break; + case GST_MESSAGE_STREAM_COLLECTION: + LOGD("GST_MESSAGE_STREAM_COLLECTION : %s", GST_ELEMENT_NAME(GST_MESSAGE_SRC(msg))); + break; + case GST_MESSAGE_STREAMS_SELECTED: + LOGD("GST_MESSAGE_STREAMS_SELECTED : %s", GST_ELEMENT_NAME(GST_MESSAGE_SRC(msg))); + break; #ifdef __DEBUG__ case GST_MESSAGE_REQUEST_STATE: LOGD("GST_MESSAGE_REQUEST_STATE"); break; @@ -2130,6 +2102,18 @@ __mmplayer_gst_bus_sync_callback(GstBus *bus, GstMessage *message, gpointer data case GST_MESSAGE_DURATION_CHANGED: __mmplayer_gst_handle_duration(player, message); break; + case GST_MESSAGE_ELEMENT: + { + const gchar *klass = NULL; + klass = gst_element_factory_get_metadata + (gst_element_get_factory((GstElement *)message->src), GST_ELEMENT_METADATA_KLASS); + if (!klass || !g_strrstr(klass, "Codec/Decoder")) { + reply = GST_BUS_PASS; + break; + } + __mmplayer_gst_handle_element_message(player, message); + } + break; case GST_MESSAGE_ASYNC_DONE: /* NOTE:Don't call gst_callback directly * because previous frame can be showed even though this message is received for seek. @@ -2351,6 +2335,10 @@ __mmplayer_gst_create_es_decoder(mmplayer_t *player, mmplayer_stream_type_e type _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select", G_CALLBACK(_mmplayer_gst_decode_autoplug_select), (gpointer)player); + if (player->need_video_dec_sorting || player->need_audio_dec_sorting) + _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-sort", + G_CALLBACK(_mmplayer_gst_decode_autoplug_sort), (gpointer)player); + /* This signal is emitted when a element is added to the bin.*/ _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "element-added", G_CALLBACK(_mmplayer_gst_element_added), (gpointer)player); @@ -2678,7 +2666,7 @@ __mmplayer_gst_rtp_no_more_pads(GstElement *element, gpointer data) if (!_mmplayer_gst_remove_fakesink(player, &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK])) - /* NOTE : __mmplayer_pipeline_complete() can be called several time. because + /* NOTE : _mmplayer_pipeline_complete() can be called several time. because * signaling mechanism(pad-added, no-more-pad, new-decoded-pad) from various * source element are not same. To overcome this situation, this function will called * several places and several times. Therefore, this is not an error case. @@ -2736,6 +2724,243 @@ __mmplayer_gst_make_rtsp_src(mmplayer_t *player) return element; } +void __mmplayer_http_src_setup(GstElement *element, GstElement *source, gpointer data) +{ +#define HTTP_SOURCE_BLOCK_SIZE (64 * 1024) + + mmplayer_t *player = (mmplayer_t *)data; + MMHandleType attrs = 0; + gchar *user_agent, *cookies, **cookie_list; + gint http_timeout = DEFAULT_HTTP_TIMEOUT; + user_agent = cookies = NULL; + cookie_list = NULL; + + MMPLAYER_FENTER(); + MMPLAYER_RETURN_IF_FAIL(player); + + LOGD("source element %s", GST_ELEMENT_NAME(source)); + + /* get profile attribute */ + attrs = MMPLAYER_GET_ATTRS(player); + if (!attrs) { + LOGE("failed to get content attribute"); + return; + } + + player->pipeline->mainbin[MMPLAYER_M_SRC].id = MMPLAYER_M_SRC; + player->pipeline->mainbin[MMPLAYER_M_SRC].gst = source; + + /* get attribute */ + mm_attrs_get_string_by_name(attrs, "streaming_cookie", &cookies); + mm_attrs_get_string_by_name(attrs, "streaming_user_agent", &user_agent); + + if (player->ini.http_timeout != DEFAULT_HTTP_TIMEOUT) + http_timeout = player->ini.http_timeout; + + /* get attribute */ + SECURE_LOGD("cookies : %s", cookies); + SECURE_LOGD("user_agent : %s", user_agent); + LOGD("timeout : %d", http_timeout); + + /* setting property to streaming source */ + g_object_set(G_OBJECT(source), "timeout", http_timeout, "blocksize", (unsigned long)(HTTP_SOURCE_BLOCK_SIZE), NULL); + + /* parsing cookies */ + if ((cookie_list = _mmplayer_get_cookie_list((const char *)cookies))) { + g_object_set(G_OBJECT(source), "cookies", cookie_list, NULL); + g_strfreev(cookie_list); + } + + if (user_agent) + g_object_set(G_OBJECT(source), "user-agent", user_agent, NULL); + + MMPLAYER_FLEAVE(); + return; +} + +gint __mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * collection, + GstStream * stream, gpointer data) +{ + GstStreamType stype = gst_stream_get_stream_type (stream); + + if (stype & GST_STREAM_TYPE_AUDIO) + LOGW("AUDIO type 0x%X", stype); + else if (stype & GST_STREAM_TYPE_VIDEO) + LOGW("VIDEO type 0x%X", stype); + else if (stype & GST_STREAM_TYPE_TEXT) + LOGW("TEXT type 0x%X", stype); + + return 1; +} + +void +__mmplayer_gst_deep_element_added(GstElement *bin, GstBin *child, GstElement *element, gpointer data) +{ + gchar *factory_name = NULL; + mmplayer_t *player = (mmplayer_t *)data; + mmplayer_gst_element_t *mainbin = NULL; + + MMPLAYER_FENTER(); + MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin); + + factory_name = GST_OBJECT_NAME(gst_element_get_factory(element)); + mainbin = player->pipeline->mainbin; + + LOGD("%s > %s > %s : %s", GST_ELEMENT_NAME(bin), GST_ELEMENT_NAME(child), + factory_name, GST_ELEMENT_NAME(element)); + + /* keep the first typefind reference only */ + if (!mainbin[MMPLAYER_M_TYPEFIND].gst && g_strrstr(factory_name, "typefind")) { + mainbin[MMPLAYER_M_TYPEFIND].id = MMPLAYER_M_TYPEFIND; + mainbin[MMPLAYER_M_TYPEFIND].gst = element; + + _mmplayer_add_signal_connection(player, G_OBJECT(element), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type", G_CALLBACK(_mmplayer_typefind_have_type), (gpointer)player); + + } else if (!mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst && g_strrstr(factory_name, "queue2")) { + + gint64 dur_bytes = 0L; + muxed_buffer_type_e type = MUXED_BUFFER_TYPE_MEM_QUEUE; + + mainbin[MMPLAYER_M_MUXED_S_BUFFER].id = MMPLAYER_M_MUXED_S_BUFFER; + mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = element; + + if (!gst_element_query_duration(mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes)) + LOGW("failed to get duration from source %s", GST_ELEMENT_NAME(mainbin[MMPLAYER_M_SRC].gst)); + + LOGD("type %s, dur_bytes = %"G_GINT64_FORMAT, player->type, dur_bytes); + + /* NOTE : in case of ts streaming, player could not get the correct duration info * + * skip the pull mode(file or ring buffering) setting. */ + if (dur_bytes > 0) { + if ((!g_strrstr(player->type, "video/mpegts")) && (!g_strrstr(player->type, "application/x-hls"))) { + type = MUXED_BUFFER_TYPE_MEM_RING_BUFFER; + player->streamer->ring_buffer_size = player->ini.http_ring_buffer_size; + } + } else { + dur_bytes = 0; + } + + _mm_player_streaming_set_queue2(player->streamer, + element, + FALSE, + type, + (guint64)dur_bytes); /* no meaning at the moment */ + + } else if (g_strrstr(factory_name, "parsebin")) { + + if (!mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst) { + GstIterator *iter = NULL; + GValue item = {0, }; + GstElement *ch_element = NULL; + GstElementFactory *ch_factory = NULL; + + g_object_set(G_OBJECT(child), "message-forward", TRUE, NULL); + + iter = gst_bin_iterate_recurse(child); + if (iter != NULL) { + while (gst_iterator_next(iter, &item) == GST_ITERATOR_OK) { + ch_element = g_value_get_object(&item); + ch_factory = gst_element_get_factory(ch_element); + + if (g_strrstr(GST_OBJECT_NAME(ch_factory), "multiqueue")) { + player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].id = MMPLAYER_M_DEMUXED_S_BUFFER; + player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst = ch_element; + + if ((MMPLAYER_IS_HTTP_STREAMING(player)) || + (MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) || + (MMPLAYER_IS_DASH_STREAMING(player))) { + _mm_player_streaming_set_multiqueue(player->streamer, ch_element); + } + g_value_reset(&item); + break; + } + g_value_reset(&item); + } + gst_iterator_free(iter); + } + } + mainbin[MMPLAYER_M_AUTOPLUG_PARSEBIN].id = MMPLAYER_M_AUTOPLUG_PARSEBIN; + mainbin[MMPLAYER_M_AUTOPLUG_PARSEBIN].gst = element; + _mmplayer_add_signal_connection(player, G_OBJECT(element), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "unknown-type", G_CALLBACK(_mmplayer_gst_decode_unknown_type), (gpointer)player); + + _mmplayer_add_signal_connection(player, G_OBJECT(element), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-continue", G_CALLBACK(_mmplayer_gst_decode_autoplug_continue), (gpointer)player); + + if (player->need_video_dec_sorting || player->need_audio_dec_sorting) + _mmplayer_add_signal_connection(player, G_OBJECT(element), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-sort", G_CALLBACK(_mmplayer_gst_decode_autoplug_sort), (gpointer)player); + + _mmplayer_add_signal_connection(player, G_OBJECT(element), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select", G_CALLBACK(_mmplayer_gst_decode_autoplug_select), (gpointer)player); + + } else { + _mmplayer_gst_element_added((GstElement *)child, element, data); + } + return; +} + +void +__mmplayer_gst_deep_element_removed(GstElement *bin, GstBin *child, GstElement *element, gpointer data) +{ + LOGD("%s > %s > %s", GST_ELEMENT_NAME(bin), GST_ELEMENT_NAME(child), GST_ELEMENT_NAME(element)); + return; +} + +static GstElement * +__mmplayer_gst_make_uridecodebin(mmplayer_t *player) +{ + GstElement *uridecodebin3 = NULL; + + MMPLAYER_FENTER(); + MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL); + + uridecodebin3 = gst_element_factory_make("uridecodebin3", "uridecodebin3"); + if (!uridecodebin3) { + LOGE("failed to create uridecodebin3"); + return NULL; + } + + /* get attribute */ + SECURE_LOGD("uri : %s", player->profile.uri); + + /* setting property to streaming source */ + g_object_set(G_OBJECT(uridecodebin3), "uri", player->profile.uri, "message-forward", TRUE, NULL); + + _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "source-setup", G_CALLBACK(__mmplayer_http_src_setup), (gpointer)player); + + _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added", G_CALLBACK(_mmplayer_gst_decode_pad_added), (gpointer)player); + + _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-removed", G_CALLBACK(_mmplayer_gst_decode_pad_removed), (gpointer)player); + + _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads", G_CALLBACK(_mmplayer_gst_decode_no_more_pads), (gpointer)player); + + _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "select-stream", G_CALLBACK(__mmplayer_gst_select_stream), (gpointer)player); + +/* FIXME: need to be added for gapless playback + _mmplayer_add_signal_connection(player, G_OBJECT(element), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "about-to-finish", G_CALLBACK(_mmplayer_gst_decode_drained), (gpointer)player); +*/ + + _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "deep-element-added", G_CALLBACK(__mmplayer_gst_deep_element_added), (gpointer)player); + + _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "deep-element-removed", G_CALLBACK(__mmplayer_gst_deep_element_removed), (gpointer)player); + + if (MMPLAYER_URL_HAS_DASH_SUFFIX(player)) + LOGW("[DASH] this is still experimental feature"); + + MMPLAYER_FLEAVE(); + return uridecodebin3; +} + static GstElement * __mmplayer_gst_make_http_src(mmplayer_t *player) { @@ -2744,6 +2969,7 @@ __mmplayer_gst_make_http_src(mmplayer_t *player) MMHandleType attrs = 0; gchar *user_agent, *cookies, **cookie_list; gint http_timeout = DEFAULT_HTTP_TIMEOUT; + user_agent = cookies = NULL; cookie_list = NULL; @@ -3232,9 +3458,11 @@ _mmplayer_gst_pause(mmplayer_t *player, gboolean async) return ret; } - if ((!MMPLAYER_IS_RTSP_STREAMING(player)) && (!player->video_decoded_cb) && - (!player->pipeline->videobin) && (!player->pipeline->audiobin)) - return MM_ERROR_PLAYER_CODEC_NOT_FOUND; + if (!MMPLAYER_USE_URIDECODEBIN3(player)) { + if ((!MMPLAYER_IS_RTSP_STREAMING(player)) && (!player->video_decoded_cb) && + (!player->pipeline->videobin) && (!player->pipeline->audiobin)) + return MM_ERROR_PLAYER_CODEC_NOT_FOUND; + } MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PAUSED); @@ -3730,32 +3958,24 @@ _mmplayer_gst_create_source(mmplayer_t *player) int _mmplayer_gst_build_es_pipeline(mmplayer_t *player) { - MMHandleType attrs = 0; - MMPLAYER_FENTER(); MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED); - /* get profile attribute */ - attrs = MMPLAYER_GET_ATTRS(player); - if (!attrs) { - LOGE("failed to get content attribute"); - return MM_ERROR_PLAYER_INTERNAL; - } - SECURE_LOGD("uri : %s", player->profile.uri); - mm_attrs_set_int_by_name(attrs, "profile_prepare_async", TRUE); - if (mm_attrs_commit_all(attrs)) /* return -1 if error */ - LOGE("failed to commit"); + mm_player_set_attribute((MMHandleType)player, NULL, "profile_prepare_async", TRUE, NULL); - if (player->v_stream_caps && !__mmplayer_gst_create_es_path(player, MM_PLAYER_STREAM_TYPE_VIDEO, player->v_stream_caps)) + if ((player->v_stream_caps) && + !(__mmplayer_gst_create_es_path(player, MM_PLAYER_STREAM_TYPE_VIDEO, player->v_stream_caps))) return MM_ERROR_PLAYER_INTERNAL; - if (player->a_stream_caps && !__mmplayer_gst_create_es_path(player, MM_PLAYER_STREAM_TYPE_AUDIO, player->a_stream_caps)) + if ((player->a_stream_caps) && + !(__mmplayer_gst_create_es_path(player, MM_PLAYER_STREAM_TYPE_AUDIO, player->a_stream_caps))) return MM_ERROR_PLAYER_INTERNAL; - if (player->s_stream_caps && !__mmplayer_gst_create_es_path(player, MM_PLAYER_STREAM_TYPE_TEXT, player->s_stream_caps)) + if ((player->s_stream_caps) && + !(__mmplayer_gst_create_es_path(player, MM_PLAYER_STREAM_TYPE_TEXT, player->s_stream_caps))) return MM_ERROR_PLAYER_INTERNAL; MMPLAYER_FLEAVE(); @@ -3769,19 +3989,13 @@ _mmplayer_gst_build_pipeline(mmplayer_t *player) GstElement *src_elem = NULL; GstElement *autoplug_elem = NULL; GList *element_bucket = NULL; - MMHandleType attrs = 0; main_element_id_e autoplug_elem_id = MMPLAYER_M_NUM; MMPLAYER_FENTER(); MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED); - /* get profile attribute */ - attrs = MMPLAYER_GET_ATTRS(player); - if (!attrs) { - LOGE("failed to get content attribute"); - return MM_ERROR_PLAYER_INTERNAL; - } + mainbin = player->pipeline->mainbin; LOGD("uri type %d", player->profile.uri_type); @@ -3791,6 +4005,10 @@ _mmplayer_gst_build_pipeline(mmplayer_t *player) src_elem = __mmplayer_gst_make_rtsp_src(player); break; case MM_PLAYER_URI_TYPE_URL_HTTP: + if (player->ini.use_uridecodebin3) { /* or MMPLAYER_USE_URIDECODEBIN3(player) */ + LOGD("uridecodebin include src element."); + goto ADD_DECODEBIN; + } src_elem = __mmplayer_gst_make_http_src(player); break; case MM_PLAYER_URI_TYPE_FILE: @@ -3843,8 +4061,6 @@ _mmplayer_gst_build_pipeline(mmplayer_t *player) return MM_ERROR_PLAYER_INTERNAL; } - mainbin = player->pipeline->mainbin; - /* take source element */ LOGD("source elem is created %s", GST_ELEMENT_NAME(src_elem)); @@ -3852,17 +4068,25 @@ _mmplayer_gst_build_pipeline(mmplayer_t *player) mainbin[MMPLAYER_M_SRC].gst = src_elem; element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_SRC]); - /* create next element for auto-plugging */ +ADD_DECODEBIN: /* create next element for auto-plugging */ if (MMPLAYER_IS_HTTP_STREAMING(player)) { - autoplug_elem_id = MMPLAYER_M_TYPEFIND; - autoplug_elem = gst_element_factory_make("typefind", "typefinder"); - if (!autoplug_elem) { - LOGE("failed to create typefind element"); - goto ERROR; + if (!src_elem) { /* make uridecodebin3 which include src element */ + autoplug_elem_id = MMPLAYER_M_AUTOPLUG; + autoplug_elem = __mmplayer_gst_make_uridecodebin(player); + if (!autoplug_elem) { + LOGE("failed to create uridecodebin3 element"); + goto ERROR; + } + } else { + autoplug_elem_id = MMPLAYER_M_TYPEFIND; + autoplug_elem = gst_element_factory_make("typefind", "typefinder"); + if (!autoplug_elem) { + LOGE("failed to create typefind element"); + goto ERROR; + } + _mmplayer_add_signal_connection(player, G_OBJECT(autoplug_elem), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type", + G_CALLBACK(_mmplayer_typefind_have_type), (gpointer)player); } - - _mmplayer_add_signal_connection(player, G_OBJECT(autoplug_elem), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type", - G_CALLBACK(_mmplayer_typefind_have_type), (gpointer)player); } else if (!MMPLAYER_IS_RTSP_STREAMING(player)) { autoplug_elem_id = MMPLAYER_M_AUTOPLUG; autoplug_elem = _mmplayer_gst_make_decodebin(player); @@ -4087,11 +4311,6 @@ _mmplayer_activate_next_source(mmplayer_t *player, GstState target) goto ERROR; } - if (gst_element_set_state(mainbin[MMPLAYER_M_SRC].gst, target) == GST_STATE_CHANGE_FAILURE) { - LOGE("Failed to change state of src element"); - goto ERROR; - } - if (!MMPLAYER_IS_HTTP_STREAMING(player)) { if (gst_element_set_state(mainbin[MMPLAYER_M_AUTOPLUG].gst, target) == GST_STATE_CHANGE_FAILURE) { LOGE("Failed to change state of decodebin"); @@ -4104,6 +4323,11 @@ _mmplayer_activate_next_source(mmplayer_t *player, GstState target) } } + if (gst_element_set_state(mainbin[MMPLAYER_M_SRC].gst, target) == GST_STATE_CHANGE_FAILURE) { + LOGE("Failed to change state of src element"); + goto ERROR; + } + player->gapless.stream_changed = TRUE; player->gapless.running = TRUE; MMPLAYER_FLEAVE(); @@ -4111,8 +4335,7 @@ _mmplayer_activate_next_source(mmplayer_t *player, GstState target) ERROR: if (player) { - MMPLAYER_PLAYBACK_UNLOCK(player); - + _mmplayer_set_reconfigure_state(player, FALSE); if (!player->msg_posted) { MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param); player->msg_posted = TRUE;