4 * Copyright(c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, heechul jeon <heechul.jeon@samsung.co>,
7 * YoungHwan An <younghwan_.an@samsung.com>, Eunhae Choi <eunhae1.choi@samsung.com>
9 * Licensed under the Apache License, Version 2.0(the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 /*===========================================================================================
27 ========================================================================================== */
29 #include "mm_player_es.h"
30 #include "mm_player_utils.h"
31 #include "mm_player_internal.h"
33 #include <gst/app/gstappsrc.h>
35 /*---------------------------------------------------------------------------
36 | LOCAL VARIABLE DEFINITIONS for internal |
37 ---------------------------------------------------------------------------*/
38 #define DEFAULT_FRAMERATE_NUM 30
39 #define DEFAULT_FRAMERATE_DEN 1
40 #define DEFAULT_VIDEO_FRAME_DURATION 33 /* ms */
41 #define PLAYER_DATA_PUSH_WAIT_COUNT 10
42 #define PLAYER_STATE_CHECK_INTERVAL (100 * 1000)
44 /*---------------------------------------------------------------------------
45 | LOCAL FUNCTION PROTOTYPES: |
46 ---------------------------------------------------------------------------*/
47 static int __parse_media_format(MMPlayerVideoStreamInfo *video, MMPlayerAudioStreamInfo *audio, media_format_h format);
48 static int __convert_media_format_video_mime_to_str(MMPlayerVideoStreamInfo *video, media_format_mimetype_e mime);
49 static int __convert_media_format_audio_mime_to_str(MMPlayerAudioStreamInfo *audio, media_format_mimetype_e mime);
50 static gboolean __mm_player_is_codec_data_changed(mm_player_t *player, media_packet_h packet, MMPlayerStreamType streamtype);
52 /*===========================================================================================
54 | FUNCTION DEFINITIONS |
56 ========================================================================================== */
59 __convert_media_format_video_mime_to_str(MMPlayerVideoStreamInfo *video,
60 media_format_mimetype_e mime)
62 MMPLAYER_RETURN_VAL_IF_FAIL(video, MM_ERROR_INVALID_ARGUMENT);
65 case MEDIA_FORMAT_MPEG4_SP:
66 video->mime = g_strdup("video/mpeg");
69 case MEDIA_FORMAT_H264_SP:
70 case MEDIA_FORMAT_H264_MP:
71 case MEDIA_FORMAT_H264_HP:
72 video->mime = g_strdup("video/x-h264");
75 video->mime = g_strdup("unknown");
83 __convert_media_format_audio_mime_to_str(MMPlayerAudioStreamInfo *audio,
84 media_format_mimetype_e mime)
86 MMPLAYER_RETURN_VAL_IF_FAIL(audio, MM_ERROR_INVALID_ARGUMENT);
89 case MEDIA_FORMAT_AAC:
90 audio->mime = g_strdup("audio/mpeg");
94 audio->mime = g_strdup("unknown");
102 __parse_media_format(MMPlayerVideoStreamInfo *video,
103 MMPlayerAudioStreamInfo *audio, media_format_h format)
106 media_format_mimetype_e mime;
111 if (media_format_get_audio_info(format, &mime, &channel, &samplerate, NULL,
112 &avg_bps) != MEDIA_FORMAT_ERROR_NONE) {
113 LOGE("media_format_get_audio_info failed");
114 return MM_ERROR_PLAYER_INTERNAL;
117 __convert_media_format_audio_mime_to_str(audio, mime);
118 audio->sample_rate = samplerate;
119 audio->channels = channel;
120 //video->user_info = ;
124 media_format_mimetype_e mime;
130 if (media_format_get_video_info(format, &mime, &width, &height, &avg_bps,
131 NULL) != MEDIA_FORMAT_ERROR_NONE) {
132 LOGE("media_format_get_video_info failed");
133 return MM_ERROR_PLAYER_INTERNAL;
136 if (media_format_get_video_frame_rate(format, &frame_rate))
137 LOGW("failed to get video frame rate, will be set 30.");
139 LOGD("frame_rate %d", frame_rate);
141 __convert_media_format_video_mime_to_str(video, mime);
143 video->width = width;
144 video->height = height;
145 video->framerate_num = (frame_rate > 0) ? frame_rate : DEFAULT_FRAMERATE_NUM;
146 video->framerate_den = DEFAULT_FRAMERATE_DEN;
149 return MM_ERROR_NONE;
153 __mmplayer_update_video_info(MMHandleType hplayer, media_format_h fmt)
155 mm_player_t *player = (mm_player_t *)hplayer;
156 gboolean ret = FALSE;
157 GstStructure *str = NULL;
158 media_format_mimetype_e mimetype = 0;
159 gint cur_width = 0, width = 0;
160 gint cur_height = 0, height = 0;
164 MMPLAYER_RETURN_VAL_IF_FAIL(player && player->v_stream_caps, FALSE);
165 MMPLAYER_RETURN_VAL_IF_FAIL(fmt, FALSE);
167 if (MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PAUSED &&
168 MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING) {
169 LOGW("skip update video info, state: %s", MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)));
173 str = gst_caps_get_structure(player->v_stream_caps, 0);
175 LOGE("failed to get caps info");
179 if (!gst_structure_get_int(str, "width", &cur_width))
180 LOGD("missing 'width' field in video caps");
182 if (!gst_structure_get_int(str, "height", &cur_height))
183 LOGD("missing 'height' field in video caps");
185 media_format_get_video_info(fmt, &mimetype, &width, &height, NULL, NULL);
186 if ((cur_width != width) || (cur_height != height)) {
187 LOGW("resolution is changed %dx%d -> %dx%d",
188 cur_width, cur_height, width, height);
189 _mmplayer_set_video_info(hplayer, fmt);
198 _mmplayer_set_media_stream_buffer_status_cb(MMHandleType hplayer,
199 MMPlayerStreamType type,
200 mm_player_media_stream_buffer_status_callback callback,
203 mm_player_t *player = (mm_player_t *)hplayer;
207 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
209 MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
211 if (player->media_stream_buffer_status_cb[type]) {
213 LOGD("[type:%s] will be clear", MMPLAYER_STREAM_TYPE_GET_NAME(type));
215 LOGD("[type:%s] will be overwritten", MMPLAYER_STREAM_TYPE_GET_NAME(type));
218 player->media_stream_buffer_status_cb[type] = callback;
219 player->buffer_cb_user_param[type] = user_param;
221 LOGD("player handle %p, type %s, callback %p",
222 player, MMPLAYER_STREAM_TYPE_GET_NAME(type), player->media_stream_buffer_status_cb[type]);
223 MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
227 return MM_ERROR_NONE;
231 _mmplayer_set_media_stream_seek_data_cb(MMHandleType hplayer,
232 MMPlayerStreamType type,
233 mm_player_media_stream_seek_data_callback callback,
236 mm_player_t *player = (mm_player_t *)hplayer;
240 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
242 MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
244 if (player->media_stream_seek_data_cb[type]) {
246 LOGD("[type:%s] will be clear", MMPLAYER_STREAM_TYPE_GET_NAME(type));
248 LOGD("[type:%s] will be overwritten", MMPLAYER_STREAM_TYPE_GET_NAME(type));
251 player->media_stream_seek_data_cb[type] = callback;
252 player->seek_cb_user_param[type] = user_param;
254 LOGD("player handle %p, type %s, callback %p",
255 player, MMPLAYER_STREAM_TYPE_GET_NAME(type), player->media_stream_seek_data_cb[type]);
256 MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
260 return MM_ERROR_NONE;
264 __mmplayer_get_source_element(mm_player_t *player, MMPlayerStreamType type)
266 enum MainElementID elemId = MMPLAYER_M_NUM;
268 if (player && player->pipeline && player->pipeline->mainbin) {
269 /* get elem according to the stream type */
270 if (type == MM_PLAYER_STREAM_TYPE_AUDIO) {
271 if (player->pipeline->mainbin[MMPLAYER_M_2ND_SRC].gst)
272 elemId = MMPLAYER_M_2ND_SRC;
273 else if (g_strrstr(GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_SRC].gst), "audio_appsrc"))
274 elemId = MMPLAYER_M_SRC;
275 } else if (type == MM_PLAYER_STREAM_TYPE_VIDEO) {
276 elemId = MMPLAYER_M_SRC;
277 } else if (type == MM_PLAYER_STREAM_TYPE_TEXT) {
278 elemId = MMPLAYER_M_SUBSRC;
281 if (elemId != MMPLAYER_M_NUM)
282 return player->pipeline->mainbin[elemId].gst;
289 _mmplayer_set_media_stream_max_size(MMHandleType hplayer, MMPlayerStreamType type, guint64 max_size)
291 mm_player_t *player = (mm_player_t *)hplayer;
292 GstElement *element = NULL;
295 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
297 if ((type < MM_PLAYER_STREAM_TYPE_AUDIO) ||
298 (type > MM_PLAYER_STREAM_TYPE_TEXT) ||
300 LOGE("Invalid param type:%d, max_size:%"G_GUINT64_FORMAT, type, max_size);
301 return MM_ERROR_INVALID_ARGUMENT;
304 LOGD("type:%s, max_size %"G_GUINT64_FORMAT, MMPLAYER_STREAM_TYPE_GET_NAME(type), max_size);
306 if ((element = __mmplayer_get_source_element(player, type))) {
307 LOGD("update max_size of %s", GST_ELEMENT_NAME(element));
308 g_object_set(G_OBJECT(element), "max-bytes", max_size, NULL);
311 player->media_stream_buffer_max_size[type] = max_size;
314 return MM_ERROR_NONE;
318 _mmplayer_get_media_stream_max_size(MMHandleType hplayer, MMPlayerStreamType type, guint64 *max_size)
320 mm_player_t *player = (mm_player_t *)hplayer;
324 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
325 MMPLAYER_RETURN_VAL_IF_FAIL(max_size, MM_ERROR_INVALID_ARGUMENT);
327 *max_size = player->media_stream_buffer_max_size[type];
331 return MM_ERROR_NONE;
335 _mmplayer_set_media_stream_min_percent(MMHandleType hplayer, MMPlayerStreamType type, guint min_percent)
337 mm_player_t *player = (mm_player_t *)hplayer;
338 GstElement *element = NULL;
342 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
344 if ((type < MM_PLAYER_STREAM_TYPE_AUDIO) || (type > MM_PLAYER_STREAM_TYPE_TEXT)) {
345 LOGE("Invalid param type:%d", type);
346 return MM_ERROR_INVALID_ARGUMENT;
349 LOGD("type:%s, min_per %u", MMPLAYER_STREAM_TYPE_GET_NAME(type), min_percent);
351 if ((element = __mmplayer_get_source_element(player, type))) {
352 LOGD("update min_per of %s", GST_ELEMENT_NAME(element));
353 g_object_set(G_OBJECT(element), "min-percent", min_percent, NULL);
356 player->media_stream_buffer_min_percent[type] = min_percent;
359 return MM_ERROR_NONE;
363 _mmplayer_get_media_stream_min_percent(MMHandleType hplayer, MMPlayerStreamType type, guint *min_percent)
365 mm_player_t *player = (mm_player_t *)hplayer;
369 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
370 MMPLAYER_RETURN_VAL_IF_FAIL(min_percent, MM_ERROR_INVALID_ARGUMENT);
372 *min_percent = player->media_stream_buffer_min_percent[type];
376 return MM_ERROR_NONE;
380 __mmplayer_check_buffer_level(mm_player_t *player, GstElement *element, MMPlayerStreamType type)
382 guint64 current_level_bytes = 0;
383 guint64 max_bytes = 0;
384 guint current_level_per = 0;
387 MMPLAYER_RETURN_VAL_IF_FAIL(player && element, MM_ERROR_PLAYER_NOT_INITIALIZED);
389 if (player->media_stream_buffer_max_size[type] > 0)
390 max_bytes = player->media_stream_buffer_max_size[type];
392 g_object_get(G_OBJECT(element), "max-bytes", &max_bytes, NULL);
394 if (max_bytes == 0) {
395 LOGW("buffer max size is zero");
396 return MM_ERROR_NONE;
399 g_object_get(G_OBJECT(element), "current-level-bytes", ¤t_level_bytes, NULL);
401 if (max_bytes <= current_level_bytes) {
402 LOGE("no available buffer space, type: %s, max %"G_GUINT64_FORMAT", curr %"G_GUINT64_FORMAT,
403 MMPLAYER_STREAM_TYPE_GET_NAME(type), max_bytes, current_level_bytes);
404 return MM_ERROR_PLAYER_BUFFER_SPACE;
407 if (MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING) {
408 MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
409 if (!player->media_stream_buffer_status_cb[type]) {
410 MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
411 return MM_ERROR_NONE;
414 current_level_per = (guint)(gst_util_guint64_to_gdouble(current_level_bytes) / gst_util_guint64_to_gdouble(max_bytes) * 100);
416 LOGD("type: %s, min_per %u, curr_per %u max %"G_GUINT64_FORMAT" cur %"G_GUINT64_FORMAT,
417 MMPLAYER_STREAM_TYPE_GET_NAME(type), player->media_stream_buffer_min_percent[type],
419 player->media_stream_buffer_max_size[type],
420 current_level_bytes);
422 if (current_level_per < player->media_stream_buffer_min_percent[type])
423 player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param[type]);
425 MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
429 return MM_ERROR_NONE;
433 _mmplayer_submit_packet(MMHandleType hplayer, media_packet_h packet)
435 int ret = MM_ERROR_NONE;
436 GstBuffer *_buffer = NULL;
437 mm_player_t *player = (mm_player_t *)hplayer;
440 GstElement *element = NULL;
441 MMPlayerStreamType streamtype = MM_PLAYER_STREAM_TYPE_AUDIO;
442 media_format_h fmt = NULL;
445 gboolean need_update_caps = false;
447 MMPLAYER_RETURN_VAL_IF_FAIL(packet, MM_ERROR_INVALID_ARGUMENT);
448 MMPLAYER_RETURN_VAL_IF_FAIL(player &&
450 player->pipeline->mainbin &&
451 player->pipeline->mainbin[MMPLAYER_M_SRC].gst,
452 MM_ERROR_PLAYER_NOT_INITIALIZED);
454 /* get stream type if audio or video */
455 media_packet_is_audio(packet, &flag);
457 streamtype = MM_PLAYER_STREAM_TYPE_AUDIO;
459 media_packet_is_video(packet, &flag);
461 streamtype = MM_PLAYER_STREAM_TYPE_VIDEO;
463 streamtype = MM_PLAYER_STREAM_TYPE_TEXT;
466 need_update_caps = __mm_player_is_codec_data_changed(player, packet, streamtype);
468 element = __mmplayer_get_source_element(player, streamtype);
470 LOGE("there is no source element of type %d", streamtype);
471 ret = MM_ERROR_PLAYER_INTERNAL;
475 /* check buffer level */
476 ret = __mmplayer_check_buffer_level(player, element, streamtype);
477 if (ret != MM_ERROR_NONE)
481 if (media_packet_get_buffer_data_ptr(packet, (void **)&buf) != MEDIA_PACKET_ERROR_NONE) {
482 LOGE("failed to get buffer data ptr");
483 ret = MM_ERROR_PLAYER_INTERNAL;
487 if (media_packet_get_buffer_size(packet, &size) != MEDIA_PACKET_ERROR_NONE) {
488 LOGE("failed to get buffer size");
489 ret = MM_ERROR_PLAYER_INTERNAL;
493 if (buf != NULL && size > 0) {
494 GstMapInfo buff_info = GST_MAP_INFO_INIT;
496 uint64_t duration = 0;
500 _buffer = gst_buffer_new_and_alloc(size);
503 LOGE("failed to allocate memory for push buffer");
504 ret = MM_ERROR_PLAYER_NO_FREE_SPACE;
508 if (gst_buffer_map(_buffer, &buff_info, GST_MAP_READWRITE)) {
509 memcpy(buff_info.data, buf, size);
510 buff_info.size = size;
512 gst_buffer_unmap(_buffer, &buff_info);
515 /* wait till the pipeline is ready to get data, if not some data is missed */
516 while ((GST_STATE(element) < GST_STATE_PAUSED) && (wait_cnt < PLAYER_DATA_PUSH_WAIT_COUNT)) {
517 LOGW("wait to update source state : %d, %d", player->state, GST_STATE(element));
518 usleep(PLAYER_STATE_CHECK_INTERVAL);
522 if (wait_cnt == PLAYER_DATA_PUSH_WAIT_COUNT) {
523 LOGE("source is not ready %d", GST_STATE(element));
524 ret = MM_ERROR_PLAYER_INTERNAL;
528 if (streamtype == MM_PLAYER_STREAM_TYPE_VIDEO) {
529 /* get format to check video format */
530 media_packet_get_format(packet, &fmt);
532 need_update_caps |= __mmplayer_update_video_info(hplayer, fmt);
533 media_format_unref(fmt);
536 if (need_update_caps)
537 g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst),
538 "caps", player->v_stream_caps, NULL);
541 if (media_packet_get_duration(packet, &duration) != MEDIA_PACKET_ERROR_NONE) {
542 LOGW("failed to get duration info");
543 /* keep push without error handling */
547 duration = DEFAULT_VIDEO_FRAME_DURATION * GST_MSECOND;
549 GST_BUFFER_DURATION(_buffer) = (GstClockTime)duration;
550 } else if ((streamtype == MM_PLAYER_STREAM_TYPE_AUDIO) && need_update_caps) {
551 LOGD("update audio caps");
552 g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst),
553 "caps", player->a_stream_caps, NULL);
557 if (media_packet_get_pts(packet, &pts) != MEDIA_PACKET_ERROR_NONE) {
558 LOGE("failed to get pts info");
559 ret = MM_ERROR_PLAYER_INTERNAL;
562 GST_BUFFER_PTS(_buffer) = (GstClockTime)pts;
564 if (MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING) {
565 /* the pushed pts should be lager than current position if it is not in playing state. */
566 LOGD("type:%s, curr pos: %"G_GINT64_FORMAT", pushed pts:%"G_GINT64_FORMAT", size:%"G_GUINT64_FORMAT,
567 MMPLAYER_STREAM_TYPE_GET_NAME(streamtype), player->last_position, (GstClockTime)pts, (guint64)size);
570 gst_app_src_push_buffer(GST_APP_SRC(element), _buffer);
572 LOGW("There is no data to push : buf %p, size %"G_GUINT64_FORMAT, buf, (guint64)size);
576 if (media_packet_is_end_of_stream(packet, &is_eos) != MEDIA_PACKET_ERROR_NONE) {
577 LOGE("failed to get eos info");
578 return MM_ERROR_PLAYER_INTERNAL;
582 LOGW("we got eos of stream type(%s)", MMPLAYER_STREAM_TYPE_GET_NAME(streamtype));
583 g_signal_emit_by_name(element, "end-of-stream", &ret);
589 gst_buffer_unref(_buffer);
594 __mmplayer_video_caps_new(MMHandleType hplayer, MMPlayerVideoStreamInfo *video,
595 const char *fieldname, ...)
598 GstCaps *caps = NULL;
599 GstStructure *structure = NULL;
601 mm_player_t *player = MM_PLAYER_CAST(hplayer);
604 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
605 MMPLAYER_RETURN_VAL_IF_FAIL(video, MM_ERROR_PLAYER_NOT_INITIALIZED);
607 LOGD("width=%d height=%d framerate num=%d, den=%d",
608 video->width, video->height, video->framerate_num, video->framerate_den);
610 caps = gst_caps_new_simple(video->mime,
611 "width", G_TYPE_INT, video->width,
612 "height", G_TYPE_INT, video->height,
613 "framerate", GST_TYPE_FRACTION, video->framerate_num, video->framerate_den, NULL);
615 for (cap_size = 0; cap_size < gst_caps_get_size(caps); cap_size++) {
616 va_start(var_args, fieldname);
617 structure = gst_caps_get_structure(caps, cap_size);
618 gst_structure_set_valist(structure, fieldname, var_args);
622 if (video->extradata_size) {
623 GstBuffer *buf = NULL;
624 GstMapInfo buff_info = GST_MAP_INFO_INIT;
626 buf = gst_buffer_new_and_alloc(video->extradata_size);
628 if (gst_buffer_map(buf, &buff_info, GST_MAP_READ)) {
629 memcpy(buff_info.data, video->codec_extradata, video->extradata_size);
630 buff_info.size = video->extradata_size;
631 gst_buffer_unmap(buf, &buff_info);
634 gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
635 gst_buffer_unref(buf);
638 if (player->v_stream_caps) {
639 LOGW("caps will be updated ");
641 gst_caps_unref(player->v_stream_caps);
642 player->v_stream_caps = NULL;
645 player->v_stream_caps = gst_caps_copy(caps);
646 MMPLAYER_LOG_GST_CAPS_TYPE(player->v_stream_caps);
647 gst_caps_unref(caps);
651 return MM_ERROR_NONE;
655 __mmplayer_set_uri_type(mm_player_t *player)
659 player->profile.uri_type = MM_PLAYER_URI_TYPE_MS_BUFF;
660 player->es_player_push_mode = TRUE;
667 _mmplayer_set_video_info(MMHandleType hplayer, media_format_h format)
669 mm_player_t *player = MM_PLAYER_CAST(hplayer);
670 MMPlayerVideoStreamInfo video = { 0, };
671 int ret = MM_ERROR_NONE;
672 gboolean drc = FALSE;
676 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
678 __mmplayer_set_uri_type(player);
680 ret = __parse_media_format(&video, NULL, format);
681 if (ret != MM_ERROR_NONE)
684 mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_DRC_MODE, &drc);
686 if (strstr(video.mime, "video/mpeg")) {
687 __mmplayer_video_caps_new(hplayer, &video,
688 "mpegversion", G_TYPE_INT, video.version,
689 "systemstream", G_TYPE_BOOLEAN, FALSE,
690 "adaptive-streaming", G_TYPE_BOOLEAN, drc, NULL);
691 } else if (strstr(video.mime, "video/x-h264")) {
693 if (info.colordepth) {
694 __mmplayer_video_caps_new(hplayer, &info,
695 "colordepth", G_TYPE_INT, info.colordepth, NULL);
699 __mmplayer_video_caps_new(hplayer, &video,
700 "stream-format", G_TYPE_STRING, "byte-stream",
701 "alignment", G_TYPE_STRING, "au",
702 "adaptive-streaming", G_TYPE_BOOLEAN, drc, NULL);
706 else if (strstr(info->mime, "video/x-wmv")) {
707 __mmplayer_video_caps_new(hplayer, &info,
708 "wmvversion", G_TYPE_INT, info.version, NULL);
709 } else if (strstr(info.mime, "video/x-pn-realvideo")) {
710 __mmplayer_video_caps_new(hplayer, &info,
711 "rmversion", G_TYPE_INT, info.version, NULL);
712 } else if (strstr(info.mime, "video/x-msmpeg")) {
713 __mmplayer_video_caps_new(hplayer, &info,
714 "msmpegversion", G_TYPE_INT, info.version, NULL);
715 } else if (strstr(info.mime, "video/x-h265")) {
717 __mmplayer_video_caps_new(hplayer, &info,
718 "colordepth", G_TYPE_INT, info.colordepth, NULL);
720 __mmplayer_video_caps_new(hplayer, &info, NULL);
722 __mmplayer_video_caps_new(hplayer, &info, NULL);
724 g_free((char *)video.mime);
728 return MM_ERROR_NONE;
732 _mmplayer_set_audio_info(MMHandleType hplayer, media_format_h format)
734 mm_player_t *player = MM_PLAYER_CAST(hplayer);
735 GstCaps *caps = NULL;
736 MMPlayerAudioStreamInfo audio = { 0, };
737 int ret = MM_ERROR_NONE;
741 MMPLAYER_RETURN_VAL_IF_FAIL(hplayer, MM_ERROR_PLAYER_NOT_INITIALIZED);
743 __mmplayer_set_uri_type(player);
745 ret = __parse_media_format(NULL, &audio, format);
746 if (ret != MM_ERROR_NONE)
749 audio.user_info = 0; //test
751 LOGD("set audio player[%p] version=%d rate=%d channel=%d",
752 player, audio.version, audio.sample_rate, audio.channels);
754 if (strstr(audio.mime, "audio/mpeg")) {
755 if (audio.version == 1) { // mp3
756 caps = gst_caps_new_simple("audio/mpeg",
757 "channels", G_TYPE_INT, audio.channels,
758 "rate", G_TYPE_INT, audio.sample_rate,
759 "mpegversion", G_TYPE_INT, audio.version,
760 "layer", G_TYPE_INT, audio.user_info, NULL);
762 gchar *stream_format = NULL;
764 if (audio.user_info == 0)
765 stream_format = g_strdup("raw");
766 else if (audio.user_info == 1)
767 stream_format = g_strdup("adts");
768 else if (audio.user_info == 2)
769 stream_format = g_strdup("adif");
771 caps = gst_caps_new_simple("audio/mpeg",
772 "channels", G_TYPE_INT, audio.channels,
773 "rate", G_TYPE_INT, audio.sample_rate,
774 "mpegversion", G_TYPE_INT, audio.version,
775 "stream-format", G_TYPE_STRING, stream_format, NULL);
777 MMPLAYER_FREEIF(stream_format);
778 stream_format = NULL;
782 else if (strstr(audio.mime, "audio/x-raw-int")) {
783 caps = gst_caps_new_simple("audio/x-raw-int",
784 "width", G_TYPE_INT, audio.width,
785 "depth", G_TYPE_INT, audio.depth,
786 "endianness", G_TYPE_INT, audio.endianness,
787 "signed", G_TYPE_BOOLEAN, audio.signedness,
788 "channels", G_TYPE_INT, audio.channels,
789 "rate", G_TYPE_INT, audio.sample_rate, NULL);
791 caps = gst_caps_new_simple(audio.mime,
792 "channels", G_TYPE_INT, audio.channels,
793 "rate", G_TYPE_INT, audio.sample_rate, NULL);
797 if (audio.extradata_size && audio.codec_extradata) {
798 GstBuffer *buf = NULL;
799 GstMapInfo buff_info = GST_MAP_INFO_INIT;
801 buf = gst_buffer_new_and_alloc(audio.extradata_size);
803 if (gst_buffer_map(buf, &buff_info, GST_MAP_READ)) {
804 memcpy(buff_info.data, audio.codec_extradata, audio.extradata_size);
805 gst_buffer_unmap(buf, &buff_info);
808 gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
809 gst_buffer_unref(buf);
810 g_free((char *)audio.codec_extradata);
813 g_free((char *)audio.mime);
815 player->a_stream_caps = gst_caps_copy(caps);
816 gst_caps_unref(caps);
820 return MM_ERROR_NONE;
824 _mmplayer_set_subtitle_info(MMHandleType hplayer,
825 MMPlayerSubtitleStreamInfo *subtitle)
828 mm_player_t *player = MM_PLAYER_CAST(hplayer);
829 GstCaps *caps = NULL;
833 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
834 MMPLAYER_RETURN_VAL_IF_FAIL(info, MM_ERROR_PLAYER_NOT_INITIALIZED);
836 LOGD("set subtitle player[%p] info [%p]", player, info);
839 caps = gst_caps_new_simple(info->mime, NULL, NULL); // TO CHECK
843 if (strstr(info->mime, "application/x-xsub")) {
844 gst_caps_set_simple(caps, "codec_tag", G_TYPE_UINT, info->codec_tag, NULL);
845 } else if (strstr(info->mime, "application/x-smpte-text")) {
847 gst_caps_set_simple(caps, "ttml_priv_data", G_TYPE_POINTER,
848 info->context, NULL);
852 player->s_stream_caps = gst_caps_copy(caps);
854 gst_caps_unref(caps);
859 return MM_ERROR_NONE;
863 _mmplayer_set_media_stream_dynamic_resolution(MMHandleType hplayer, bool drc)
865 mm_player_t *player = MM_PLAYER_CAST(hplayer);
866 int ret = MM_ERROR_NONE;
870 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
872 mm_attrs_set_int_by_name(player->attrs, MM_PLAYER_DRC_MODE, (int)drc);
873 if (player->v_stream_caps) {
874 gst_caps_set_simple(player->v_stream_caps,
875 "adaptive-streaming", G_TYPE_BOOLEAN, drc, NULL);
876 MMPLAYER_LOG_GST_CAPS_TYPE(player->v_stream_caps);
885 __mm_player_is_codec_data_changed(mm_player_t *player, media_packet_h packet,
886 MMPlayerStreamType streamtype)
888 GstCaps *cur_caps = NULL;
889 GstCaps *new_caps = NULL;
890 GstStructure *str = NULL;
891 const GValue *value = NULL;
892 GstBuffer *buffer = NULL;
893 GstMapInfo codec_data_map = GST_MAP_INFO_INIT;
894 GstBuffer *new_buffer = NULL;
895 char *codec_data = NULL;
896 unsigned int codec_data_size = 0;
898 MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
899 MMPLAYER_RETURN_VAL_IF_FAIL(packet, FALSE);
901 if (media_packet_get_codec_data(packet, (void **)&codec_data, &codec_data_size)
902 != MEDIA_PACKET_ERROR_NONE)
905 if (codec_data_size == 0) {
906 LOGW("codec_data_size is zero");
910 if (streamtype == MM_PLAYER_STREAM_TYPE_AUDIO) {
911 cur_caps = player->a_stream_caps;
912 } else if (streamtype == MM_PLAYER_STREAM_TYPE_VIDEO) {
913 cur_caps = player->v_stream_caps;
915 LOGW("streamtype is not audio or video");
920 LOGW("Current caps is NULL");
924 str = gst_caps_get_structure(cur_caps, 0);
926 LOGW("Failed to get caps info");
930 /* Check if the codec data in the saved caps have been changed */
931 value = gst_structure_get_value(str, "codec_data");
934 buffer = gst_value_get_buffer(value);
935 if (!gst_buffer_map(buffer, &codec_data_map, GST_MAP_READ)) {
936 LOGW("codec data buffer map failed");
939 if (codec_data_map.size == codec_data_size) {
940 for (i = 0; i <= codec_data_map.size; i++) {
941 if (codec_data_map.data[i] != codec_data[i])
944 gst_buffer_unmap(buffer, &codec_data_map);
947 gst_buffer_unmap(buffer, &codec_data_map);
950 new_caps = gst_caps_copy(cur_caps);
952 LOGW("Failed to copy caps");
956 new_buffer = gst_buffer_new_allocate(NULL, codec_data_size, NULL);
958 LOGW("Failed to alloc gst buffer for codec data");
959 gst_caps_unref(new_caps);
962 gst_buffer_fill(new_buffer, 0, codec_data, codec_data_size);
963 gst_caps_set_simple(new_caps, "codec_data", GST_TYPE_BUFFER, new_buffer, NULL);
964 gst_buffer_unref(new_buffer);
966 if (streamtype == MM_PLAYER_STREAM_TYPE_AUDIO)
967 player->a_stream_caps = new_caps;
968 else if (streamtype == MM_PLAYER_STREAM_TYPE_VIDEO)
969 player->v_stream_caps = new_caps;
971 gst_caps_unref(cur_caps);
973 LOGD("need to update caps due to codec data is changed");