[v0.6.11] add buffer status cb lock and check state transition when unrealize
[platform/core/multimedia/libmm-player.git] / src / mm_player_es.c
1 /*
2  * libmm-player
3  *
4  * Copyright(c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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>
8  *
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
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
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.
20  *
21  */
22
23 /*===========================================================================================
24 |                                                                                                                                                                                       |
25 |  INCLUDE FILES                                                                                                                                                        |
26 |                                                                                                                                                                                       |
27 ========================================================================================== */
28 #include <dlog.h>
29 #include "mm_player_es.h"
30 #include "mm_player_utils.h"
31 #include "mm_player_internal.h"
32
33 #include <gst/app/gstappsrc.h>
34
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
42 /*---------------------------------------------------------------------------
43 |    LOCAL FUNCTION PROTOTYPES:                                             |
44 ---------------------------------------------------------------------------*/
45 static int __parse_media_format(MMPlayerVideoStreamInfo * video, MMPlayerAudioStreamInfo * audio, media_format_h format);
46 static int __convert_media_format_video_mime_to_str(MMPlayerVideoStreamInfo * video, media_format_mimetype_e mime);
47 static int __convert_media_format_audio_mime_to_str(MMPlayerAudioStreamInfo * audio, media_format_mimetype_e mime);
48
49 /*===========================================================================================
50 |                                                                                                                                                                                       |
51 |  FUNCTION DEFINITIONS                                                                                                                                         |
52 |                                                                                                                                                                                       |
53 ========================================================================================== */
54
55 static int
56 __convert_media_format_video_mime_to_str(MMPlayerVideoStreamInfo * video,
57         media_format_mimetype_e mime)
58 {
59         MMPLAYER_RETURN_VAL_IF_FAIL(video, MM_ERROR_INVALID_ARGUMENT);
60
61         switch (mime) {
62         case MEDIA_FORMAT_MPEG4_SP:
63                 video->mime = g_strdup("video/mpeg");
64                 video->version = 4;
65                 break;
66         case MEDIA_FORMAT_H264_SP:
67         case MEDIA_FORMAT_H264_MP:
68         case MEDIA_FORMAT_H264_HP:
69                 video->mime = g_strdup("video/x-h264");
70                 break;
71         default:
72                 video->mime = g_strdup("unknown");
73                 break;
74         }
75
76         return MM_ERROR_NONE;
77 }
78
79 static int
80 __convert_media_format_audio_mime_to_str(MMPlayerAudioStreamInfo * audio,
81         media_format_mimetype_e mime)
82 {
83         MMPLAYER_RETURN_VAL_IF_FAIL(audio, MM_ERROR_INVALID_ARGUMENT);
84
85         switch (mime) {
86         case MEDIA_FORMAT_AAC:
87                 audio->mime = g_strdup("audio/mpeg");
88                 audio->version = 2;
89                 break;
90         default:
91                 audio->mime = g_strdup("unknown");
92                 break;
93         }
94
95         return MM_ERROR_NONE;
96 }
97
98 static int
99 __parse_media_format(MMPlayerVideoStreamInfo * video,
100         MMPlayerAudioStreamInfo * audio, media_format_h format)
101 {
102         if (audio) {
103                 media_format_mimetype_e mime;
104                 int channel;
105                 int samplerate;
106                 int avg_bps;
107
108                 if (media_format_get_audio_info(format, &mime, &channel, &samplerate, NULL,
109                         &avg_bps) != MEDIA_FORMAT_ERROR_NONE) {
110                         LOGE("media_format_get_audio_info failed");
111                         return MM_ERROR_PLAYER_INTERNAL;
112                 }
113
114                 __convert_media_format_audio_mime_to_str(audio, mime);
115                 audio->sample_rate = samplerate;
116                 audio->channels = channel;
117                 //video->user_info = ;
118         }
119
120         if (video) {
121                 media_format_mimetype_e mime;
122                 int width = 0;
123                 int height = 0;
124                 int avg_bps = 0;
125                 int frame_rate = 0;
126
127                 if (media_format_get_video_info(format, &mime, &width, &height, &avg_bps,
128                         NULL) != MEDIA_FORMAT_ERROR_NONE) {
129                         LOGE("media_format_get_video_info failed");
130                         return MM_ERROR_PLAYER_INTERNAL;
131                 }
132
133                 if (media_format_get_video_frame_rate(format, &frame_rate))
134                         LOGW("failed to get video frame rate, will be set 30.");
135
136                 LOGD("frame_rate %d", frame_rate);
137
138                 __convert_media_format_video_mime_to_str(video, mime);
139
140                 video->width = width;
141                 video->height = height;
142                 video->framerate_num = (frame_rate > 0) ? (frame_rate) : (DEFAULT_FRAMERATE_NUM);
143                 video->framerate_den = DEFAULT_FRAMERATE_DEN;
144         }
145
146         return MM_ERROR_NONE;
147 }
148
149 static gboolean
150 __mmplayer_update_video_info(MMHandleType hplayer, media_format_h fmt)
151 {
152         mm_player_t *player = (mm_player_t *) hplayer;
153         gboolean ret = FALSE;
154         GstStructure *str = NULL;
155         media_format_mimetype_e mimetype = 0;
156         gint cur_width = 0, width = 0;
157         gint cur_height = 0, height = 0;
158
159         MMPLAYER_FENTER();
160
161         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
162         MMPLAYER_RETURN_VAL_IF_FAIL(fmt, FALSE);
163
164         if (player->v_stream_caps) {
165                 str = gst_caps_get_structure(player->v_stream_caps, 0);
166                 if (!gst_structure_get_int(str, "width", &cur_width))
167                         LOGD("missing 'width' field in video caps");
168
169                 if (!gst_structure_get_int(str, "height", &cur_height))
170                         LOGD("missing 'height' field in video caps");
171
172                 media_format_get_video_info(fmt, &mimetype, &width, &height, NULL, NULL);
173                 if ((cur_width != width) || (cur_height != height)) {
174                         LOGW("resolution is changed %dx%d -> %dx%d",
175                                 cur_width, cur_height, width, height);
176                         _mmplayer_set_video_info(hplayer, fmt);
177                         ret = TRUE;
178                 }
179         }
180
181         MMPLAYER_FLEAVE();
182         return ret;
183 }
184
185
186 int
187 _mmplayer_set_media_stream_buffer_status_cb(MMHandleType hplayer,
188                                                                                         MMPlayerStreamType type,
189                                                                                         mm_player_media_stream_buffer_status_callback callback,
190                                                                                         void *user_param)
191 {
192         mm_player_t *player = (mm_player_t *) hplayer;
193
194         MMPLAYER_FENTER();
195
196         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
197
198         if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
199                 return MM_ERROR_INVALID_ARGUMENT;
200
201         MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
202
203         if (player->media_stream_buffer_status_cb[type]) {
204                 if (!callback)
205                         LOGD("[type:%d] will be clear.\n", type);
206                 else
207                         LOGD("[type:%d] will be overwritten.\n", type);
208         }
209
210         player->media_stream_buffer_status_cb[type] = callback;
211         player->buffer_cb_user_param = user_param;
212
213         LOGD("player handle %p, type %d, callback %p\n", player, type,
214                 player->media_stream_buffer_status_cb[type]);
215         MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
216
217         MMPLAYER_FLEAVE();
218
219         return MM_ERROR_NONE;
220 }
221
222 int
223 _mmplayer_set_media_stream_seek_data_cb(MMHandleType hplayer,
224                                                                                 MMPlayerStreamType type,
225                                                                                 mm_player_media_stream_seek_data_callback callback,
226                                                                                 void *user_param)
227 {
228         mm_player_t *player = (mm_player_t *) hplayer;
229
230         MMPLAYER_FENTER();
231
232         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
233
234         if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
235                 return MM_ERROR_INVALID_ARGUMENT;
236         MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
237
238         if (player->media_stream_seek_data_cb[type]) {
239                 if (!callback)
240                         LOGD("[type:%d] will be clear.\n", type);
241                 else
242                         LOGD("[type:%d] will be overwritten.\n", type);
243         }
244
245         player->media_stream_seek_data_cb[type] = callback;
246         player->buffer_cb_user_param = user_param;
247
248         LOGD("player handle %p, type %d, callback %p\n", player, type,
249                 player->media_stream_seek_data_cb[type]);
250         MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
251
252         MMPLAYER_FLEAVE();
253
254         return MM_ERROR_NONE;
255 }
256
257 static GstElement*
258 __mmplayer_get_source_element(mm_player_t *player, MMPlayerStreamType type)
259 {
260         enum MainElementID elemId = MMPLAYER_M_NUM;
261
262         if (player && player->pipeline && player->pipeline->mainbin) {
263                 /* get elem according to the stream type */
264                 if (type == MM_PLAYER_STREAM_TYPE_AUDIO) {
265                         if (player->pipeline->mainbin[MMPLAYER_M_2ND_SRC].gst)
266                                 elemId = MMPLAYER_M_2ND_SRC;
267                         else if (g_strrstr(GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_SRC].gst), "audio_appsrc"))
268                                 elemId = MMPLAYER_M_SRC;
269                 } else if (type == MM_PLAYER_STREAM_TYPE_VIDEO) {
270                         elemId = MMPLAYER_M_SRC;
271                 } else if (type == MM_PLAYER_STREAM_TYPE_TEXT) {
272                         elemId = MMPLAYER_M_SUBSRC;
273                 }
274
275                 if (elemId != MMPLAYER_M_NUM)
276                         return player->pipeline->mainbin[elemId].gst;
277         }
278
279         return NULL;
280 }
281
282 int
283 _mmplayer_set_media_stream_max_size(MMHandleType hplayer, MMPlayerStreamType type, guint64 max_size)
284 {
285         mm_player_t *player = (mm_player_t *) hplayer;
286         GstElement *element = NULL;
287
288         MMPLAYER_FENTER();
289         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
290
291         if ((type < MM_PLAYER_STREAM_TYPE_AUDIO) ||
292                 (type > MM_PLAYER_STREAM_TYPE_TEXT) ||
293                 (max_size == 0)) {
294                 LOGE("Invalid param type:%d, max_size:%d", type, max_size);
295                 return MM_ERROR_INVALID_ARGUMENT;
296         }
297
298         LOGD("type %d, max_size %llu\n", type, max_size);
299
300         if ((element = __mmplayer_get_source_element(player, type))) {
301                 LOGD("update max_size of %s\n", GST_ELEMENT_NAME(element));
302                 g_object_set(G_OBJECT(element), "max-bytes", max_size, NULL);
303         }
304
305         player->media_stream_buffer_max_size[type] = max_size;
306
307         MMPLAYER_FLEAVE();
308         return MM_ERROR_NONE;
309 }
310
311 int
312 _mmplayer_get_media_stream_max_size(MMHandleType hplayer, MMPlayerStreamType type, guint64 *max_size)
313 {
314         mm_player_t *player = (mm_player_t *) hplayer;
315
316         MMPLAYER_FENTER();
317
318         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
319         MMPLAYER_RETURN_VAL_IF_FAIL(max_size, MM_ERROR_INVALID_ARGUMENT);
320
321         if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
322                 return MM_ERROR_INVALID_ARGUMENT;
323
324         *max_size = player->media_stream_buffer_max_size[type];
325
326         MMPLAYER_FLEAVE();
327
328         return MM_ERROR_NONE;
329 }
330
331 int
332 _mmplayer_set_media_stream_min_percent(MMHandleType hplayer, MMPlayerStreamType type, guint min_percent)
333 {
334         mm_player_t *player = (mm_player_t *) hplayer;
335         GstElement *element = NULL;
336
337         MMPLAYER_FENTER();
338
339         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
340
341         if ((type < MM_PLAYER_STREAM_TYPE_AUDIO) || (type > MM_PLAYER_STREAM_TYPE_TEXT)) {
342                 LOGE("Invalid param type:%d", type);
343                 return MM_ERROR_INVALID_ARGUMENT;
344         }
345
346         LOGD("type %d, min_per %u\n", type, min_percent);
347
348         if ((element = __mmplayer_get_source_element(player, type))) {
349                 LOGD("update min_per of %s\n", GST_ELEMENT_NAME(element));
350                 g_object_set(G_OBJECT(element), "min-percent", min_percent, NULL);
351         }
352
353         player->media_stream_buffer_min_percent[type] = min_percent;
354
355         MMPLAYER_FLEAVE();
356         return MM_ERROR_NONE;
357 }
358
359 int
360 _mmplayer_get_media_stream_min_percent(MMHandleType hplayer, MMPlayerStreamType type, guint *min_percent)
361 {
362         mm_player_t *player = (mm_player_t *) hplayer;
363
364         MMPLAYER_FENTER();
365
366         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
367         MMPLAYER_RETURN_VAL_IF_FAIL(min_percent, MM_ERROR_INVALID_ARGUMENT);
368
369         if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
370                 return MM_ERROR_INVALID_ARGUMENT;
371
372         *min_percent = player->media_stream_buffer_min_percent[type];
373
374         MMPLAYER_FLEAVE();
375
376         return MM_ERROR_NONE;
377 }
378
379 static int
380 __mmplayer_check_buffer_level(mm_player_t *player, GstElement* element, MMPlayerStreamType type)
381 {
382         guint64 current_level_bytes = 0;
383         guint64 max_bytes = 0;
384         guint current_level_per = 0;
385
386         MMPLAYER_FENTER();
387         MMPLAYER_RETURN_VAL_IF_FAIL(player && element, MM_ERROR_PLAYER_NOT_INITIALIZED);
388
389         if (player->media_stream_buffer_max_size[type] > 0)
390                 max_bytes = player->media_stream_buffer_max_size[type];
391         else
392                 g_object_get(G_OBJECT(element), "max-bytes", &max_bytes, NULL);
393
394         if (max_bytes == 0) {
395                 LOGW("buffer max size is zero.");
396                 return MM_ERROR_NONE;
397         }
398
399         g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
400
401         if (max_bytes <= current_level_bytes) {
402                 LOGE("no available buffer space. type %d, max %lld, curr %lld", type, max_bytes, current_level_bytes);
403                 return MM_ERROR_PLAYER_BUFFER_SPACE;
404         }
405
406         if (MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING) {
407                 MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
408                 if (!player->media_stream_buffer_status_cb[type]) {
409                         MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
410                         return MM_ERROR_NONE;
411                 }
412
413                 current_level_per = (guint)(gst_util_guint64_to_gdouble(current_level_bytes)/gst_util_guint64_to_gdouble(max_bytes)*100);
414
415                 LOGD("type %d, min_per %u, curr_per %u max %lld cur %lld\n",
416                                         type, player->media_stream_buffer_min_percent[type],
417                                         current_level_per,
418                                         player->media_stream_buffer_max_size[type],
419                                         current_level_bytes);
420
421                 if (current_level_per < player->media_stream_buffer_min_percent[type])
422                         player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param);
423
424                 MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
425         }
426
427         MMPLAYER_FLEAVE();
428         return MM_ERROR_NONE;
429 }
430
431 int
432 _mmplayer_submit_packet(MMHandleType hplayer, media_packet_h packet)
433 {
434         int ret = MM_ERROR_NONE;
435         GstBuffer *_buffer = NULL;
436         mm_player_t *player = (mm_player_t *) hplayer;
437         guint8 *buf = NULL;
438         uint64_t size = 0;
439         GstElement* element = NULL;
440         MMPlayerStreamType streamtype = MM_PLAYER_STREAM_TYPE_AUDIO;
441         media_format_h fmt = NULL;
442         bool flag = FALSE;
443         bool is_eos = FALSE;
444
445         MMPLAYER_RETURN_VAL_IF_FAIL(packet, MM_ERROR_INVALID_ARGUMENT);
446         MMPLAYER_RETURN_VAL_IF_FAIL(player &&
447         player->pipeline &&
448         player->pipeline->mainbin &&
449         player->pipeline->mainbin[MMPLAYER_M_SRC].gst,
450         MM_ERROR_PLAYER_NOT_INITIALIZED);
451
452         /* get stream type if audio or video */
453         media_packet_is_audio(packet, &flag);
454         if (flag) {
455                 streamtype = MM_PLAYER_STREAM_TYPE_AUDIO;
456         } else {
457                 media_packet_is_video(packet, &flag);
458                 if (flag)
459                         streamtype = MM_PLAYER_STREAM_TYPE_VIDEO;
460                 else
461                         streamtype = MM_PLAYER_STREAM_TYPE_TEXT;
462         }
463
464         element = __mmplayer_get_source_element(player, streamtype);
465         if (!element) {
466                 LOGE("there is no source element of type %d", streamtype);
467                 ret = MM_ERROR_PLAYER_INTERNAL;
468                 goto ERROR;
469         }
470
471         /* check buffer level */
472         ret = __mmplayer_check_buffer_level(player, element, streamtype);
473         if (ret != MM_ERROR_NONE)
474                 return ret;
475
476         /* get data */
477         if (media_packet_get_buffer_data_ptr(packet, (void **) &buf) != MEDIA_PACKET_ERROR_NONE) {
478                 LOGE("failed to get buffer data ptr");
479                 ret = MM_ERROR_PLAYER_INTERNAL;
480                 goto ERROR;
481         }
482
483         if (media_packet_get_buffer_size(packet, &size) != MEDIA_PACKET_ERROR_NONE) {
484                 LOGE("failed to get buffer size");
485                 ret = MM_ERROR_PLAYER_INTERNAL;
486                 goto ERROR;
487         }
488
489         if (buf != NULL && size > 0) {
490                 GstMapInfo buff_info = GST_MAP_INFO_INIT;
491                 uint64_t pts = 0;
492                 uint64_t duration = 0;
493
494                 /* get size */
495                 _buffer = gst_buffer_new_and_alloc(size);
496
497                 if (!_buffer) {
498                         LOGE("failed to allocate memory for push buffer\n");
499                         ret = MM_ERROR_PLAYER_NO_FREE_SPACE;
500                         goto ERROR;
501                 }
502
503                 if (gst_buffer_map(_buffer, &buff_info, GST_MAP_READWRITE)) {
504                         memcpy(buff_info.data, buf, size);
505                         buff_info.size = size;
506
507                         gst_buffer_unmap(_buffer, &buff_info);
508                 }
509
510                 if (streamtype == MM_PLAYER_STREAM_TYPE_VIDEO) {
511                         /* get format to check video format */
512                         media_packet_get_format(packet, &fmt);
513                         if (fmt) {
514                                 if (__mmplayer_update_video_info(hplayer, fmt)) {
515                                         LOGD("update video caps");
516                                         g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst),
517                                                 "caps", player->v_stream_caps, NULL);
518                                 }
519                                 media_format_unref(fmt);
520                         }
521
522                         /* get duration */
523                         if (media_packet_get_duration(packet, &duration) != MEDIA_PACKET_ERROR_NONE) {
524                                 LOGW("failed to get duration info");
525                                 /* keep push without error handling */
526                         }
527
528                         if (duration == 0)
529                                 duration = DEFAULT_VIDEO_FRAME_DURATION * GST_MSECOND;
530
531                         GST_BUFFER_DURATION(_buffer) = (GstClockTime)duration;
532                 }
533
534                 /* get pts */
535                 if (media_packet_get_pts(packet, &pts) != MEDIA_PACKET_ERROR_NONE) {
536                         LOGE("failed to get pts info");
537                         ret = MM_ERROR_PLAYER_INTERNAL;
538                         goto ERROR;
539                 }
540                 GST_BUFFER_PTS(_buffer) = (GstClockTime)pts;
541                 gst_app_src_push_buffer(GST_APP_SRC(element), _buffer);
542         }
543
544         /* check eos */
545         if (media_packet_is_end_of_stream(packet, &is_eos) != MEDIA_PACKET_ERROR_NONE) {
546                 LOGE("failed to get eos info");
547                 ret = MM_ERROR_PLAYER_INTERNAL;
548                 goto ERROR;
549         }
550
551         if (is_eos) {
552                 LOGW("we got eos of stream type(%d)", streamtype);
553                 g_signal_emit_by_name(element, "end-of-stream", &ret);
554         }
555
556 ERROR:
557         return ret;
558 }
559
560 static int
561 __mmplayer_video_caps_new(MMHandleType hplayer, MMPlayerVideoStreamInfo * video,
562         const char *fieldname, ...)
563 {
564         int cap_size;
565         GstCaps *caps = NULL;
566         GstStructure *structure = NULL;
567         va_list var_args;
568         mm_player_t *player = MM_PLAYER_CAST(hplayer);
569
570         MMPLAYER_FENTER();
571         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
572         MMPLAYER_RETURN_VAL_IF_FAIL(video, MM_ERROR_PLAYER_NOT_INITIALIZED);
573
574         LOGD("width=%d height=%d framerate num=%d, den=%d",
575         video->width, video->height, video->framerate_num, video->framerate_den);
576
577         caps = gst_caps_new_simple(video->mime,
578                 "width", G_TYPE_INT, video->width,
579                 "height", G_TYPE_INT, video->height,
580                 "framerate", GST_TYPE_FRACTION, video->framerate_num, video->framerate_den, NULL);
581
582         for (cap_size = 0; cap_size < gst_caps_get_size(caps); cap_size++) {
583                 va_start(var_args, fieldname);
584                 structure = gst_caps_get_structure(caps, cap_size);
585                 gst_structure_set_valist(structure, fieldname, var_args);
586                 va_end(var_args);
587         }
588
589         if (video->extradata_size) {
590                 GstBuffer *buf = NULL;
591                 GstMapInfo buff_info = GST_MAP_INFO_INIT;
592
593                 buf = gst_buffer_new_and_alloc(video->extradata_size);
594
595                 if (gst_buffer_map(buf, &buff_info, GST_MAP_READ)) {
596                         memcpy(buff_info.data, video->codec_extradata, video->extradata_size);
597                         buff_info.size = video->extradata_size;
598                         gst_buffer_unmap(buf, &buff_info);
599                 }
600
601                 gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
602                 gst_buffer_unref(buf);
603         }
604
605         if (player->v_stream_caps) {
606                 LOGW("caps will be updated ");
607
608                 gst_caps_unref(player->v_stream_caps);
609                 player->v_stream_caps = NULL;
610         }
611
612         player->v_stream_caps = gst_caps_copy(caps);
613         MMPLAYER_LOG_GST_CAPS_TYPE(player->v_stream_caps);
614         gst_caps_unref(caps);
615
616         MMPLAYER_FLEAVE();
617
618         return MM_ERROR_NONE;
619 }
620
621 static void
622 __mmplayer_set_uri_type(mm_player_t *player)
623 {
624         MMPLAYER_FENTER();
625
626         player->profile.uri_type = MM_PLAYER_URI_TYPE_MS_BUFF;
627         player->es_player_push_mode = TRUE;
628
629         MMPLAYER_FLEAVE();
630         return;
631 }
632
633 int
634 _mmplayer_set_video_info(MMHandleType hplayer, media_format_h format)
635 {
636         mm_player_t *player = MM_PLAYER_CAST(hplayer);
637         MMPlayerVideoStreamInfo video = { 0, };
638         int ret = MM_ERROR_NONE;
639         gboolean drc = FALSE;
640
641         MMPLAYER_FENTER();
642
643         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
644
645         __mmplayer_set_uri_type(player);
646
647         ret = __parse_media_format(&video, NULL, format);
648         if (ret != MM_ERROR_NONE)
649                 return ret;
650
651         mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_DRC_MODE, &drc);
652
653         if (strstr(video.mime, "video/mpeg")) {
654                 __mmplayer_video_caps_new(hplayer, &video,
655                 "mpegversion", G_TYPE_INT, video.version,
656                 "systemstream", G_TYPE_BOOLEAN, FALSE,
657                 "adaptive-streaming", G_TYPE_BOOLEAN, drc, NULL);
658         } else if (strstr(video.mime, "video/x-h264")) {
659                 /*
660                 if (info.colordepth) {
661                         __mmplayer_video_caps_new(hplayer, &info,
662                                 "colordepth", G_TYPE_INT, info.colordepth, NULL);
663                 } else
664                 */
665                 {
666                         __mmplayer_video_caps_new(hplayer, &video,
667                         "stream-format", G_TYPE_STRING, "byte-stream",
668                         "alignment", G_TYPE_STRING, "au",
669                         "adaptive-streaming", G_TYPE_BOOLEAN, drc, NULL);
670                 }
671         }
672 #if 0
673         else if (strstr(info->mime, "video/x-wmv")) {
674                 __mmplayer_video_caps_new(hplayer, &info,
675                 "wmvversion", G_TYPE_INT, info.version, NULL);
676         } else if (strstr(info.mime, "video/x-pn-realvideo")) {
677                 __mmplayer_video_caps_new(hplayer, &info,
678                 "rmversion", G_TYPE_INT, info.version, NULL);
679         } else if (strstr(info.mime, "video/x-msmpeg")) {
680                 __mmplayer_video_caps_new(hplayer, &info,
681                 "msmpegversion", G_TYPE_INT, info.version, NULL);
682         } else if (strstr(info.mime, "video/x-h265")) {
683                 if (info.colordepth)
684                         __mmplayer_video_caps_new(hplayer, &info,
685                         "colordepth", G_TYPE_INT, info.colordepth, NULL);
686                 else
687                         __mmplayer_video_caps_new(hplayer, &info, NULL);
688         } else
689                 __mmplayer_video_caps_new(hplayer, &info, NULL);
690 #endif
691         g_free((char *) video.mime);
692
693         MMPLAYER_FLEAVE();
694
695         return MM_ERROR_NONE;
696 }
697
698 int
699 _mmplayer_set_audio_info(MMHandleType hplayer, media_format_h format)
700 {
701         mm_player_t *player = MM_PLAYER_CAST(hplayer);
702         GstCaps *caps = NULL;
703         MMPlayerAudioStreamInfo audio = { 0, };
704         int ret = MM_ERROR_NONE;
705
706         MMPLAYER_FENTER();
707
708         MMPLAYER_RETURN_VAL_IF_FAIL(hplayer, MM_ERROR_PLAYER_NOT_INITIALIZED);
709
710         __mmplayer_set_uri_type(player);
711
712         ret = __parse_media_format(NULL, &audio, format);
713         if (ret != MM_ERROR_NONE)
714                 return ret;
715
716         audio.user_info = 0;           //test
717
718         LOGD("set audio player[%p] info [%p] version=%d rate=%d channel=%d",
719         player, audio, audio.version, audio.sample_rate, audio.channels);
720
721         if (strstr(audio.mime, "audio/mpeg")) {
722                 if (audio.version == 1) {       // mp3
723                         caps = gst_caps_new_simple("audio/mpeg",
724                         "channels", G_TYPE_INT, audio.channels,
725                         "rate", G_TYPE_INT, audio.sample_rate,
726                         "mpegversion", G_TYPE_INT, audio.version,
727                         "layer", G_TYPE_INT, audio.user_info, NULL);
728                 } else {                    // aac
729                         gchar *format = NULL;
730
731                         if (audio.user_info == 0)
732                         format = g_strdup("raw");
733                         else if (audio.user_info == 1)
734                         format = g_strdup("adts");
735                         else if (audio.user_info == 2)
736                         format = g_strdup("adif");
737
738                         caps = gst_caps_new_simple("audio/mpeg",
739                         "channels", G_TYPE_INT, audio.channels,
740                         "rate", G_TYPE_INT, audio.sample_rate,
741                         "mpegversion", G_TYPE_INT, audio.version,
742                         "stream-format", G_TYPE_STRING, format, NULL);
743
744                         g_free(format);
745                         format = NULL;
746                 }
747         }
748 #if 0
749         else if (strstr(audio.mime, "audio/x-raw-int")) {
750                 caps = gst_caps_new_simple("audio/x-raw-int",
751                 "width", G_TYPE_INT, audio.width,
752                 "depth", G_TYPE_INT, audio.depth,
753                 "endianness", G_TYPE_INT, audio.endianness,
754                 "signed", G_TYPE_BOOLEAN, audio.signedness,
755                 "channels", G_TYPE_INT, audio.channels,
756                 "rate", G_TYPE_INT, audio.sample_rate, NULL);
757         } else {
758                 caps = gst_caps_new_simple(audio.mime,
759                 "channels", G_TYPE_INT, audio.channels,
760                 "rate", G_TYPE_INT, audio.sample_rate, NULL);
761         }
762 #endif
763
764         if (audio.extradata_size) {
765                 GstBuffer *buf = NULL;
766                 GstMapInfo buff_info = GST_MAP_INFO_INIT;
767
768                 buf = gst_buffer_new_and_alloc(audio.extradata_size);
769
770                 if (gst_buffer_map(buf, &buff_info, GST_MAP_READ)) {
771                         memcpy(buff_info.data, audio.codec_extradata, audio.extradata_size);
772                         gst_buffer_unmap(buf, &buff_info);
773                 }
774
775                 gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
776                 gst_buffer_unref(buf);
777         }
778
779         g_free((char *) audio.mime);
780
781         player->a_stream_caps = gst_caps_copy(caps);
782         gst_caps_unref(caps);
783
784         MMPLAYER_FLEAVE();
785
786         return MM_ERROR_NONE;
787 }
788
789 int
790 _mmplayer_set_subtitle_info(MMHandleType hplayer,
791         MMPlayerSubtitleStreamInfo * subtitle)
792 {
793 #if 0                           //todo
794         mm_player_t *player = MM_PLAYER_CAST(hplayer);
795         GstCaps *caps = NULL;
796
797         MMPLAYER_FENTER();
798
799         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
800         MMPLAYER_RETURN_VAL_IF_FAIL(info, MM_ERROR_PLAYER_NOT_INITIALIZED);
801
802         LOGD("set subtitle player[%p] info [%p]", player, info);
803
804
805         caps = gst_caps_new_simple(info->mime, NULL, NULL);  // TO CHECK
806         if (NULL == caps)
807                 return FALSE;
808
809         if (strstr(info->mime, "application/x-xsub")) {
810                 gst_caps_set_simple(caps, "codec_tag", G_TYPE_UINT, info->codec_tag, NULL);
811         } else if (strstr(info->mime, "application/x-smpte-text")) {
812                 if (info->context) {
813                         gst_caps_set_simple(caps, "ttml_priv_data", G_TYPE_POINTER,
814                         info->context, NULL);
815                 }
816         }
817
818         player->s_stream_caps = gst_caps_copy(caps);
819
820         gst_caps_unref(caps);
821 #endif
822
823         MMPLAYER_FLEAVE();
824
825         return MM_ERROR_NONE;
826 }
827
828 int
829 _mmplayer_set_media_stream_dynamic_resolution(MMHandleType hplayer, bool drc)
830 {
831         mm_player_t *player = MM_PLAYER_CAST(hplayer);
832         int ret = MM_ERROR_NONE;
833
834         MMPLAYER_FENTER();
835
836         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
837
838         mm_attrs_set_int_by_name(player->attrs, MM_PLAYER_DRC_MODE, (int)drc);
839         if (player->v_stream_caps) {
840                 gst_caps_set_simple(player->v_stream_caps,
841                         "adaptive-streaming", G_TYPE_BOOLEAN, drc, NULL);
842                 MMPLAYER_LOG_GST_CAPS_TYPE(player->v_stream_caps);
843         }
844
845         MMPLAYER_FLEAVE();
846
847         return ret;
848 }
849