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