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 ========================================================================================== */
28 #include "mm_player_es.h"
29 #include "mm_player_utils.h"
30 #include "mm_player_internal.h"
32 #include <gst/app/gstappsrc.h>
34 /*---------------------------------------------------------------------------
35 | LOCAL VARIABLE DEFINITIONS for internal |
36 ---------------------------------------------------------------------------*/
38 /*---------------------------------------------------------------------------
39 | LOCAL FUNCTION PROTOTYPES: |
40 ---------------------------------------------------------------------------*/
41 static int _parse_media_format (MMPlayerVideoStreamInfo * video, MMPlayerAudioStreamInfo * audio, media_format_h format);
42 static int _convert_media_format_video_mime_to_str (MMPlayerVideoStreamInfo * video, media_format_mimetype_e mime);
43 static int _convert_media_format_audio_mime_to_str (MMPlayerAudioStreamInfo * audio, media_format_mimetype_e mime);
45 /*===========================================================================================
47 | FUNCTION DEFINITIONS |
49 ========================================================================================== */
52 _convert_media_format_video_mime_to_str (MMPlayerVideoStreamInfo * video,
53 media_format_mimetype_e mime)
55 return_val_if_fail (video, MM_ERROR_INVALID_ARGUMENT);
58 case MEDIA_FORMAT_MPEG4_SP:
59 video->mime = g_strdup ("video/mpeg");
62 case MEDIA_FORMAT_H264_SP:
63 case MEDIA_FORMAT_H264_MP:
64 case MEDIA_FORMAT_H264_HP:
65 video->mime = g_strdup ("video/x-h264");
68 video->mime = g_strdup ("unknown");
76 _convert_media_format_audio_mime_to_str (MMPlayerAudioStreamInfo * audio,
77 media_format_mimetype_e mime)
79 return_val_if_fail (audio, MM_ERROR_INVALID_ARGUMENT);
82 case MEDIA_FORMAT_AAC:
83 audio->mime = g_strdup ("audio/mpeg");
87 audio->mime = g_strdup ("unknown");
95 _parse_media_format (MMPlayerVideoStreamInfo * video,
96 MMPlayerAudioStreamInfo * audio, media_format_h format)
99 media_format_mimetype_e mime;
104 if (media_format_get_audio_info (format, &mime, &channel, &samplerate, NULL,
105 &avg_bps) != MEDIA_FORMAT_ERROR_NONE) {
106 debug_error ("media_format_get_audio_info failed");
107 return MM_ERROR_PLAYER_INTERNAL;
110 _convert_media_format_audio_mime_to_str (audio, mime);
111 audio->sample_rate = samplerate;
112 audio->channels = channel;
113 //video->user_info = ;
117 media_format_mimetype_e mime;
122 if (media_format_get_video_info (format, &mime, &width, &height, &avg_bps,
123 NULL) != MEDIA_FORMAT_ERROR_NONE) {
124 debug_error ("media_format_get_video_info failed");
125 return MM_ERROR_PLAYER_INTERNAL;
128 _convert_media_format_video_mime_to_str (video, mime);
129 video->width = width;
130 video->height = height;
133 return MM_ERROR_NONE;
137 _mmplayer_update_video_info(MMHandleType hplayer, media_format_h fmt)
139 mm_player_t *player = (mm_player_t *) hplayer;
140 gboolean ret = FALSE;
141 GstStructure *str = NULL;
142 media_format_mimetype_e mimetype = 0;
143 gint cur_width = 0, width = 0;
144 gint cur_height = 0, height = 0;
148 return_val_if_fail (player, FALSE);
149 return_val_if_fail (fmt, FALSE);
151 if (player->v_stream_caps)
153 str = gst_caps_get_structure (player->v_stream_caps, 0);
154 if ( !gst_structure_get_int (str, "width", &cur_width))
156 debug_log ("missing 'width' field in video caps");
159 if ( !gst_structure_get_int (str, "height", &cur_height))
161 debug_log ("missing 'height' field in video caps");
164 media_format_get_video_info(fmt, &mimetype, &width, &height, NULL, NULL);
165 if ((cur_width != width) || (cur_height != height))
167 debug_warning ("resolution is changed %dx%d -> %dx%d",
168 cur_width, cur_height, width, height);
169 _mmplayer_set_video_info(hplayer, fmt);
180 _mmplayer_set_media_stream_buffer_status_cb(MMHandleType hplayer,
181 MMPlayerStreamType type,
182 mm_player_media_stream_buffer_status_callback callback,
185 mm_player_t *player = (mm_player_t *) hplayer;
189 return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
191 if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
192 return MM_ERROR_INVALID_ARGUMENT;
194 if (player->media_stream_buffer_status_cb[type])
198 debug_log ("[type:%d] will be clear.\n", type);
202 debug_log ("[type:%d] will be overwritten.\n", type);
206 player->media_stream_buffer_status_cb[type] = callback;
207 player->buffer_cb_user_param = user_param;
209 debug_log ("player handle %p, type %d, callback %p\n", player, type,
210 player->media_stream_buffer_status_cb[type]);
214 return MM_ERROR_NONE;
218 _mmplayer_set_media_stream_seek_data_cb(MMHandleType hplayer,
219 MMPlayerStreamType type,
220 mm_player_media_stream_seek_data_callback callback,
223 mm_player_t *player = (mm_player_t *) hplayer;
227 return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
229 if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
230 return MM_ERROR_INVALID_ARGUMENT;
232 if (player->media_stream_seek_data_cb[type])
236 debug_log ("[type:%d] will be clear.\n", type);
240 debug_log ("[type:%d] will be overwritten.\n", type);
244 player->media_stream_seek_data_cb[type] = callback;
245 player->buffer_cb_user_param = user_param;
247 debug_log ("player handle %p, type %d, callback %p\n", player, type,
248 player->media_stream_seek_data_cb[type]);
252 return MM_ERROR_NONE;
256 _mmplayer_set_media_stream_max_size(MMHandleType hplayer, MMPlayerStreamType type, guint64 max_size)
258 mm_player_t *player = (mm_player_t *) hplayer;
262 return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
264 if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
265 return MM_ERROR_INVALID_ARGUMENT;
267 player->media_stream_buffer_max_size[type] = max_size;
269 debug_log ("type %d, max_size %llu\n",
270 type, player->media_stream_buffer_max_size[type]);
274 return MM_ERROR_NONE;
278 _mmplayer_get_media_stream_max_size(MMHandleType hplayer, MMPlayerStreamType type, guint64 *max_size)
280 mm_player_t *player = (mm_player_t *) hplayer;
284 return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
285 return_val_if_fail (max_size, MM_ERROR_INVALID_ARGUMENT);
287 if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
288 return MM_ERROR_INVALID_ARGUMENT;
290 *max_size = player->media_stream_buffer_max_size[type];
294 return MM_ERROR_NONE;
298 _mmplayer_set_media_stream_min_percent(MMHandleType hplayer, MMPlayerStreamType type, guint min_percent)
300 mm_player_t *player = (mm_player_t *) hplayer;
304 return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
306 if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
307 return MM_ERROR_INVALID_ARGUMENT;
309 player->media_stream_buffer_min_percent[type] = min_percent;
311 debug_log ("type %d, min_per %u\n",
312 type, player->media_stream_buffer_min_percent[type]);
316 return MM_ERROR_NONE;
320 _mmplayer_get_media_stream_min_percent(MMHandleType hplayer, MMPlayerStreamType type, guint *min_percent)
322 mm_player_t *player = (mm_player_t *) hplayer;
326 return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
327 return_val_if_fail (min_percent, MM_ERROR_INVALID_ARGUMENT);
329 if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
330 return MM_ERROR_INVALID_ARGUMENT;
332 *min_percent = player->media_stream_buffer_min_percent[type];
336 return MM_ERROR_NONE;
340 _mmplayer_submit_packet (MMHandleType hplayer, media_packet_h packet)
342 int ret = MM_ERROR_NONE;
344 mm_player_t *player = (mm_player_t *) hplayer;
346 MMPlayerTrackType streamtype = MM_PLAYER_TRACK_TYPE_AUDIO;
347 media_format_h fmt = NULL;
349 return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
350 return_val_if_fail (packet, MM_ERROR_INVALID_ARGUMENT);
353 media_packet_get_buffer_data_ptr (packet, (void **) &buf);
356 GstMapInfo buff_info = GST_MAP_INFO_INIT;
362 media_packet_get_buffer_size (packet, &size);
364 _buffer = gst_buffer_new_and_alloc (size);
365 if (gst_buffer_map (_buffer, &buff_info, GST_MAP_READWRITE)) {
367 memcpy (buff_info.data, buf, size);
368 buff_info.size = size;
370 gst_buffer_unmap (_buffer, &buff_info);
374 media_packet_get_pts (packet, &pts);
375 GST_BUFFER_PTS (_buffer) = (GstClockTime) (pts * 1000000);
377 /* get stream type if audio or video */
378 media_packet_is_audio (packet, &flag);
380 streamtype = MM_PLAYER_TRACK_TYPE_AUDIO;
382 media_packet_is_video (packet, &flag);
385 streamtype = MM_PLAYER_TRACK_TYPE_VIDEO;
387 streamtype = MM_PLAYER_TRACK_TYPE_TEXT;
390 if (streamtype == MM_PLAYER_TRACK_TYPE_AUDIO) {
391 #if 0 // TO CHECK : has gone (set to pad)
392 if (GST_CAPS_IS_SIMPLE (player->a_stream_caps))
393 GST_BUFFER_CAPS (_buffer) = gst_caps_copy (player->a_stream_caps);
395 debug_error ("External Demuxer case: Audio Buffer Caps not set.");
397 if (player->pipeline->mainbin[MMPLAYER_M_2ND_SRC].gst)
398 gst_app_src_push_buffer (GST_APP_SRC (player->pipeline->mainbin[MMPLAYER_M_2ND_SRC].gst), _buffer);
399 else if (g_strrstr (GST_ELEMENT_NAME (player->pipeline->mainbin[MMPLAYER_M_SRC].gst), "audio_appsrc"))
400 gst_app_src_push_buffer (GST_APP_SRC (player->pipeline->mainbin[MMPLAYER_M_SRC].gst), _buffer);
401 } else if (streamtype == MM_PLAYER_TRACK_TYPE_VIDEO) {
402 #if 0 // TO CHECK : has gone (set to pad)
403 if (GST_CAPS_IS_SIMPLE (player->v_stream_caps))
404 GST_BUFFER_CAPS (_buffer) = gst_caps_copy (player->v_stream_caps);
406 debug_error ("External Demuxer case: Video Buffer Caps not set.");
408 /* get format to check video format */
409 media_packet_get_format (packet, &fmt);
412 gboolean ret = FALSE;
413 ret = _mmplayer_update_video_info(hplayer, fmt);
416 g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst),
417 "caps", player->v_stream_caps, NULL);
421 gst_app_src_push_buffer (GST_APP_SRC (player->pipeline->mainbin[MMPLAYER_M_SRC].gst), _buffer);
422 } else if (streamtype == MM_PLAYER_TRACK_TYPE_TEXT) {
423 #if 0 // TO CHECK : has gone (set to pad)
424 if (GST_CAPS_IS_SIMPLE (player->s_stream_caps))
425 GST_BUFFER_CAPS (_buffer) = gst_caps_copy (player->s_stream_caps);
427 debug_error ("External Demuxer case: Subtitle Buffer Caps not set.");
429 gst_app_src_push_buffer (GST_APP_SRC (player->pipeline->mainbin[MMPLAYER_M_SUBSRC].gst), _buffer);
431 debug_error ("Not a valid packet from external demux");
435 debug_log ("Sending EOS on pipeline...");
436 if (streamtype == MM_PLAYER_TRACK_TYPE_AUDIO) {
437 if (player->pipeline->mainbin[MMPLAYER_M_2ND_SRC].gst)
438 g_signal_emit_by_name (player->pipeline->
439 mainbin[MMPLAYER_M_2ND_SRC].gst, "end-of-stream", &ret);
441 g_signal_emit_by_name (player->pipeline->mainbin[MMPLAYER_M_SRC].gst,
442 "end-of-stream", &ret);
443 } else if (streamtype == MM_PLAYER_TRACK_TYPE_VIDEO) {
444 g_signal_emit_by_name (player->pipeline->mainbin[MMPLAYER_M_SRC].gst,
445 "end-of-stream", &ret);
446 } else if (streamtype == MM_PLAYER_TRACK_TYPE_TEXT) {
447 g_signal_emit_by_name (player->pipeline->mainbin[MMPLAYER_M_SUBSRC].gst,
448 "end-of-stream", &ret);
452 if (MMPLAYER_PENDING_STATE (player) == MM_PLAYER_STATE_PLAYING) {
453 //ret = __mmplayer_set_state(player, MM_PLAYER_STATE_PLAYING);
460 _mmplayer_video_caps_new (MMHandleType hplayer, MMPlayerVideoStreamInfo * video,
461 const char *fieldname, ...)
464 GstCaps *caps = NULL;
465 GstStructure *structure = NULL;
467 mm_player_t *player = MM_PLAYER_CAST (hplayer);
470 return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
471 return_val_if_fail (video, MM_ERROR_PLAYER_NOT_INITIALIZED);
473 debug_log ("width=%d height=%d framerate num=%d, den=%d",
474 video->width, video->height, video->framerate_num, video->framerate_den);
476 caps = gst_caps_new_simple (video->mime,
477 "width", G_TYPE_INT, video->width,
478 "height", G_TYPE_INT, video->height,
479 "framerate", GST_TYPE_FRACTION, video->framerate_num, video->framerate_den, NULL);
481 for (cap_size = 0; cap_size < gst_caps_get_size (caps); cap_size++) {
482 va_start (var_args, fieldname);
483 structure = gst_caps_get_structure (caps, cap_size);
484 gst_structure_set_valist (structure, fieldname, var_args);
488 if (video->extradata_size) {
489 GstBuffer *buf = NULL;
490 GstMapInfo buff_info = GST_MAP_INFO_INIT;
492 buf = gst_buffer_new_and_alloc (video->extradata_size);
494 if (gst_buffer_map (buf, &buff_info, GST_MAP_READ)) {
495 memcpy (buff_info.data, video->codec_extradata, video->extradata_size);
496 buff_info.size = video->extradata_size;
497 gst_buffer_unmap (buf, &buff_info);
500 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
501 gst_buffer_unref (buf);
504 if (player->v_stream_caps)
506 debug_warning ("caps will be updated ");
508 gst_caps_unref(player->v_stream_caps);
509 player->v_stream_caps = NULL;
512 player->v_stream_caps = gst_caps_copy (caps);
513 MMPLAYER_LOG_GST_CAPS_TYPE (player->v_stream_caps);
514 gst_caps_unref (caps);
518 return MM_ERROR_NONE;
522 _mmplayer_set_video_info (MMHandleType hplayer, media_format_h format)
524 mm_player_t *player = MM_PLAYER_CAST (hplayer);
525 MMPlayerVideoStreamInfo video = { 0, };
526 int ret = MM_ERROR_NONE;
530 return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
532 ret = _parse_media_format (&video, NULL, format);
533 if(ret != MM_ERROR_NONE)
536 if (strstr (video.mime, "video/mpeg")) {
537 _mmplayer_video_caps_new (hplayer, &video,
538 "mpegversion", G_TYPE_INT, video.version,
539 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
540 } else if (strstr (video.mime, "video/x-h264")) {
541 //if (info.colordepth)
543 // _mmplayer_video_caps_new(hplayer, &info,
544 // "colordepth", G_TYPE_INT, info.colordepth, NULL);
548 _mmplayer_video_caps_new (hplayer, &video,
549 "stream-format", G_TYPE_STRING, "byte-stream",
550 "alignment", G_TYPE_STRING, "au", NULL);
554 else if (strstr (info->mime, "video/x-wmv")) {
555 _mmplayer_video_caps_new (hplayer, &info,
556 "wmvversion", G_TYPE_INT, info.version, NULL);
557 } else if (strstr (info.mime, "video/x-pn-realvideo")) {
558 _mmplayer_video_caps_new (hplayer, &info,
559 "rmversion", G_TYPE_INT, info.version, NULL);
560 } else if (strstr (info.mime, "video/x-msmpeg")) {
561 _mmplayer_video_caps_new (hplayer, &info,
562 "msmpegversion", G_TYPE_INT, info.version, NULL);
563 } else if (strstr (info.mime, "video/x-h265")) {
564 if (info.colordepth) {
565 _mmplayer_video_caps_new (hplayer, &info,
566 "colordepth", G_TYPE_INT, info.colordepth, NULL);
568 _mmplayer_video_caps_new (hplayer, &info, NULL);
571 _mmplayer_video_caps_new (hplayer, &info, NULL);
574 g_free ((char *) video.mime);
578 return MM_ERROR_NONE;
582 _mmplayer_set_audio_info (MMHandleType hplayer, media_format_h format)
584 mm_player_t *player = MM_PLAYER_CAST (hplayer);
585 GstCaps *caps = NULL;
586 MMPlayerAudioStreamInfo audio = { 0, };
587 int ret = MM_ERROR_NONE;
591 return_val_if_fail (hplayer, MM_ERROR_PLAYER_NOT_INITIALIZED);
593 ret = _parse_media_format (NULL, &audio, format);
594 if(ret != MM_ERROR_NONE)
597 audio.user_info = 0; //test
599 debug_log ("set audio player[%p] info [%p] version=%d rate=%d channel=%d",
600 player, audio, audio.version, audio.sample_rate, audio.channels);
602 if (strstr (audio.mime, "audio/mpeg")) {
603 if (audio.version == 1) { // mp3
604 caps = gst_caps_new_simple ("audio/mpeg",
605 "channels", G_TYPE_INT, audio.channels,
606 "rate", G_TYPE_INT, audio.sample_rate,
607 "mpegversion", G_TYPE_INT, audio.version,
608 "layer", G_TYPE_INT, audio.user_info, NULL);
610 gchar *format = NULL;
612 if (audio.user_info == 0)
613 format = g_strdup ("raw");
614 else if (audio.user_info == 1)
615 format = g_strdup ("adts");
616 else if (audio.user_info == 2)
617 format = g_strdup ("adif");
619 caps = gst_caps_new_simple ("audio/mpeg",
620 "channels", G_TYPE_INT, audio.channels,
621 "rate", G_TYPE_INT, audio.sample_rate,
622 "mpegversion", G_TYPE_INT, audio.version,
623 "stream-format", G_TYPE_STRING, format, NULL);
630 else if (strstr (audio.mime, "audio/x-raw-int")) {
631 caps = gst_caps_new_simple ("audio/x-raw-int",
632 "width", G_TYPE_INT, audio.width,
633 "depth", G_TYPE_INT, audio.depth,
634 "endianness", G_TYPE_INT, audio.endianness,
635 "signed", G_TYPE_BOOLEAN, audio.signedness,
636 "channels", G_TYPE_INT, audio.channels,
637 "rate", G_TYPE_INT, audio.sample_rate, NULL);
639 caps = gst_caps_new_simple (audio.mime,
640 "channels", G_TYPE_INT, audio.channels,
641 "rate", G_TYPE_INT, audio.sample_rate, NULL);
645 if (audio.extradata_size) {
646 GstBuffer *buf = NULL;
647 GstMapInfo buff_info = GST_MAP_INFO_INIT;
649 buf = gst_buffer_new_and_alloc (audio.extradata_size);
651 if (gst_buffer_map (buf, &buff_info, GST_MAP_READ)) {
652 memcpy (buff_info.data, audio.codec_extradata, audio.extradata_size);
653 gst_buffer_unmap (buf, &buff_info);
656 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
657 gst_buffer_unref (buf);
660 g_free ((char *) audio.mime);
662 player->a_stream_caps = gst_caps_copy (caps);
663 gst_caps_unref (caps);
667 return MM_ERROR_NONE;
671 _mmplayer_set_subtitle_info (MMHandleType hplayer,
672 MMPlayerSubtitleStreamInfo * subtitle)
676 mm_player_t *player = MM_PLAYER_CAST (hplayer);
677 GstCaps *caps = NULL;
681 return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
682 return_val_if_fail (info, MM_ERROR_PLAYER_NOT_INITIALIZED);
684 debug_log ("set subtitle player[%p] info [%p]", player, info);
687 caps = gst_caps_new_simple (info->mime, NULL, NULL); // TO CHECK
691 if (strstr (info->mime, "application/x-xsub")) {
692 gst_caps_set_simple (caps, "codec_tag", G_TYPE_UINT, info->codec_tag, NULL);
693 } else if (strstr (info->mime, "application/x-smpte-text")) {
695 gst_caps_set_simple (caps, "ttml_priv_data", G_TYPE_POINTER,
696 info->context, NULL);
700 player->s_stream_caps = gst_caps_copy (caps);
702 gst_caps_unref (caps);
707 return MM_ERROR_NONE;