/*
* libmm-player
*
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright(c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
*
* Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, heechul jeon <heechul.jeon@samsung.co>,
* YoungHwan An <younghwan_.an@samsung.com>, Eunhae Choi <eunhae1.choi@samsung.com>
*
- * Licensed under the Apache License, Version 2.0 (the "License");
+ * Licensed under the Apache License, Version 2.0(the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
#include <dlog.h>
#include "mm_player_es.h"
#include "mm_player_utils.h"
-#include "mm_player_internal.h"
#include <gst/app/gstappsrc.h>
/*---------------------------------------------------------------------------
-| LOCAL VARIABLE DEFINITIONS for internal |
+| LOCAL VARIABLE DEFINITIONS for internal |
---------------------------------------------------------------------------*/
+#define DEFAULT_FRAMERATE_NUM 30
+#define DEFAULT_FRAMERATE_DEN 1
+#define DEFAULT_VIDEO_FRAME_DURATION 33 /* ms */
+#define PLAYER_DATA_PUSH_WAIT_COUNT 10
+#define PLAYER_STATE_CHECK_INTERVAL (100 * 1000)
/*---------------------------------------------------------------------------
-| LOCAL FUNCTION PROTOTYPES: |
+| LOCAL FUNCTION PROTOTYPES: |
---------------------------------------------------------------------------*/
-static int _parse_media_format (MMPlayerVideoStreamInfo * video, MMPlayerAudioStreamInfo * audio, media_format_h format);
-static int _convert_media_format_video_mime_to_str (MMPlayerVideoStreamInfo * video, media_format_mimetype_e mime);
-static int _convert_media_format_audio_mime_to_str (MMPlayerAudioStreamInfo * audio, media_format_mimetype_e mime);
+static gboolean __mm_player_is_codec_data_changed(mmplayer_t *player, media_packet_h packet, mmplayer_stream_type_e streamtype);
/*===========================================================================================
| |
| FUNCTION DEFINITIONS |
-| |
+| |
========================================================================================== */
static int
-_convert_media_format_video_mime_to_str (MMPlayerVideoStreamInfo * video,
- media_format_mimetype_e mime)
+__convert_media_format_video_mime_to_str(mmplayer_video_stream_info_t *video,
+ media_format_mimetype_e mime)
{
- MMPLAYER_RETURN_VAL_IF_FAIL (video, MM_ERROR_INVALID_ARGUMENT);
-
- switch (mime) {
- case MEDIA_FORMAT_MPEG4_SP:
- video->mime = g_strdup ("video/mpeg");
- video->version = 4;
- break;
- case MEDIA_FORMAT_H264_SP:
+ MMPLAYER_RETURN_VAL_IF_FAIL(video, MM_ERROR_INVALID_ARGUMENT);
+
+ switch (mime) {
+ case MEDIA_FORMAT_MPEG4_SP:
+ video->mime = g_strdup("video/mpeg");
+ video->version = 4;
+ break;
+ case MEDIA_FORMAT_H264_SP:
case MEDIA_FORMAT_H264_MP:
case MEDIA_FORMAT_H264_HP:
- video->mime = g_strdup ("video/x-h264");
- break;
- default:
- video->mime = g_strdup ("unknown");
- break;
- }
-
- return MM_ERROR_NONE;
-}
+ video->mime = g_strdup("video/x-h264");
+ break;
+ default:
+ video->mime = g_strdup("unknown");
+ break;
+ }
-static int
-_convert_media_format_audio_mime_to_str (MMPlayerAudioStreamInfo * audio,
- media_format_mimetype_e mime)
-{
- MMPLAYER_RETURN_VAL_IF_FAIL (audio, MM_ERROR_INVALID_ARGUMENT);
-
- switch (mime) {
- case MEDIA_FORMAT_AAC:
- audio->mime = g_strdup ("audio/mpeg");
- audio->version = 2;
- break;
- default:
- audio->mime = g_strdup ("unknown");
- break;
- }
-
- return MM_ERROR_NONE;
+ return MM_ERROR_NONE;
}
static int
-_parse_media_format (MMPlayerVideoStreamInfo * video,
- MMPlayerAudioStreamInfo * audio, media_format_h format)
+__convert_media_format_audio_mime_to_str(mmplayer_audio_stream_info_t *audio,
+ media_format_mimetype_e mime)
{
- if (audio) {
- media_format_mimetype_e mime;
- int channel;
- int samplerate;
- int avg_bps;
-
- if (media_format_get_audio_info (format, &mime, &channel, &samplerate, NULL,
- &avg_bps) != MEDIA_FORMAT_ERROR_NONE) {
- LOGE ("media_format_get_audio_info failed");
- return MM_ERROR_PLAYER_INTERNAL;
- }
-
- _convert_media_format_audio_mime_to_str (audio, mime);
- audio->sample_rate = samplerate;
- audio->channels = channel;
-//video->user_info = ;
- }
-
- if (video) {
- media_format_mimetype_e mime;
- int width;
- int height;
- int avg_bps;
-
- if (media_format_get_video_info (format, &mime, &width, &height, &avg_bps,
- NULL) != MEDIA_FORMAT_ERROR_NONE) {
- LOGE ("media_format_get_video_info failed");
- return MM_ERROR_PLAYER_INTERNAL;
- }
-
- _convert_media_format_video_mime_to_str (video, mime);
- video->width = width;
- video->height = height;
- }
-
- return MM_ERROR_NONE;
-}
+ MMPLAYER_RETURN_VAL_IF_FAIL(audio, MM_ERROR_INVALID_ARGUMENT);
+
+ switch (mime) {
+ case MEDIA_FORMAT_AAC:
+ audio->mime = g_strdup("audio/mpeg");
+ audio->version = 2;
+ break;
+ default:
+ audio->mime = g_strdup("unknown");
+ break;
+ }
-static gboolean
-_mmplayer_update_video_info(MMHandleType hplayer, media_format_h fmt)
-{
- mm_player_t *player = (mm_player_t *) hplayer;
- gboolean ret = FALSE;
- GstStructure *str = NULL;
- media_format_mimetype_e mimetype = 0;
- gint cur_width = 0, width = 0;
- gint cur_height = 0, height = 0;
-
- MMPLAYER_FENTER ();
-
- MMPLAYER_RETURN_VAL_IF_FAIL (player, FALSE);
- MMPLAYER_RETURN_VAL_IF_FAIL (fmt, FALSE);
-
- if (player->v_stream_caps)
- {
- str = gst_caps_get_structure (player->v_stream_caps, 0);
- if ( !gst_structure_get_int (str, "width", &cur_width))
- {
- LOGD ("missing 'width' field in video caps");
- }
-
- if ( !gst_structure_get_int (str, "height", &cur_height))
- {
- LOGD ("missing 'height' field in video caps");
- }
-
- media_format_get_video_info(fmt, &mimetype, &width, &height, NULL, NULL);
- if ((cur_width != width) || (cur_height != height))
- {
- LOGW ("resolution is changed %dx%d -> %dx%d",
- cur_width, cur_height, width, height);
- _mmplayer_set_video_info(hplayer, fmt);
- ret = TRUE;
- }
- }
-
- MMPLAYER_FLEAVE ();
- return ret;
+ return MM_ERROR_NONE;
}
-
-int
-_mmplayer_set_media_stream_buffer_status_cb(MMHandleType hplayer,
- MMPlayerStreamType type,
- mm_player_media_stream_buffer_status_callback callback,
- void *user_param)
+static int
+__parse_media_format(mmplayer_video_stream_info_t *video,
+ mmplayer_audio_stream_info_t *audio, media_format_h format)
{
- mm_player_t *player = (mm_player_t *) hplayer;
-
- MMPLAYER_FENTER ();
-
- MMPLAYER_RETURN_VAL_IF_FAIL (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
- return MM_ERROR_INVALID_ARGUMENT;
-
- if (player->media_stream_buffer_status_cb[type])
- {
- if (!callback)
- {
- LOGD ("[type:%d] will be clear.\n", type);
+ if (audio) {
+ media_format_mimetype_e mime;
+ int channel;
+ int samplerate;
+ int avg_bps;
+
+ if (media_format_get_audio_info(format, &mime, &channel, &samplerate, NULL,
+ &avg_bps) != MEDIA_FORMAT_ERROR_NONE) {
+ LOGE("media_format_get_audio_info failed");
+ return MM_ERROR_PLAYER_INTERNAL;
}
- else
- {
- LOGD ("[type:%d] will be overwritten.\n", type);
+ if (mime & MEDIA_FORMAT_AAC) {
+ bool is_adts = false;
+ media_format_get_audio_aac_type (format, &is_adts);
+ if (is_adts)
+ audio->user_info = 1;
+ else
+ audio->user_info = 2;
}
+ /* FIXME : Check other mime type (now support AAC only) */
+ __convert_media_format_audio_mime_to_str(audio, mime);
+ audio->sample_rate = samplerate;
+ audio->channels = channel;
}
- player->media_stream_buffer_status_cb[type] = callback;
- player->buffer_cb_user_param = user_param;
+ if (video) {
+ media_format_mimetype_e mime;
+ int width = 0;
+ int height = 0;
+ int avg_bps = 0;
+ int frame_rate = 0;
+
+ if (media_format_get_video_info(format, &mime, &width, &height, &avg_bps,
+ NULL) != MEDIA_FORMAT_ERROR_NONE) {
+ LOGE("media_format_get_video_info failed");
+ return MM_ERROR_PLAYER_INTERNAL;
+ }
+
+ if (media_format_get_video_frame_rate(format, &frame_rate))
+ LOGW("failed to get video frame rate, will be set 30.");
- LOGD ("player handle %p, type %d, callback %p\n", player, type,
- player->media_stream_buffer_status_cb[type]);
+ LOGD("frame_rate %d", frame_rate);
- MMPLAYER_FLEAVE ();
+ __convert_media_format_video_mime_to_str(video, mime);
+
+ video->width = width;
+ video->height = height;
+ video->framerate_num = (frame_rate > 0) ? frame_rate : DEFAULT_FRAMERATE_NUM;
+ video->framerate_den = DEFAULT_FRAMERATE_DEN;
+ }
return MM_ERROR_NONE;
}
-int
-_mmplayer_set_media_stream_seek_data_cb(MMHandleType hplayer,
- MMPlayerStreamType type,
- mm_player_media_stream_seek_data_callback callback,
- void *user_param)
+static gboolean
+__mmplayer_is_video_info_changed (MMHandleType hplayer, media_format_h fmt)
{
- mm_player_t *player = (mm_player_t *) hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
+ gboolean ret = FALSE;
+ GstStructure *str = NULL;
+ media_format_mimetype_e mimetype = 0;
+ gint cur_width = 0, width = 0;
+ gint cur_height = 0, height = 0;
+
+ MMPLAYER_FENTER();
+
+ MMPLAYER_RETURN_VAL_IF_FAIL(player && player->v_stream_caps, FALSE);
+ MMPLAYER_RETURN_VAL_IF_FAIL(fmt, FALSE);
+
+ if (MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PAUSED &&
+ MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING) {
+ LOGW("skip update video info, state: %s", MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)));
+ return FALSE;
+ }
- MMPLAYER_FENTER ();
+ str = gst_caps_get_structure(player->v_stream_caps, 0);
+ if (!str) {
+ LOGE("failed to get caps info");
+ return FALSE;
+ }
- MMPLAYER_RETURN_VAL_IF_FAIL (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ if (!gst_structure_get_int(str, "width", &cur_width))
+ LOGD("missing 'width' field in video caps");
- if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
- return MM_ERROR_INVALID_ARGUMENT;
+ if (!gst_structure_get_int(str, "height", &cur_height))
+ LOGD("missing 'height' field in video caps");
- if (player->media_stream_seek_data_cb[type])
- {
- if (!callback)
- {
- LOGD ("[type:%d] will be clear.\n", type);
- }
- else
- {
- LOGD ("[type:%d] will be overwritten.\n", type);
- }
+ media_format_get_video_info(fmt, &mimetype, &width, &height, NULL, NULL);
+ if ((cur_width != width) || (cur_height != height)) {
+ LOGW("resolution is changed %dx%d -> %dx%d",
+ cur_width, cur_height, width, height);
+ _mmplayer_set_video_info(hplayer, fmt);
+ ret = TRUE;
+ }
+
+ MMPLAYER_FLEAVE();
+ return ret;
+}
+
+static gboolean
+__mmplayer_is_audio_info_changed (MMHandleType hplayer, media_format_h fmt)
+{
+ mmplayer_t *player = (mmplayer_t *)hplayer;
+ gboolean ret = FALSE;
+ GstStructure *str = NULL;
+ media_format_mimetype_e mimetype = 0;
+ gint cur_samplerate = 0, samplerate = 0;
+ gint cur_channel = 0, channel = 0;
+
+ MMPLAYER_FENTER();
+
+ MMPLAYER_RETURN_VAL_IF_FAIL(player && player->a_stream_caps, FALSE);
+ MMPLAYER_RETURN_VAL_IF_FAIL(fmt, FALSE);
+
+ if (MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PAUSED &&
+ MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING) {
+ LOGW("skip update audio info, state: %s", MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)));
+ return FALSE;
}
- player->media_stream_seek_data_cb[type] = callback;
- player->buffer_cb_user_param = user_param;
+ str = gst_caps_get_structure(player->a_stream_caps, 0);
+ if (!str) {
+ LOGE("failed to get caps info");
+ return FALSE;
+ }
- LOGD ("player handle %p, type %d, callback %p\n", player, type,
- player->media_stream_seek_data_cb[type]);
+ if (!gst_structure_get_int(str, "channels", &cur_channel))
+ LOGD("missing 'channel' field in audio caps");
- MMPLAYER_FLEAVE ();
+ if (!gst_structure_get_int(str, "rate", &cur_samplerate))
+ LOGD("missing 'rate' field in audio caps");
- return MM_ERROR_NONE;
+ media_format_get_audio_info(fmt, &mimetype, &channel, &samplerate, NULL, NULL);
+ if ((cur_channel != channel) || (cur_samplerate != samplerate)) {
+ LOGW("audio info change channel(%d), samplerate(%d) -> %d, %d",
+ cur_channel, cur_samplerate, channel, samplerate);
+ _mmplayer_set_audio_info(hplayer, fmt);
+ ret = TRUE;
+ }
+
+ MMPLAYER_FLEAVE();
+ return ret;
}
-GstElement*
-__mmplayer_get_source_element (mm_player_t *player, MMPlayerStreamType type)
+static GstElement *
+__mmplayer_get_source_element(mmplayer_t *player, mmplayer_stream_type_e type)
{
- enum MainElementID elemId = MMPLAYER_M_NUM;
+ main_element_id_e elemId = MMPLAYER_M_NUM;
if (player && player->pipeline && player->pipeline->mainbin) {
-
/* get elem according to the stream type */
if (type == MM_PLAYER_STREAM_TYPE_AUDIO) {
- if (player->pipeline->mainbin[MMPLAYER_M_2ND_SRC].gst) {
+ if (player->pipeline->mainbin[MMPLAYER_M_2ND_SRC].gst)
elemId = MMPLAYER_M_2ND_SRC;
- } else if (g_strrstr (GST_ELEMENT_NAME (player->pipeline->mainbin[MMPLAYER_M_SRC].gst), "audio_appsrc")) {
+ else if (g_strrstr(GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_SRC].gst), "audio_appsrc"))
elemId = MMPLAYER_M_SRC;
- }
- }
- else if (type == MM_PLAYER_STREAM_TYPE_VIDEO) {
+ } else if (type == MM_PLAYER_STREAM_TYPE_VIDEO) {
elemId = MMPLAYER_M_SRC;
- }
- else if (type == MM_PLAYER_STREAM_TYPE_TEXT) {
+ } else if (type == MM_PLAYER_STREAM_TYPE_TEXT) {
elemId = MMPLAYER_M_SUBSRC;
}
}
int
-_mmplayer_set_media_stream_max_size(MMHandleType hplayer, MMPlayerStreamType type, guint64 max_size)
+_mmplayer_set_media_stream_max_size(MMHandleType hplayer, mmplayer_stream_type_e type, guint64 max_size)
{
- mm_player_t *player = (mm_player_t *) hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
GstElement *element = NULL;
- MMPLAYER_FENTER ();
- MMPLAYER_RETURN_VAL_IF_FAIL (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
if ((type < MM_PLAYER_STREAM_TYPE_AUDIO) ||
(type > MM_PLAYER_STREAM_TYPE_TEXT) ||
(max_size == 0)) {
- LOGE ("Invalid param type:%d, max_size:%d", type, max_size);
+ LOGE("Invalid param type:%d, max_size:%"G_GUINT64_FORMAT, type, max_size);
return MM_ERROR_INVALID_ARGUMENT;
}
- LOGD ("type %d, max_size %llu\n", type, max_size);
+ LOGD("type:%s, max_size %"G_GUINT64_FORMAT, MMPLAYER_STREAM_TYPE_GET_NAME(type), max_size);
if ((element = __mmplayer_get_source_element(player, type))) {
- LOGD ("update max_size of %s\n", GST_ELEMENT_NAME(element));
+ LOGD("update max_size of %s", GST_ELEMENT_NAME(element));
g_object_set(G_OBJECT(element), "max-bytes", max_size, NULL);
}
player->media_stream_buffer_max_size[type] = max_size;
- MMPLAYER_FLEAVE ();
+ MMPLAYER_FLEAVE();
return MM_ERROR_NONE;
}
int
-_mmplayer_get_media_stream_max_size(MMHandleType hplayer, MMPlayerStreamType type, guint64 *max_size)
+_mmplayer_get_media_stream_max_size(MMHandleType hplayer, mmplayer_stream_type_e type, guint64 *max_size)
{
- mm_player_t *player = (mm_player_t *) hplayer;
-
- MMPLAYER_FENTER ();
+ mmplayer_t *player = (mmplayer_t *)hplayer;
- MMPLAYER_RETURN_VAL_IF_FAIL (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
- MMPLAYER_RETURN_VAL_IF_FAIL (max_size, MM_ERROR_INVALID_ARGUMENT);
+ MMPLAYER_FENTER();
- if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
- return MM_ERROR_INVALID_ARGUMENT;
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(max_size, MM_ERROR_INVALID_ARGUMENT);
*max_size = player->media_stream_buffer_max_size[type];
- MMPLAYER_FLEAVE ();
+ MMPLAYER_FLEAVE();
return MM_ERROR_NONE;
}
int
-_mmplayer_set_media_stream_min_percent(MMHandleType hplayer, MMPlayerStreamType type, guint min_percent)
+_mmplayer_set_media_stream_min_percent(MMHandleType hplayer, mmplayer_stream_type_e type, guint min_percent)
{
- mm_player_t *player = (mm_player_t *) hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
GstElement *element = NULL;
- MMPLAYER_FENTER ();
+ MMPLAYER_FENTER();
- MMPLAYER_RETURN_VAL_IF_FAIL (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
if ((type < MM_PLAYER_STREAM_TYPE_AUDIO) || (type > MM_PLAYER_STREAM_TYPE_TEXT)) {
- LOGE ("Invalid param type:%d", type);
+ LOGE("Invalid param type:%d", type);
return MM_ERROR_INVALID_ARGUMENT;
}
- LOGD ("type %d, min_per %u\n", type, min_percent);
+ LOGD("type:%s, min_per %u", MMPLAYER_STREAM_TYPE_GET_NAME(type), min_percent);
if ((element = __mmplayer_get_source_element(player, type))) {
- LOGD ("update min_per of %s\n", GST_ELEMENT_NAME(element));
+ LOGD("update min_per of %s", GST_ELEMENT_NAME(element));
g_object_set(G_OBJECT(element), "min-percent", min_percent, NULL);
}
player->media_stream_buffer_min_percent[type] = min_percent;
- MMPLAYER_FLEAVE ();
+ MMPLAYER_FLEAVE();
return MM_ERROR_NONE;
}
int
-_mmplayer_get_media_stream_min_percent(MMHandleType hplayer, MMPlayerStreamType type, guint *min_percent)
+_mmplayer_get_media_stream_min_percent(MMHandleType hplayer, mmplayer_stream_type_e type, guint *min_percent)
{
- mm_player_t *player = (mm_player_t *) hplayer;
-
- MMPLAYER_FENTER ();
+ mmplayer_t *player = (mmplayer_t *)hplayer;
- MMPLAYER_RETURN_VAL_IF_FAIL (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
- MMPLAYER_RETURN_VAL_IF_FAIL (min_percent, MM_ERROR_INVALID_ARGUMENT);
+ MMPLAYER_FENTER();
- if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
- return MM_ERROR_INVALID_ARGUMENT;
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(min_percent, MM_ERROR_INVALID_ARGUMENT);
*min_percent = player->media_stream_buffer_min_percent[type];
- MMPLAYER_FLEAVE ();
+ MMPLAYER_FLEAVE();
return MM_ERROR_NONE;
}
static int
-__mmplayer_check_buffer_level(mm_player_t *player, GstElement* element, MMPlayerStreamType type)
+__mmplayer_check_buffer_level(mmplayer_t *player, GstElement *element, mmplayer_stream_type_e type)
{
guint64 current_level_bytes = 0;
guint64 max_bytes = 0;
guint current_level_per = 0;
- MMPLAYER_FENTER ();
- MMPLAYER_RETURN_VAL_IF_FAIL ( player && element, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(player && element, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(((type == MM_PLAYER_STREAM_TYPE_AUDIO) || (type == MM_PLAYER_STREAM_TYPE_VIDEO)), MM_ERROR_INVALID_ARGUMENT);
- if (player->media_stream_buffer_max_size[type] > 0) {
+ if (player->media_stream_buffer_max_size[type] > 0)
max_bytes = player->media_stream_buffer_max_size[type];
- } else {
+ else
g_object_get(G_OBJECT(element), "max-bytes", &max_bytes, NULL);
- }
if (max_bytes == 0) {
- LOGW ("buffer max size is zero.");
+ LOGW("buffer max size is zero");
return MM_ERROR_NONE;
}
g_object_get(G_OBJECT(element), "current-level-bytes", ¤t_level_bytes, NULL);
if (max_bytes <= current_level_bytes) {
- LOGE ("no available buffer space. type %d, max %lld, curr %lld", type, max_bytes, current_level_bytes);
+ LOGE("no available buffer space, type: %s, max %"G_GUINT64_FORMAT", curr %"G_GUINT64_FORMAT,
+ MMPLAYER_STREAM_TYPE_GET_NAME(type), max_bytes, current_level_bytes);
return MM_ERROR_PLAYER_BUFFER_SPACE;
}
if (MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING) {
- if (!player->media_stream_buffer_status_cb[type]) {
- return MM_ERROR_NONE;
- }
-
- current_level_per = (guint)(gst_util_guint64_to_gdouble(current_level_bytes)/gst_util_guint64_to_gdouble(max_bytes)*100);
+ current_level_per = (guint)(gst_util_guint64_to_gdouble(current_level_bytes) / gst_util_guint64_to_gdouble(max_bytes) * 100);
- LOGD ("type %d, min_per %u, curr_per %u max %lld cur %lld\n",
- type, player->media_stream_buffer_min_percent[type],
+ LOGD("type: %s, min_per %u, curr_per %u max %"G_GUINT64_FORMAT" cur %"G_GUINT64_FORMAT,
+ MMPLAYER_STREAM_TYPE_GET_NAME(type), player->media_stream_buffer_min_percent[type],
current_level_per,
player->media_stream_buffer_max_size[type],
current_level_bytes);
- if (current_level_per < player->media_stream_buffer_min_percent[type])
- player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param);
+ if (current_level_per < player->media_stream_buffer_min_percent[type]) {
+ MMMessageParamType msg_param = {0,};
+
+ msg_param.union_type = MM_MSG_UNION_BUFFER_STATUS;
+ msg_param.buffer_status.stream_type = type;
+ msg_param.buffer_status.status = MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN;
+ msg_param.buffer_status.bytes = current_level_bytes;
+
+ MMPLAYER_POST_MSG(player, MM_MESSAGE_PUSH_BUFFER_STATUS, &msg_param);
+ }
}
- MMPLAYER_FLEAVE ();
+ MMPLAYER_FLEAVE();
return MM_ERROR_NONE;
}
int
-_mmplayer_submit_packet (MMHandleType hplayer, media_packet_h packet)
+_mmplayer_submit_packet(MMHandleType hplayer, media_packet_h packet)
{
- int ret = MM_ERROR_NONE;
- GstBuffer *_buffer = NULL;
- mm_player_t *player = (mm_player_t *) hplayer;
- guint8 *buf = NULL;
- uint64_t size = 0;
- GstElement* element = NULL;
- MMPlayerStreamType streamtype = MM_PLAYER_STREAM_TYPE_AUDIO;
- media_format_h fmt = NULL;
- bool flag = FALSE;
- bool is_eos = FALSE;
-
- MMPLAYER_RETURN_VAL_IF_FAIL (packet, MM_ERROR_INVALID_ARGUMENT);
- MMPLAYER_RETURN_VAL_IF_FAIL ( player &&
- player->pipeline &&
- player->pipeline->mainbin &&
- player->pipeline->mainbin[MMPLAYER_M_SRC].gst,
- MM_ERROR_PLAYER_INTERNAL );
-
- /* get stream type if audio or video */
- media_packet_is_audio (packet, &flag);
- if (flag) {
- streamtype = MM_PLAYER_STREAM_TYPE_AUDIO;
- } else {
- media_packet_is_video (packet, &flag);
- if (flag)
- streamtype = MM_PLAYER_STREAM_TYPE_VIDEO;
- else
- streamtype = MM_PLAYER_STREAM_TYPE_TEXT;
- }
-
- element = __mmplayer_get_source_element(player, streamtype);
- if (!element) {
- LOGE ("there is no source element of type %d", streamtype);
- ret = MM_ERROR_PLAYER_INTERNAL;
- goto ERROR;
- }
-
- /* check buffer level */
- ret = __mmplayer_check_buffer_level (player, element, streamtype);
- if (ret != MM_ERROR_NONE)
- return ret;
-
- /* get data */
- if (media_packet_get_buffer_data_ptr (packet, (void **) &buf) != MEDIA_PACKET_ERROR_NONE) {
- LOGE("failed to get buffer data ptr");
- ret = MM_ERROR_PLAYER_INTERNAL;
- goto ERROR;
- }
-
- if (media_packet_get_buffer_size (packet, &size) != MEDIA_PACKET_ERROR_NONE) {
- LOGE("failed to get buffer size");
- ret = MM_ERROR_PLAYER_INTERNAL;
- goto ERROR;
- }
-
- if (buf != NULL && size > 0) {
- GstMapInfo buff_info = GST_MAP_INFO_INIT;
- uint64_t pts = 0;
-
- /* get size */
- _buffer = gst_buffer_new_and_alloc (size);
-
- if (!_buffer) {
- LOGE("failed to allocate memory for push buffer\n");
- ret = MM_ERROR_PLAYER_NO_FREE_SPACE;
- goto ERROR;
- }
-
- if (gst_buffer_map (_buffer, &buff_info, GST_MAP_READWRITE)) {
-
- memcpy (buff_info.data, buf, size);
- buff_info.size = size;
-
- gst_buffer_unmap (_buffer, &buff_info);
- }
-
- if (streamtype == MM_PLAYER_STREAM_TYPE_VIDEO) {
- /* get format to check video format */
- media_packet_get_format (packet, &fmt);
- if (fmt) {
- if (_mmplayer_update_video_info(hplayer, fmt)) {
- LOGD("update video caps");
- g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst),
- "caps", player->v_stream_caps, NULL);
- }
- media_format_unref(fmt);
- }
- }
-
- /* get pts */
- if (media_packet_get_pts (packet, &pts) != MEDIA_PACKET_ERROR_NONE) {
- LOGE("failed to get pts info");
- ret = MM_ERROR_PLAYER_INTERNAL;
- goto ERROR;
- }
- GST_BUFFER_PTS (_buffer) = (GstClockTime)pts;
- gst_app_src_push_buffer (GST_APP_SRC (element), _buffer);
- }
-
- /* check eos */
- if (media_packet_is_end_of_stream(packet, &is_eos) != MEDIA_PACKET_ERROR_NONE) {
- LOGE("failed to get eos info");
- ret = MM_ERROR_PLAYER_INTERNAL;
- goto ERROR;
- }
-
- if (is_eos) {
- LOGW ("we got eos of stream type(%d)", streamtype);
- g_signal_emit_by_name (element, "end-of-stream", &ret);
- }
+ int ret = MM_ERROR_NONE;
+ GstBuffer *_buffer = NULL;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
+ guint8 *buf = NULL;
+ uint64_t size = 0;
+ GstElement *element = NULL;
+ mmplayer_stream_type_e streamtype = MM_PLAYER_STREAM_TYPE_AUDIO;
+ media_format_h fmt = NULL;
+ bool flag = false;
+ bool is_eos = false;
+ gboolean need_update_caps = FALSE;
+
+ MMPLAYER_RETURN_VAL_IF_FAIL(packet, MM_ERROR_INVALID_ARGUMENT);
+ MMPLAYER_RETURN_VAL_IF_FAIL(player &&
+ player->pipeline &&
+ player->pipeline->mainbin &&
+ player->pipeline->mainbin[MMPLAYER_M_SRC].gst,
+ MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+ /* get stream type if audio or video */
+ media_packet_is_audio(packet, &flag);
+ if (flag) {
+ streamtype = MM_PLAYER_STREAM_TYPE_AUDIO;
+ } else {
+ media_packet_is_video(packet, &flag);
+ if (flag)
+ streamtype = MM_PLAYER_STREAM_TYPE_VIDEO;
+ else
+ streamtype = MM_PLAYER_STREAM_TYPE_TEXT;
+ }
+
+ element = __mmplayer_get_source_element(player, streamtype);
+ if (!element) {
+ LOGE("there is no source element of type %d", streamtype);
+ ret = MM_ERROR_PLAYER_INTERNAL;
+ goto ERROR;
+ }
+
+ /* check buffer level */
+ ret = __mmplayer_check_buffer_level(player, element, streamtype);
+ if (ret != MM_ERROR_NONE)
+ return ret;
+
+ /* get data */
+ if (media_packet_get_buffer_data_ptr(packet, (void **)&buf) != MEDIA_PACKET_ERROR_NONE) {
+ LOGE("failed to get buffer data ptr");
+ ret = MM_ERROR_PLAYER_INTERNAL;
+ goto ERROR;
+ }
+
+ if (media_packet_get_buffer_size(packet, &size) != MEDIA_PACKET_ERROR_NONE) {
+ LOGE("failed to get buffer size");
+ ret = MM_ERROR_PLAYER_INTERNAL;
+ goto ERROR;
+ }
+
+ if (buf != NULL && size > 0) {
+ GstMapInfo buff_info = GST_MAP_INFO_INIT;
+ uint64_t pts = 0;
+ uint64_t duration = 0;
+ int wait_cnt = 0;
+
+ /* get size */
+ _buffer = gst_buffer_new_and_alloc(size);
+
+ if (!_buffer) {
+ LOGE("failed to allocate memory for push buffer");
+ ret = MM_ERROR_PLAYER_NO_FREE_SPACE;
+ goto ERROR;
+ }
+
+ if (gst_buffer_map(_buffer, &buff_info, GST_MAP_READWRITE)) {
+ memcpy(buff_info.data, buf, size);
+ buff_info.size = size;
+
+ gst_buffer_unmap(_buffer, &buff_info);
+ }
+
+ /* wait till the pipeline is ready to get data, if not some data is missed */
+ while ((GST_STATE(element) < GST_STATE_PAUSED) && (wait_cnt < PLAYER_DATA_PUSH_WAIT_COUNT)) {
+ LOGW("wait to update source state : %d, %d", player->state, GST_STATE(element));
+ usleep(PLAYER_STATE_CHECK_INTERVAL);
+ wait_cnt++;
+ }
+
+ if (wait_cnt == PLAYER_DATA_PUSH_WAIT_COUNT) {
+ LOGE("source is not ready %d", GST_STATE(element));
+ ret = MM_ERROR_PLAYER_INTERNAL;
+ goto ERROR;
+ }
+
+ if (streamtype == MM_PLAYER_STREAM_TYPE_VIDEO) {
+ /* get format to check video format */
+ media_packet_get_format(packet, &fmt);
+ if (fmt) {
+ need_update_caps |= __mmplayer_is_video_info_changed (hplayer, fmt);
+ media_format_unref(fmt);
+ }
+ need_update_caps |= __mm_player_is_codec_data_changed(player, packet, streamtype);
+
+ if (need_update_caps)
+ g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst),
+ "caps", player->v_stream_caps, NULL);
+
+ /* get duration */
+ if (media_packet_get_duration(packet, &duration) != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("failed to get duration info");
+ /* keep push without error handling */
+ }
+
+ if (duration == 0)
+ duration = DEFAULT_VIDEO_FRAME_DURATION * GST_MSECOND;
+
+ GST_BUFFER_DURATION(_buffer) = (GstClockTime)duration;
+ } else if (streamtype == MM_PLAYER_STREAM_TYPE_AUDIO) {
+ media_packet_get_format(packet, &fmt);
+ if (fmt) {
+ need_update_caps |= __mmplayer_is_audio_info_changed (hplayer, fmt);
+ media_format_unref(fmt);
+ }
+ need_update_caps |= __mm_player_is_codec_data_changed(player, packet, streamtype);
+
+ if (need_update_caps) {
+ LOGD("update audio caps");
+ g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst),
+ "caps", player->a_stream_caps, NULL);
+ }
+ }
+
+ /* get pts */
+ if (media_packet_get_pts(packet, &pts) != MEDIA_PACKET_ERROR_NONE) {
+ LOGE("failed to get pts info");
+ ret = MM_ERROR_PLAYER_INTERNAL;
+ goto ERROR;
+ }
+ GST_BUFFER_PTS(_buffer) = (GstClockTime)pts;
+
+ if (MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING) {
+ /* the pushed pts should be lager than current position if it is not in playing state. */
+ LOGD("type:%s, curr pos: %"G_GINT64_FORMAT", pushed pts:%"G_GINT64_FORMAT", size:%"G_GUINT64_FORMAT,
+ MMPLAYER_STREAM_TYPE_GET_NAME(streamtype), player->last_position, (GstClockTime)pts, (guint64)size);
+ }
+
+ gst_app_src_push_buffer(GST_APP_SRC(element), _buffer);
+ } else {
+ LOGW("There is no data to push : buf %p, size %"G_GUINT64_FORMAT, buf, (guint64)size);
+ }
+
+ /* check eos */
+ if (media_packet_is_end_of_stream(packet, &is_eos) != MEDIA_PACKET_ERROR_NONE) {
+ LOGE("failed to get eos info");
+ return MM_ERROR_PLAYER_INTERNAL;
+ }
+
+ if (is_eos) {
+ LOGW("we got eos of stream type(%s)", MMPLAYER_STREAM_TYPE_GET_NAME(streamtype));
+ g_signal_emit_by_name(element, "end-of-stream", &ret);
+ }
+
+ return ret;
ERROR:
- return ret;
+ gst_buffer_unref(_buffer);
+ return ret;
}
-int
-_mmplayer_video_caps_new (MMHandleType hplayer, MMPlayerVideoStreamInfo * video,
- const char *fieldname, ...)
+static int
+__mmplayer_video_caps_new(MMHandleType hplayer, mmplayer_video_stream_info_t *video,
+ const char *fieldname, ...)
{
- int cap_size;
- GstCaps *caps = NULL;
- GstStructure *structure = NULL;
- va_list var_args;
- mm_player_t *player = MM_PLAYER_CAST (hplayer);
-
- MMPLAYER_FENTER ();
- MMPLAYER_RETURN_VAL_IF_FAIL (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
- MMPLAYER_RETURN_VAL_IF_FAIL (video, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- LOGD ("width=%d height=%d framerate num=%d, den=%d",
- video->width, video->height, video->framerate_num, video->framerate_den);
-
- caps = gst_caps_new_simple (video->mime,
- "width", G_TYPE_INT, video->width,
- "height", G_TYPE_INT, video->height,
- "framerate", GST_TYPE_FRACTION, video->framerate_num, video->framerate_den, NULL);
-
- for (cap_size = 0; cap_size < gst_caps_get_size (caps); cap_size++) {
- va_start (var_args, fieldname);
- structure = gst_caps_get_structure (caps, cap_size);
- gst_structure_set_valist (structure, fieldname, var_args);
- va_end (var_args);
- }
-
- if (video->extradata_size) {
- GstBuffer *buf = NULL;
- GstMapInfo buff_info = GST_MAP_INFO_INIT;
-
- buf = gst_buffer_new_and_alloc (video->extradata_size);
-
- if (gst_buffer_map (buf, &buff_info, GST_MAP_READ)) {
- memcpy (buff_info.data, video->codec_extradata, video->extradata_size);
- buff_info.size = video->extradata_size;
- gst_buffer_unmap (buf, &buff_info);
- }
-
- gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
- gst_buffer_unref (buf);
- }
-
- if (player->v_stream_caps)
- {
- LOGW ("caps will be updated ");
-
- 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);
- gst_caps_unref (caps);
-
- MMPLAYER_FLEAVE ();
-
- return MM_ERROR_NONE;
+ int cap_size;
+ GstCaps *caps = NULL;
+ GstStructure *structure = NULL;
+ va_list var_args;
+ mmplayer_t *player = MM_PLAYER_CAST(hplayer);
+
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(video, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+ LOGD("width=%d height=%d framerate num=%d, den=%d",
+ video->width, video->height, video->framerate_num, video->framerate_den);
+
+ caps = gst_caps_new_simple(video->mime,
+ "width", G_TYPE_INT, video->width,
+ "height", G_TYPE_INT, video->height,
+ "framerate", GST_TYPE_FRACTION, video->framerate_num, video->framerate_den, NULL);
+
+ for (cap_size = 0; cap_size < gst_caps_get_size(caps); cap_size++) {
+ va_start(var_args, fieldname);
+ structure = gst_caps_get_structure(caps, cap_size);
+ gst_structure_set_valist(structure, fieldname, var_args);
+ va_end(var_args);
+ }
+
+ if (video->extradata_size) {
+ GstBuffer *buf = NULL;
+ GstMapInfo buff_info = GST_MAP_INFO_INIT;
+
+ buf = gst_buffer_new_and_alloc(video->extradata_size);
+
+ if (gst_buffer_map(buf, &buff_info, GST_MAP_READ)) {
+ memcpy(buff_info.data, video->codec_extradata, video->extradata_size);
+ buff_info.size = video->extradata_size;
+ gst_buffer_unmap(buf, &buff_info);
+ }
+
+ gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
+ gst_buffer_unref(buf);
+ }
+
+ if (player->v_stream_caps) {
+ LOGW("caps will be updated ");
+
+ 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);
+ gst_caps_unref(caps);
+
+ MMPLAYER_FLEAVE();
+
+ return MM_ERROR_NONE;
}
static void
-_mmplayer_set_uri_type(mm_player_t *player)
+__mmplayer_set_uri_type(mmplayer_t *player)
{
- MMPLAYER_FENTER ();
+ MMPLAYER_FENTER();
player->profile.uri_type = MM_PLAYER_URI_TYPE_MS_BUFF;
player->es_player_push_mode = TRUE;
- MMPLAYER_FLEAVE ();
+ MMPLAYER_FLEAVE();
return;
}
int
-_mmplayer_set_video_info (MMHandleType hplayer, media_format_h format)
+_mmplayer_set_video_info(MMHandleType hplayer, media_format_h format)
{
- mm_player_t *player = MM_PLAYER_CAST (hplayer);
- MMPlayerVideoStreamInfo video = { 0, };
- int ret = MM_ERROR_NONE;
-
- MMPLAYER_FENTER ();
-
- MMPLAYER_RETURN_VAL_IF_FAIL (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- _mmplayer_set_uri_type(player);
-
- ret = _parse_media_format (&video, NULL, format);
- if(ret != MM_ERROR_NONE)
- return ret;
-
- if (strstr (video.mime, "video/mpeg")) {
- _mmplayer_video_caps_new (hplayer, &video,
- "mpegversion", G_TYPE_INT, video.version,
- "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
- } else if (strstr (video.mime, "video/x-h264")) {
- //if (info.colordepth)
- {
- // _mmplayer_video_caps_new(hplayer, &info,
- // "colordepth", G_TYPE_INT, info.colordepth, NULL);
- }
- //else
- {
- _mmplayer_video_caps_new (hplayer, &video,
- "stream-format", G_TYPE_STRING, "byte-stream",
- "alignment", G_TYPE_STRING, "au", NULL);
- }
- }
-#if 0
- else if (strstr (info->mime, "video/x-wmv")) {
- _mmplayer_video_caps_new (hplayer, &info,
- "wmvversion", G_TYPE_INT, info.version, NULL);
- } else if (strstr (info.mime, "video/x-pn-realvideo")) {
- _mmplayer_video_caps_new (hplayer, &info,
- "rmversion", G_TYPE_INT, info.version, NULL);
- } else if (strstr (info.mime, "video/x-msmpeg")) {
- _mmplayer_video_caps_new (hplayer, &info,
- "msmpegversion", G_TYPE_INT, info.version, NULL);
- } else if (strstr (info.mime, "video/x-h265")) {
- if (info.colordepth) {
- _mmplayer_video_caps_new (hplayer, &info,
- "colordepth", G_TYPE_INT, info.colordepth, NULL);
- } else {
- _mmplayer_video_caps_new (hplayer, &info, NULL);
- }
- } else {
- _mmplayer_video_caps_new (hplayer, &info, NULL);
- }
-#endif
- g_free ((char *) video.mime);
+ mmplayer_t *player = MM_PLAYER_CAST(hplayer);
+ mmplayer_video_stream_info_t video = { 0, };
+ int ret = MM_ERROR_NONE;
+ gboolean drc = FALSE;
+
+ MMPLAYER_FENTER();
+
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
- MMPLAYER_FLEAVE ();
+ __mmplayer_set_uri_type(player);
- return MM_ERROR_NONE;
+ ret = __parse_media_format(&video, NULL, format);
+ if (ret != MM_ERROR_NONE)
+ return ret;
+
+ mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_DRC_MODE, &drc);
+
+ if (strstr(video.mime, "video/mpeg")) {
+ __mmplayer_video_caps_new(hplayer, &video,
+ "mpegversion", G_TYPE_INT, video.version,
+ "systemstream", G_TYPE_BOOLEAN, FALSE,
+ "adaptive-streaming", G_TYPE_BOOLEAN, drc, NULL);
+ } else if (strstr(video.mime, "video/x-h264")) {
+ __mmplayer_video_caps_new(hplayer, &video,
+ "stream-format", G_TYPE_STRING, "byte-stream",
+ "alignment", G_TYPE_STRING, "au",
+ "adaptive-streaming", G_TYPE_BOOLEAN, drc, NULL);
+ }
+ g_free((char *)video.mime);
+
+ MMPLAYER_FLEAVE();
+
+ return MM_ERROR_NONE;
}
int
-_mmplayer_set_audio_info (MMHandleType hplayer, media_format_h format)
+_mmplayer_set_audio_info(MMHandleType hplayer, media_format_h format)
{
- mm_player_t *player = MM_PLAYER_CAST (hplayer);
- GstCaps *caps = NULL;
- MMPlayerAudioStreamInfo audio = { 0, };
- int ret = MM_ERROR_NONE;
-
- MMPLAYER_FENTER ();
-
- MMPLAYER_RETURN_VAL_IF_FAIL (hplayer, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- _mmplayer_set_uri_type(player);
-
- ret = _parse_media_format (NULL, &audio, format);
- if(ret != MM_ERROR_NONE)
- return ret;
-
- audio.user_info = 0; //test
-
- LOGD ("set audio player[%p] info [%p] version=%d rate=%d channel=%d",
- player, audio, audio.version, audio.sample_rate, audio.channels);
-
- if (strstr (audio.mime, "audio/mpeg")) {
- if (audio.version == 1) { // mp3
- caps = gst_caps_new_simple ("audio/mpeg",
- "channels", G_TYPE_INT, audio.channels,
- "rate", G_TYPE_INT, audio.sample_rate,
- "mpegversion", G_TYPE_INT, audio.version,
- "layer", G_TYPE_INT, audio.user_info, NULL);
- } else { // aac
- gchar *format = NULL;
-
- if (audio.user_info == 0)
- format = g_strdup ("raw");
- else if (audio.user_info == 1)
- format = g_strdup ("adts");
- else if (audio.user_info == 2)
- format = g_strdup ("adif");
-
- caps = gst_caps_new_simple ("audio/mpeg",
- "channels", G_TYPE_INT, audio.channels,
- "rate", G_TYPE_INT, audio.sample_rate,
- "mpegversion", G_TYPE_INT, audio.version,
- "stream-format", G_TYPE_STRING, format, NULL);
-
- g_free (format);
- format = NULL;
- }
- }
+ mmplayer_t *player = MM_PLAYER_CAST(hplayer);
+ GstCaps *caps = NULL;
+ mmplayer_audio_stream_info_t audio = { 0, };
+ int ret = MM_ERROR_NONE;
+
+ MMPLAYER_FENTER();
+
+ MMPLAYER_RETURN_VAL_IF_FAIL(hplayer, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+ __mmplayer_set_uri_type(player);
+
+ ret = __parse_media_format(NULL, &audio, format);
+ if (ret != MM_ERROR_NONE)
+ return ret;
+
+
+ LOGD("set audio player[%p] version=%d rate=%d channel=%d",
+ player, audio.version, audio.sample_rate, audio.channels);
+
+ if (strstr(audio.mime, "audio/mpeg")) {
+ if (audio.version == 2) { // aac
+ gchar *stream_format = NULL;
+
+ if (audio.user_info == 0)
+ stream_format = g_strdup("raw");
+ else if (audio.user_info == 1)
+ stream_format = g_strdup("adts");
+ else if (audio.user_info == 2)
+ stream_format = g_strdup("adif");
+
+ caps = gst_caps_new_simple("audio/mpeg",
+ "channels", G_TYPE_INT, audio.channels,
+ "rate", G_TYPE_INT, audio.sample_rate,
+ "mpegversion", G_TYPE_INT, audio.version,
+ "stream-format", G_TYPE_STRING, stream_format, NULL);
+
+ MMPLAYER_FREEIF(stream_format);
+ stream_format = NULL;
+ } else if (audio.version == 1 ) { // mp3
+ caps = gst_caps_new_simple("audio/mpeg",
+ "channels", G_TYPE_INT, audio.channels,
+ "rate", G_TYPE_INT, audio.sample_rate,
+ "mpegversion", G_TYPE_INT, audio.version,
+ "layer", G_TYPE_INT, audio.user_info, NULL);
+ }
+ }
#if 0
- else if (strstr (audio.mime, "audio/x-raw-int")) {
- caps = gst_caps_new_simple ("audio/x-raw-int",
- "width", G_TYPE_INT, audio.width,
- "depth", G_TYPE_INT, audio.depth,
- "endianness", G_TYPE_INT, audio.endianness,
- "signed", G_TYPE_BOOLEAN, audio.signedness,
- "channels", G_TYPE_INT, audio.channels,
- "rate", G_TYPE_INT, audio.sample_rate, NULL);
- } else {
- caps = gst_caps_new_simple (audio.mime,
- "channels", G_TYPE_INT, audio.channels,
- "rate", G_TYPE_INT, audio.sample_rate, NULL);
- }
+ else if (strstr(audio.mime, "audio/x-raw-int")) {
+ caps = gst_caps_new_simple("audio/x-raw-int",
+ "width", G_TYPE_INT, audio.width,
+ "depth", G_TYPE_INT, audio.depth,
+ "endianness", G_TYPE_INT, audio.endianness,
+ "signed", G_TYPE_BOOLEAN, audio.signedness,
+ "channels", G_TYPE_INT, audio.channels,
+ "rate", G_TYPE_INT, audio.sample_rate, NULL);
+ } else {
+ caps = gst_caps_new_simple(audio.mime,
+ "channels", G_TYPE_INT, audio.channels,
+ "rate", G_TYPE_INT, audio.sample_rate, NULL);
+ }
#endif
- if (audio.extradata_size) {
- GstBuffer *buf = NULL;
- GstMapInfo buff_info = GST_MAP_INFO_INIT;
+ if (audio.extradata_size && audio.codec_extradata) {
+ GstBuffer *buf = NULL;
+ GstMapInfo buff_info = GST_MAP_INFO_INIT;
- buf = gst_buffer_new_and_alloc (audio.extradata_size);
+ buf = gst_buffer_new_and_alloc(audio.extradata_size);
- if (gst_buffer_map (buf, &buff_info, GST_MAP_READ)) {
- memcpy (buff_info.data, audio.codec_extradata, audio.extradata_size);
- gst_buffer_unmap (buf, &buff_info);
- }
+ if (gst_buffer_map(buf, &buff_info, GST_MAP_READ)) {
+ memcpy(buff_info.data, audio.codec_extradata, audio.extradata_size);
+ gst_buffer_unmap(buf, &buff_info);
+ }
- gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
- gst_buffer_unref (buf);
- }
+ gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
+ gst_buffer_unref(buf);
+ g_free((char *)audio.codec_extradata);
+ }
- g_free ((char *) audio.mime);
+ g_free((char *)audio.mime);
- player->a_stream_caps = gst_caps_copy (caps);
- gst_caps_unref (caps);
+ player->a_stream_caps = gst_caps_copy(caps);
+ gst_caps_unref(caps);
- MMPLAYER_FLEAVE ();
+ MMPLAYER_FLEAVE();
- return MM_ERROR_NONE;
+ return MM_ERROR_NONE;
}
int
-_mmplayer_set_subtitle_info (MMHandleType hplayer,
- MMPlayerSubtitleStreamInfo * subtitle)
+_mmplayer_set_subtitle_info(MMHandleType hplayer,
+ mmplayer_subtitle_stream_info_t *subtitle)
{
#if 0 //todo
+ mmplayer_t *player = MM_PLAYER_CAST(hplayer);
+ GstCaps *caps = NULL;
- mm_player_t *player = MM_PLAYER_CAST (hplayer);
- GstCaps *caps = NULL;
-
- MMPLAYER_FENTER ();
+ MMPLAYER_FENTER();
- MMPLAYER_RETURN_VAL_IF_FAIL (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
- MMPLAYER_RETURN_VAL_IF_FAIL (info, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(info, MM_ERROR_PLAYER_NOT_INITIALIZED);
- LOGD ("set subtitle player[%p] info [%p]", player, info);
+ LOGD("set subtitle player[%p] info [%p]", player, info);
- caps = gst_caps_new_simple (info->mime, NULL, NULL); // TO CHECK
- if (NULL == caps)
- return FALSE;
+ caps = gst_caps_new_simple(info->mime, NULL, NULL); // TO CHECK
+ if (NULL == caps)
+ return FALSE;
- if (strstr (info->mime, "application/x-xsub")) {
- gst_caps_set_simple (caps, "codec_tag", G_TYPE_UINT, info->codec_tag, NULL);
- } else if (strstr (info->mime, "application/x-smpte-text")) {
- if (info->context) {
- gst_caps_set_simple (caps, "ttml_priv_data", G_TYPE_POINTER,
- info->context, NULL);
- }
- }
+ if (strstr(info->mime, "application/x-xsub")) {
+ gst_caps_set_simple(caps, "codec_tag", G_TYPE_UINT, info->codec_tag, NULL);
+ } else if (strstr(info->mime, "application/x-smpte-text")) {
+ if (info->context) {
+ gst_caps_set_simple(caps, "ttml_priv_data", G_TYPE_POINTER,
+ info->context, NULL);
+ }
+ }
- player->s_stream_caps = gst_caps_copy (caps);
+ player->s_stream_caps = gst_caps_copy(caps);
- gst_caps_unref (caps);
+ gst_caps_unref(caps);
#endif
- MMPLAYER_FLEAVE ();
+ MMPLAYER_FLEAVE();
+
+ return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_set_media_stream_dynamic_resolution(MMHandleType hplayer, bool drc)
+{
+ mmplayer_t *player = MM_PLAYER_CAST(hplayer);
+ int ret = MM_ERROR_NONE;
+
+ MMPLAYER_FENTER();
+
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+ mm_player_set_attribute(hplayer, NULL, MM_PLAYER_DRC_MODE, (int)drc, NULL);
+ if (player->v_stream_caps) {
+ gst_caps_set_simple(player->v_stream_caps,
+ "adaptive-streaming", G_TYPE_BOOLEAN, drc, NULL);
+ MMPLAYER_LOG_GST_CAPS_TYPE(player->v_stream_caps);
+ }
+
+ MMPLAYER_FLEAVE();
+
+ return ret;
+}
+
+static gboolean
+__mm_player_is_codec_data_changed(mmplayer_t *player, media_packet_h packet,
+ mmplayer_stream_type_e streamtype)
+{
+ GstCaps *cur_caps = NULL;
+ GstCaps *new_caps = NULL;
+ GstStructure *str = NULL;
+ const GValue *value = NULL;
+ GstBuffer *buffer = NULL;
+ GstMapInfo codec_data_map = GST_MAP_INFO_INIT;
+ GstBuffer *new_buffer = NULL;
+ char *codec_data = NULL;
+ unsigned int codec_data_size = 0;
+
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
+ MMPLAYER_RETURN_VAL_IF_FAIL(packet, FALSE);
+
+ if (media_packet_get_codec_data(packet, (void **)&codec_data, &codec_data_size)
+ != MEDIA_PACKET_ERROR_NONE)
+ return FALSE;
+
+ if (codec_data_size == 0) {
+ LOGW("codec_data_size is zero");
+ return FALSE;
+ }
+
+ if (streamtype == MM_PLAYER_STREAM_TYPE_AUDIO) {
+ cur_caps = player->a_stream_caps;
+ } else if (streamtype == MM_PLAYER_STREAM_TYPE_VIDEO) {
+ cur_caps = player->v_stream_caps;
+ } else {
+ LOGW("streamtype is not audio or video");
+ return FALSE;
+ }
+
+ if (!cur_caps) {
+ LOGW("Current caps is NULL");
+ return FALSE;
+ }
+
+ str = gst_caps_get_structure(cur_caps, 0);
+ if (!str) {
+ LOGW("Failed to get caps info");
+ return FALSE;
+ }
+
+ /* Check if the codec data in the saved caps have been changed */
+ value = gst_structure_get_value(str, "codec_data");
+ if (value) {
+ int i = 0;
+ buffer = gst_value_get_buffer(value);
+ if (!gst_buffer_map(buffer, &codec_data_map, GST_MAP_READ)) {
+ LOGW("codec data buffer map failed");
+ return FALSE;
+ }
+ if (codec_data_map.size == codec_data_size) {
+ for (i = 0; i <= codec_data_map.size; i++) {
+ if (codec_data_map.data[i] != codec_data[i])
+ break;
+ }
+ gst_buffer_unmap(buffer, &codec_data_map);
+ return FALSE;
+ }
+ gst_buffer_unmap(buffer, &codec_data_map);
+ }
+
+ new_caps = gst_caps_copy(cur_caps);
+ if (!new_caps) {
+ LOGW("Failed to copy caps");
+ return FALSE;
+ }
+
+ new_buffer = gst_buffer_new_allocate(NULL, codec_data_size, NULL);
+ if (!new_buffer) {
+ LOGW("Failed to alloc gst buffer for codec data");
+ gst_caps_unref(new_caps);
+ return FALSE;
+ }
+ gst_buffer_fill(new_buffer, 0, codec_data, codec_data_size);
+ gst_caps_set_simple(new_caps, "codec_data", GST_TYPE_BUFFER, new_buffer, NULL);
+ gst_buffer_unref(new_buffer);
+
+ if (streamtype == MM_PLAYER_STREAM_TYPE_AUDIO)
+ player->a_stream_caps = new_caps;
+ else if (streamtype == MM_PLAYER_STREAM_TYPE_VIDEO)
+ player->v_stream_caps = new_caps;
+
+ gst_caps_unref(cur_caps);
- return MM_ERROR_NONE;
+ LOGD("need to update caps due to codec data is changed");
+ return TRUE;
}