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