X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmm_player_es.c;h=4df407f674580494fcb8f23500a0351cf8e88e47;hb=639e0f78bf947b1922b7ec947f373f3ddc8c0223;hp=e821e1e30818d24595017565641381f8e99d9169;hpb=aa6637df278a85dfa536cf665aae954da5218a8d;p=platform%2Fcore%2Fmultimedia%2Flibmm-player.git diff --git a/src/mm_player_es.c b/src/mm_player_es.c index e821e1e..4df407f 100644 --- a/src/mm_player_es.c +++ b/src/mm_player_es.c @@ -1,12 +1,12 @@ /* * 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 , heechul jeon , * YoungHwan An , Eunhae Choi * - * 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 * @@ -28,250 +28,235 @@ #include #include "mm_player_es.h" #include "mm_player_utils.h" -#include "mm_player_internal.h" #include /*--------------------------------------------------------------------------- -| 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; + } - LOGD ("player handle %p, type %d, callback %p\n", player, type, - player->media_stream_buffer_status_cb[type]); + if (media_format_get_video_frame_rate(format, &frame_rate)) + LOGW("failed to get video frame rate, will be set 30."); - MMPLAYER_FLEAVE (); + LOGD("frame_rate %d", frame_rate); + + __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; } @@ -283,531 +268,681 @@ __mmplayer_get_source_element (mm_player_t *player, MMPlayerStreamType type) } 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_t *player = (mmplayer_t *)hplayer; - MMPLAYER_FENTER (); + MMPLAYER_FENTER(); - MMPLAYER_RETURN_VAL_IF_FAIL (player, MM_ERROR_PLAYER_NOT_INITIALIZED); - MMPLAYER_RETURN_VAL_IF_FAIL (min_percent, MM_ERROR_INVALID_ARGUMENT); - - 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); - } - } - } - - /* 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"); + goto __FAILED; + } + + if (!cur_caps) { + LOGW("Current caps is NULL"); + goto __FAILED; + } + + str = gst_caps_get_structure(cur_caps, 0); + if (!str) { + LOGW("Failed to get caps info"); + goto __FAILED; + } + + /* 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"); + goto __FAILED; + } + 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); + goto __FAILED; + } + gst_buffer_unmap(buffer, &codec_data_map); + } + + new_caps = gst_caps_copy(cur_caps); + if (!new_caps) { + LOGW("Failed to copy caps"); + goto __FAILED; + } + + new_buffer = gst_buffer_new_allocate(NULL, codec_data_size, NULL); + if (!new_buffer) { + LOGW("Failed to alloc gst buffer for codec data"); + goto __FAILED; + } + 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); + free(codec_data); + + LOGD("need to update caps due to codec data is changed"); + + return TRUE; + +__FAILED: + if (new_caps) + gst_caps_unref(new_caps); + + if (codec_data) + free(codec_data); - return MM_ERROR_NONE; + return FALSE; }