========================================================================================== */
/*---------------------------------------------------------------------------
-| GLOBAL CONSTANT DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| IMPORTED VARIABLE DECLARATIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| IMPORTED FUNCTION DECLARATIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL #defines: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
| LOCAL CONSTANT DEFINITIONS: |
---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL DATA TYPE DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| GLOBAL VARIABLE DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL VARIABLE DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL FUNCTION PROTOTYPES: |
----------------------------------------------------------------------------*/
+#define MMPLAYER_TAG_INDENT 3
/*===========================================================================================
| |
| FUNCTION DEFINITIONS |
| |
========================================================================================== */
+#ifdef __DEBUG__
+static void
+print_tag(const GstTagList *list, const gchar *tag, gpointer unused)
+{
+ gint i, count;
+
+ count = gst_tag_list_get_tag_size(list, tag);
+
+ LOGD("count = %d", count);
+
+ for (i = 0; i < count; i++) {
+ gchar *str;
+
+ if (gst_tag_get_type(tag) == G_TYPE_STRING) {
+ if (!gst_tag_list_get_string_index(list, tag, i, &str))
+ g_assert_not_reached();
+ } else {
+ str = g_strdup_value_contents(gst_tag_list_get_value_index(list, tag, i));
+ }
+
+ if (i == 0)
+ g_print(" %15s: %s", gst_tag_get_nick(tag), str);
+ else
+ g_print(" : %s", str);
+
+ g_free(str);
+ }
+}
+#endif
static gboolean
__mmplayer_check_error_posted_from_activated_track(mmplayer_t *player, gchar *src_element_name)
{
/* check whether the error is posted from not-activated track or not */
int msg_src_pos = 0;
- gint active_pad_index = 0;
+ gint active_index = 0;
MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->mainbin[MMPLAYER_M_A_INPUT_SELECTOR].gst, TRUE);
- active_pad_index = player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].active_pad_index;
- LOGD("current active pad index -%d", active_pad_index);
+ active_index = player->track[MM_PLAYER_TRACK_TYPE_AUDIO].active_track_index;
+ LOGD("current active pad index -%d", active_index);
if (src_element_name) {
int idx = 0;
idx++;
}
}
- LOGD("active pad = %d, error src index = %d", active_pad_index, msg_src_pos);
+ LOGD("active pad = %d, error src index = %d", active_index, msg_src_pos);
}
- if (active_pad_index != msg_src_pos) {
+ if (active_index != msg_src_pos) {
LOGD("skip error because error is posted from no activated track");
return FALSE;
}
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;
LOGD("error code=%d, msg=%s, src element=%s, class=%s",
error->code, error->message, src_element_name, klass);
- if (!__mmplayer_check_error_posted_from_activated_track(player, src_element_name))
+ if (MMPLAYER_USE_DECODEBIN(player) &&
+ !__mmplayer_check_error_posted_from_activated_track(player, src_element_name))
return MM_ERROR_NONE;
switch (error->code) {
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);
}
{
/* 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) { \
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)) {\
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;\
} \
} 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) { \
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);\
} \
} 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);\
} \
} 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;
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;
}
}
- if (mm_attrs_commit_all(attrs))
- LOGE("failed to commit.");
-
gst_tag_list_unref(tag_list);
return TRUE;
/* we only handle messages from pipeline */
if ((message->src == (GstObject *)player->pipeline->mainbin[MMPLAYER_M_PIPE].gst) && (!player->gapless.reconfigure))
retval = TRUE;
+ else
+ retval = FALSE;
break;
case GST_MESSAGE_BUFFERING:
{
}
case GST_MESSAGE_STREAMS_SELECTED:
{
- if (!MMPLAYER_USE_URIDECODEBIN3(player))
+ if (MMPLAYER_USE_DECODEBIN(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);
break;
}
default:
+ retval = FALSE;
break;
}
{
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;
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;
}
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();
}
static void
+__mmplayer_print_tag_foreach(const GstTagList *tags, const gchar *tag, gpointer user_data)
+{
+ GValue val = { 0, };
+ gchar *str = NULL;
+ guint indent = GPOINTER_TO_UINT(user_data);
+
+ if (!gst_tag_list_copy_value(&val, tags, tag))
+ return;
+
+ if (G_VALUE_HOLDS_STRING(&val))
+ str = g_value_dup_string(&val);
+ else
+ str = gst_value_serialize(&val);
+
+ LOGD("%*s%s: %s\n", 2 * indent, " ", gst_tag_get_nick(tag), str);
+ g_free(str);
+ g_value_unset(&val);
+}
+
+static void
+__mmplayer_dump_collection(GstStreamCollection * collection)
+{
+ guint i = 0;
+ GstTagList *tags = NULL;
+ GstCaps *caps = NULL;
+
+ for (i = 0; i < gst_stream_collection_get_size(collection); i++) {
+ GstStream *stream = gst_stream_collection_get_stream(collection, i);
+ LOGD ("collection: Stream %u type %s flags 0x%x\n", i,
+ gst_stream_type_get_name(gst_stream_get_stream_type(stream)),
+ gst_stream_get_stream_flags(stream));
+ LOGD (" ID: %s\n", gst_stream_get_stream_id(stream));
+
+ caps = gst_stream_get_caps(stream);
+ if (caps) {
+ gchar *caps_str = gst_caps_to_string(caps);
+ LOGD (" caps: %s\n", caps_str);
+ g_free(caps_str);
+ gst_caps_unref(caps);
+ }
+
+ tags = gst_stream_get_tags(stream);
+ if (tags) {
+ LOGD (" tags:\n");
+ gst_tag_list_foreach(tags, __mmplayer_print_tag_foreach, GUINT_TO_POINTER(MMPLAYER_TAG_INDENT));
+ gst_tag_list_unref(tags);
+ }
+ }
+}
+
+static void
+__mmplayer_stream_notify_cb(GstStreamCollection *collection,
+ GstStream *stream, GParamSpec *pspec, gpointer data)
+{
+ LOGD ("Got stream-notify from stream %s for %s (collection %p)\n",
+ gst_stream_get_stream_id(stream), pspec->name, collection);
+ if (g_str_equal(pspec->name, "caps")) {
+ GstCaps *caps = gst_stream_get_caps(stream);
+ gchar *caps_str = gst_caps_to_string(caps);
+ LOGD (" New caps: %s\n", caps_str);
+ g_free(caps_str);
+ gst_caps_unref(caps);
+ }
+
+ if (g_str_equal (pspec->name, "tags")) {
+ GstTagList *tags = gst_stream_get_tags(stream);
+ if (tags) {
+ LOGD (" tags:\n");
+ gst_tag_list_foreach(tags, __mmplayer_print_tag_foreach, GUINT_TO_POINTER(MMPLAYER_TAG_INDENT));
+ gst_tag_list_unref(tags);
+ }
+ }
+}
+
+static void
__mmplayer_gst_bus_msg_callback(GstMessage *msg, gpointer data)
{
mmplayer_t *player = (mmplayer_t *)(data);
break;
case GST_MESSAGE_ERROR:
+ _mmplayer_set_reconfigure_state(player, FALSE);
__mmplayer_gst_handle_error_message(player, msg);
break;
__mmplayer_gst_handle_async_done_message(player, msg);
break;
case GST_MESSAGE_STREAM_COLLECTION:
+ {
+ GstStreamCollection *collection = NULL;
LOGD("GST_MESSAGE_STREAM_COLLECTION : %s", GST_ELEMENT_NAME(GST_MESSAGE_SRC(msg)));
- break;
+
+ gst_message_parse_stream_collection(msg, &collection);
+ if (collection) {
+ __mmplayer_dump_collection(collection);
+ if (player->collection && player->stream_notify_id) {
+ g_signal_handler_disconnect(player->collection, player->stream_notify_id);
+ player->stream_notify_id = 0;
+ }
+ gst_object_replace((GstObject **)&player->collection, (GstObject *)collection);
+ if (player->collection) {
+ player->stream_notify_id = g_signal_connect(player->collection, "stream-notify",
+ (GCallback)__mmplayer_stream_notify_cb, player);
+ }
+ gst_object_unref(collection);
+ }
+ } break;
case GST_MESSAGE_STREAMS_SELECTED:
+ {
+ GstStreamCollection *collection = NULL;
LOGD("GST_MESSAGE_STREAMS_SELECTED : %s", GST_ELEMENT_NAME(GST_MESSAGE_SRC(msg)));
- break;
- #if 0 /* delete unnecessary logs */
+ gst_message_parse_streams_selected(msg, &collection);
+ if (collection) {
+ guint i = 0, len = 0;
+ len = gst_message_streams_selected_get_size(msg);
+ for (i = 0; i < len; i++) {
+ GstStream *stream = gst_message_streams_selected_get_stream(msg, i);
+ LOGD (" Stream #%d : %s\n", i, gst_stream_get_stream_id(stream));
+ gst_object_unref(stream);
+ }
+ gst_object_unref (collection);
+ }
+ } break;
+
+#ifdef __DEBUG__
case GST_MESSAGE_REQUEST_STATE: LOGD("GST_MESSAGE_REQUEST_STATE"); break;
case GST_MESSAGE_STEP_START: LOGD("GST_MESSAGE_STEP_START"); break;
case GST_MESSAGE_QOS: LOGD("GST_MESSAGE_QOS"); break;
case GST_MESSAGE_SEGMENT_START: LOGD("GST_MESSAGE_SEGMENT_START"); break;
case GST_MESSAGE_SEGMENT_DONE: LOGD("GST_MESSAGE_SEGMENT_DONE"); break;
case GST_MESSAGE_LATENCY: LOGD("GST_MESSAGE_LATENCY"); break;
- #endif
+#endif
default:
break;
case GST_MESSAGE_TAG:
__mmplayer_gst_extract_tag_from_msg(player, message);
- #if 0 // debug
+#ifdef __DEBUG__
{
GstTagList *tags = NULL;
}
break;
}
- #endif
+#endif
break;
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.
GST_BUFFER_OFFSET(buffer) = (guint64)buf->offset;
GST_BUFFER_OFFSET_END(buffer) = (guint64)(buf->offset + len);
- //LOGD("feed buffer %p, offset %u-%u length %u", buffer, buf->offset, (buf->offset+len), len);
+#ifdef __DEBUG__
+ LOGD("feed buffer %p, offset %u-%u length %u", buffer, buf->offset, (buf->offset+len), len);
+#endif
g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret);
buf->offset += len;
_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);
dec_caps = gst_pad_query_caps(srcpad, NULL);
if (dec_caps) {
- //LOGD("got pad %s:%s , dec_caps %" GST_PTR_FORMAT, GST_DEBUG_PAD_NAME(srcpad), dec_caps);
+#ifdef __DEBUG__
+ LOGD("got pad %s:%s , dec_caps %" GST_PTR_FORMAT, GST_DEBUG_PAD_NAME(srcpad), dec_caps);
+#endif
g_object_set(G_OBJECT(decodebin), "sink-caps", dec_caps, NULL);
gst_caps_unref(dec_caps);
}
return element;
}
-void __mmplayer_http_src_setup(GstElement *element, GstElement *source, gpointer data)
+void __mmplayer_http_src_setup(GstElement *source, gpointer data)
{
#define HTTP_SOURCE_BLOCK_SIZE (64 * 1024)
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);
return;
}
-gint __mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * collection,
+static void
+__mmplayer_gst_found_source(GObject *object, GObject *orig, GParamSpec *pspec, gpointer data)
+{
+ mmplayer_t *player = (mmplayer_t *)data;
+ GstElement *source = NULL;
+
+ MMPLAYER_FENTER();
+ LOGD("%s >> %s", GST_ELEMENT_NAME(object), pspec->name);
+
+ g_object_get(orig, pspec->name, &source, NULL);
+
+ player->pipeline->mainbin[MMPLAYER_M_SRC].id = MMPLAYER_M_SRC;
+ player->pipeline->mainbin[MMPLAYER_M_SRC].gst = source;
+
+ if (MMPLAYER_IS_HTTP_STREAMING(player)) {
+ __mmplayer_http_src_setup(source, data);
+ } else if (MMPLAYER_IS_RTSP_STREAMING(player)) {
+ gchar *user_agent = NULL;
+
+ /* get attribute */
+ mm_attrs_get_string_by_name(player->attrs, "streaming_user_agent", &user_agent);
+
+ SECURE_LOGD("user_agent : %s", user_agent);
+
+ /* setting property to streaming source */
+ if (user_agent)
+ g_object_set(G_OBJECT(source), "user-agent", user_agent, NULL);
+ } else if (MMPLAYER_IS_SMOOTH_STREAMING(player)) {
+ g_object_set(G_OBJECT(source), "timeout", DEFAULT_HTTP_TIMEOUT, NULL);
+ } else if (player->profile.uri_type == MM_PLAYER_URI_TYPE_MEM) {
+ g_object_set(source, "stream-type", GST_APP_STREAM_TYPE_RANDOM_ACCESS,
+ "size", (gint64)player->profile.input_mem.len, "blocksize", 20480, NULL);
+
+ _mmplayer_add_signal_connection(player, G_OBJECT(source), MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
+ G_CALLBACK(__mmplayer_gst_appsrc_seek_data_mem), (gpointer)&player->profile.input_mem);
+ _mmplayer_add_signal_connection(player, G_OBJECT(source), MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
+ G_CALLBACK(__mmplayer_gst_appsrc_feed_data_mem), (gpointer)&player->profile.input_mem);
+ }
+ MMPLAYER_FLEAVE();
+}
+
+static gint
+__mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * collection,
+ GstStream * stream, gpointer data)
+{
+ gint ret = 0; /* 1: select, 0: skip, -1: depends on decodebin */
+ GstStreamType stype = gst_stream_get_stream_type(stream);
+ mmplayer_t *player = (mmplayer_t *)data;
+ mmplayer_track_type_e type = MM_PLAYER_TRACK_TYPE_MAX;
+ GstCaps *caps = gst_stream_get_caps(stream);
+ gchar *caps_str = NULL;
+
+ LOGD("Stream type %s flags 0x%x",
+ gst_stream_type_get_name(stype),
+ gst_stream_get_stream_flags(stream));
+ LOGD(" ID: %s", gst_stream_get_stream_id(stream));
+
+ if (caps) {
+ caps_str = gst_caps_to_string(caps);
+ LOGD(" caps: %s", caps_str);
+ }
+
+ switch (stype) {
+ case GST_STREAM_TYPE_AUDIO:
+ {
+ GstStructure *caps_structure = NULL;
+ gint samplerate = 0;
+ gint channels = 0;
+
+ type = MM_PLAYER_TRACK_TYPE_AUDIO;
+
+ if (caps) {
+ caps_structure = gst_caps_get_structure(caps, 0);
+ gst_structure_get_int(caps_structure, "rate", &samplerate);
+ gst_structure_get_int(caps_structure, "channels", &channels);
+
+ if (channels > 0 && samplerate == 0) {
+ LOGW("Skip corrupted audio stream");
+ goto EXIT;
+ }
+
+ if (g_strrstr(caps_str, "mobile-xmf"))
+ mm_player_set_attribute((MMHandleType)player, NULL,
+ "content_audio_codec", "mobile-xmf", strlen("mobile-xmf"), NULL);
+ }
+ break;
+ }
+ case GST_STREAM_TYPE_VIDEO:
+ {
+ GstStructure *caps_structure = NULL;
+ gint stype = 0;
+ gint width = 0;
+
+ type = MM_PLAYER_TRACK_TYPE_VIDEO;
+
+ /* do not support multi track video */
+ if (player->track[MM_PLAYER_TRACK_TYPE_VIDEO].total_track_num >= 1)
+ goto EXIT;
+
+ mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &stype);
+
+ /* don't make video because of not required */
+ if ((stype == MM_DISPLAY_SURFACE_NULL) &&
+ (!player->set_mode.video_export)) {
+ LOGD("no need video decoding, skip video stream");
+ goto EXIT;
+ }
+
+ if (caps) {
+ caps_structure = gst_caps_get_structure(caps, 0);
+ gst_structure_get_int(caps_structure, "width", &width);
+
+ if (width != 0) {
+ if (player->v_stream_caps) {
+ gst_caps_unref(player->v_stream_caps);
+ player->v_stream_caps = NULL;
+ }
+
+ player->v_stream_caps = gst_caps_copy(caps);
+ MMPLAYER_LOG_GST_CAPS_TYPE(player->v_stream_caps);
+ }
+ }
+ break;
+ }
+ case GST_STREAM_TYPE_TEXT:
+ type = MM_PLAYER_TRACK_TYPE_TEXT;
+ break;
+ default:
+ LOGW("Skip not supported stream type");
+ goto EXIT;
+ }
+
+ _mmplayer_track_update_stream(player, type, stream);
+
+ if (player->track[type].active_track_index == (player->track[type].total_track_num - 1)) {
+ LOGD("select this stream, active idx : %d", player->track[type].active_track_index);
+ if (type == MM_PLAYER_TRACK_TYPE_AUDIO)
+ _mmplayer_set_audio_attrs(player, caps);
+ ret = 1;
+ }
+
+EXIT:
+ g_free(caps_str);
+ if (caps)
+ gst_caps_unref(caps);
+
+ LOGD("ret %d", ret);
+ return ret;
+}
+
+static gboolean
+__mmplayer_gst_decode_request_resource(GstElement * uridecodebin, GstStreamCollection * collection,
GstStream * stream, gpointer data)
{
- GstStreamType stype = gst_stream_get_stream_type (stream);
+ mmplayer_t *player = (mmplayer_t *)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);
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
+
+ LOGD("stream type %s", gst_stream_type_get_name(stype));
+
+ /* public does not support audio hw decoder at the moment */
- return 1;
+ if (player->hw_resource[MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER] != NULL) {
+ LOGW("video decoder resource is already acquired, skip it.");
+ return TRUE;
+ }
+
+ if (_mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
+ LOGE("failed to acquire video decoder resource");
+ return FALSE;
+ }
+ player->interrupted_by_resource = FALSE;
+ MMPLAYER_FLEAVE();
+ return TRUE;
}
-void
+static 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 (!player->pipeline->mainbin[MMPLAYER_M_TYPEFIND].gst && g_strrstr(factory_name, "typefind")) {
- player->pipeline->mainbin[MMPLAYER_M_TYPEFIND].id = MMPLAYER_M_TYPEFIND;
- player->pipeline->mainbin[MMPLAYER_M_TYPEFIND].gst = element;
+ if (!mainbin[MMPLAYER_M_TYPEFIND].gst && g_strrstr(factory_name, "typefind")) { // FIXME : not required for local playback+
+ 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 (g_strrstr(factory_name, "parsebin")) {
- player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG_PARSEBIN].id = MMPLAYER_M_AUTOPLUG_PARSEBIN;
- player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG_PARSEBIN].gst = element;
+ LOGD("typefind reference is added");
+ return;
+ }
+
+ if ((MMPLAYER_IS_STREAMING(player)) && (!MMPLAYER_IS_RTSP_STREAMING(player))) {
+ /* update queue2 setting */
+ if (g_strrstr(factory_name, "queue2") && (!mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst)) {
+ 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 */
+ return;
+ }
+
+ /* update mq setting */
+ if (g_strrstr(factory_name, "parsebin") && (!mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst)) {
+ GstIterator *iter = NULL;
+ GValue item = {0, };
+ GstElement *ch_element = NULL;
+ GstElementFactory *ch_factory = 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);
+ LOGD("children factory %s", GST_OBJECT_NAME(ch_factory));
+ if (g_strrstr(GST_OBJECT_NAME(ch_factory), "multiqueue")) {
+ LOGD("get 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;
+
+ /* in case of multiqueue, max bytes size is defined with fixed value in mm_player_streaming.h */
+ _mm_player_streaming_set_multiqueue(player->streamer, ch_element);
+ g_value_reset(&item);
+ break;
+ }
+ g_value_reset(&item);
+ }
+ gst_iterator_free(iter);
+ }
+ }
+ }
+
+ if (g_strrstr(factory_name, "parsebin")) {
+ int video_codec_type = 0;
+ int audio_codec_type = 0;
+
+ g_object_set(G_OBJECT(child), "message-forward", TRUE, NULL);
+ g_object_set(G_OBJECT(element), "message-forward", TRUE, NULL);
+
+ mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_VIDEO_CODEC_TYPE, &video_codec_type);
+ mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_AUDIO_CODEC_TYPE, &audio_codec_type);
+
+ /* CAUTION: if there is hw decoder, the rank value has to be higher than sw decoder
+ and codec default type in ini has to be hw.
+ */
+ if (video_codec_type == MM_PLAYER_CODEC_TYPE_SW)
+ g_object_set(G_OBJECT(child), "force-sw-decoder-for-video", TRUE, NULL);
+ if (audio_codec_type == MM_PLAYER_CODEC_TYPE_SW)
+ g_object_set(G_OBJECT(child), "force-sw-decoder-for-audio", TRUE, NULL);
+
+ 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-select", G_CALLBACK(_mmplayer_gst_decode_autoplug_select), (gpointer)player);
+
+ _mmplayer_add_signal_connection(player, G_OBJECT(child),
+ MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "request-resource", G_CALLBACK(__mmplayer_gst_decode_request_resource), (gpointer)player);
+
} else {
_mmplayer_gst_element_added((GstElement *)child, element, data);
}
-
return;
}
__mmplayer_gst_make_uridecodebin(mmplayer_t *player)
{
GstElement *uridecodebin3 = NULL;
- GstElement *decodebin3 = NULL, *multiqueue = NULL;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL);
/* get attribute */
SECURE_LOGD("uri : %s", player->profile.uri);
- decodebin3 = gst_bin_get_by_name((GstBin *)uridecodebin3, "decodebin3-0");
-
- if (decodebin3) {
- g_object_set(G_OBJECT(decodebin3), "message-forward", TRUE, NULL);
- multiqueue = gst_bin_get_by_name((GstBin *)decodebin3, "multiqueue0");
- }
-
- if (multiqueue) {
- player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].id = MMPLAYER_M_DEMUXED_S_BUFFER;
- player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst = multiqueue;
-
- /* in case of multiqueue, max bytes size is defined with fixed value in mm_player_streaming.h */
- _mm_player_streaming_set_multiqueue(player->streamer, multiqueue);
- }
-
/* setting property to streaming source */
- g_object_set(G_OBJECT(uridecodebin3), "uri", player->profile.uri, "message-forward", TRUE, NULL);
+ g_object_set(G_OBJECT(uridecodebin3), "uri", player->profile.uri,
+ "message-forward", TRUE,
+ "buffer-size", DEFAULT_BUFFER_SIZE_BYTES, NULL);
_mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3),
- MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "source-setup", G_CALLBACK(__mmplayer_http_src_setup), (gpointer)player);
+ MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "deep-notify::source", G_CALLBACK(__mmplayer_gst_found_source), (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);
static GstElement *
__mmplayer_gst_make_http_src(mmplayer_t *player)
{
+#define MAX_RETRY_COUNT 10
GstElement *element = NULL;
MMHandleType attrs = 0;
gchar *user_agent, *cookies, **cookie_list;
gint http_timeout = DEFAULT_HTTP_TIMEOUT;
+
user_agent = cookies = NULL;
cookie_list = NULL;
/* setting property to streaming source */
g_object_set(G_OBJECT(element), "location", player->profile.uri,
- "timeout", http_timeout, "blocksize", (unsigned long)(64 * 1024), NULL);
+ "timeout", http_timeout, "blocksize", (unsigned long)(64 * 1024),
+ "retries", MAX_RETRY_COUNT, NULL);
/* parsing cookies */
if ((cookie_list = _mmplayer_get_cookie_list((const char *)cookies))) {
g_return_val_if_fail(player, FALSE);
g_return_val_if_fail(msg && GST_IS_MESSAGE(msg), FALSE);
-
gst_message_ref(msg);
g_mutex_lock(&player->bus_msg_q_lock);
{
mmplayer_t *player = (mmplayer_t *)(data);
GstMessage *msg = NULL;
- GstBus *bus = NULL;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player &&
player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
NULL);
- bus = gst_pipeline_get_bus(GST_PIPELINE(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
- if (!bus) {
- LOGE("cannot get BUS from the pipeline");
- return NULL;
- }
-
MMPLAYER_BUS_MSG_THREAD_LOCK(player);
LOGD("[handle: %p] gst bus msg thread will be started.", player);
}
MMPLAYER_BUS_MSG_THREAD_UNLOCK(player);
- gst_object_unref(GST_OBJECT(bus));
-
MMPLAYER_FLEAVE();
+
return NULL;
}
return ret;
}
- if (!MMPLAYER_USE_URIDECODEBIN3(player)) {
+ if (MMPLAYER_USE_DECODEBIN(player)) {
if ((!MMPLAYER_IS_RTSP_STREAMING(player)) && (!player->video_decoded_cb) &&
(!player->pipeline->videobin) && (!player->pipeline->audiobin))
return MM_ERROR_PLAYER_CODEC_NOT_FOUND;
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();
}
int
-_mmplayer_gst_build_pipeline(mmplayer_t *player)
+_mmplayer_gst_build_pipeline_with_src(mmplayer_t *player)
{
mmplayer_gst_element_t *mainbin = NULL;
- 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 &&
mainbin = player->pipeline->mainbin;
- /* get profile attribute */
- attrs = MMPLAYER_GET_ATTRS(player);
- if (!attrs) {
- LOGE("failed to get content attribute");
+ LOGD("uri type %d", player->profile.uri_type);
+
+ if ((player->profile.uri_type == MM_PLAYER_URI_TYPE_FILE) &&
+ (!_mmplayer_get_storage_info(player->profile.uri, &player->storage_info[MMPLAYER_PATH_VOD]))) {
return MM_ERROR_PLAYER_INTERNAL;
}
+ if (player->profile.uri_type == MM_PLAYER_URI_TYPE_MEM) {
+ g_strlcpy(player->profile.uri, "appsrc://", MM_MAX_URL_LEN);
+ }
+
+ autoplug_elem = __mmplayer_gst_make_uridecodebin(player);
+ if (!autoplug_elem) {
+ LOGE("failed to create uridecodebin3 element");
+ goto ERROR;
+ }
+
+ LOGD("autoplug elem is created %s", GST_ELEMENT_NAME(autoplug_elem));
+ mainbin[MMPLAYER_M_AUTOPLUG].id = MMPLAYER_M_AUTOPLUG;
+ mainbin[MMPLAYER_M_AUTOPLUG].gst = autoplug_elem;
+
+ if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), autoplug_elem)) {
+ LOGE("failed to add uridecodebin to pipeline");
+ goto ERROR;
+ }
+
+ /* FIXME: required ?*/
+ /* create fakesink element for keeping the pipeline state PAUSED. if needed */
+ mainbin[MMPLAYER_M_SRC_FAKESINK].id = MMPLAYER_M_SRC_FAKESINK;
+ mainbin[MMPLAYER_M_SRC_FAKESINK].gst = gst_element_factory_make("fakesink", "state-holder");
+
+ if (!mainbin[MMPLAYER_M_SRC_FAKESINK].gst) {
+ LOGE("failed to create fakesink");
+ goto ERROR;
+ }
+ GST_OBJECT_FLAG_UNSET(mainbin[MMPLAYER_M_SRC_FAKESINK].gst, GST_ELEMENT_FLAG_SINK);
+
+ /* take ownership of fakesink. we are reusing it */
+ gst_object_ref(mainbin[MMPLAYER_M_SRC_FAKESINK].gst);
+
+ if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), mainbin[MMPLAYER_M_SRC_FAKESINK].gst)) {
+ LOGE("failed to add fakesink to bin");
+ gst_object_unref(mainbin[MMPLAYER_M_SRC_FAKESINK].gst);
+ goto ERROR;
+ }
+
+ MMPLAYER_FLEAVE();
+ return MM_ERROR_NONE;
+
+ERROR:
+
+ if (mainbin[MMPLAYER_M_AUTOPLUG].gst)
+ gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_AUTOPLUG].gst));
+
+ if (mainbin[MMPLAYER_M_SRC_FAKESINK].gst)
+ gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_SRC_FAKESINK].gst));
+
+ mainbin[MMPLAYER_M_AUTOPLUG].gst = NULL;
+ mainbin[MMPLAYER_M_SRC_FAKESINK].gst = NULL;
+
+ return MM_ERROR_PLAYER_INTERNAL;
+}
+
+int
+_mmplayer_gst_build_pipeline(mmplayer_t *player)
+{
+ mmplayer_gst_element_t *mainbin = NULL;
+ GstElement *src_elem = NULL;
+ GstElement *autoplug_elem = NULL;
+ GList *element_bucket = NULL;
+ 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);
+
LOGD("uri type %d", player->profile.uri_type);
/* create source element */
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:
return MM_ERROR_PLAYER_INTERNAL;
}
+ mainbin = player->pipeline->mainbin;
+
/* take source element */
LOGD("source elem is created %s", GST_ELEMENT_NAME(src_elem));
mainbin[MMPLAYER_M_SRC].gst = src_elem;
element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_SRC]);
-ADD_DECODEBIN: /* create next element for auto-plugging */
+ /* create next element for auto-plugging */
if (MMPLAYER_IS_HTTP_STREAMING(player)) {
- 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);
+ 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);
} else if (!MMPLAYER_IS_RTSP_STREAMING(player)) {
autoplug_elem_id = MMPLAYER_M_AUTOPLUG;
autoplug_elem = _mmplayer_gst_make_decodebin(player);
goto ERROR;
}
- if (MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_RTSP_STREAMING(player)) {
+ /* FIXME: need to check whether this is required or not. */
+ if (MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_RTSP_STREAMING(player) ||
+ (player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_DEINTERLEAVE)) {
/* create fakesink element for keeping the pipeline state PAUSED. if needed */
mainbin[MMPLAYER_M_SRC_FAKESINK].id = MMPLAYER_M_SRC_FAKESINK;
mainbin[MMPLAYER_M_SRC_FAKESINK].gst = gst_element_factory_make("fakesink", "state-holder");
return MM_ERROR_PLAYER_INTERNAL;
}
- player->bus_watcher = gst_bus_add_watch(bus, (GstBusFunc)__mmplayer_gst_msg_push, player);
+ player->bus_watcher = gst_bus_add_watch_full(bus, G_PRIORITY_DEFAULT,
+ (GstBusFunc)__mmplayer_gst_msg_push, player,
+ (GDestroyNotify)_mmplayer_watcher_removed_notify);
+ if (player->bus_watcher == 0) {
+ LOGE("failed to add bus watch");
+ return MM_ERROR_PLAYER_INTERNAL;
+ }
+
+ g_mutex_init(&player->bus_watcher_mutex);
+ g_cond_init(&player->bus_watcher_cond);
+
player->context.thread_default = g_main_context_get_thread_default();
if (player->context.thread_default == NULL) {
player->context.thread_default = g_main_context_default();
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");
+ if (MMPLAYER_IS_HTTP_STREAMING(player)) {
+ if (gst_element_set_state(mainbin[MMPLAYER_M_TYPEFIND].gst, target) == GST_STATE_CHANGE_FAILURE) { // ????
+ LOGE("Failed to change state of src element");
goto ERROR;
}
} else {
- if (gst_element_set_state(mainbin[MMPLAYER_M_TYPEFIND].gst, target) == GST_STATE_CHANGE_FAILURE) {
- LOGE("Failed to change state of src element");
+ if (gst_element_set_state(mainbin[MMPLAYER_M_AUTOPLUG].gst, target) == GST_STATE_CHANGE_FAILURE) {
+ LOGE("Failed to change state of decodebin");
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;
+ }
+
player->gapless.stream_changed = TRUE;
player->gapless.running = TRUE;
MMPLAYER_FLEAVE();
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;