resolve build break (2)
[platform/core/multimedia/libmm-player.git] / src / mm_player_priv_internal.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.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 /*===========================================================================================
23 |                                                                                                                                                                                       |
24 |  INCLUDE FILES                                                                                                                                                        |
25 |                                                                                                                                                                                       |
26 ========================================================================================== */
27 #include "mm_player_priv.h"
28 #include "mm_player_priv_internal.h"
29 #include "mm_player_priv_locl_func.h"
30
31
32 /*===========================================================================================
33 |                                                                                                                                                                                       |
34 |  LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE                                                                                        |
35 |                                                                                                                                                                                       |
36 ========================================================================================== */
37
38 /*---------------------------------------------------------------------------
39 |    GLOBAL CONSTANT DEFINITIONS:                                                                                       |
40 ---------------------------------------------------------------------------*/
41
42 /*---------------------------------------------------------------------------
43 |    IMPORTED VARIABLE DECLARATIONS:                                                                            |
44 ---------------------------------------------------------------------------*/
45
46 /*---------------------------------------------------------------------------
47 |    IMPORTED FUNCTION DECLARATIONS:                                                                            |
48 ---------------------------------------------------------------------------*/
49
50 /*---------------------------------------------------------------------------
51 |    LOCAL #defines:                                                                                                            |
52 ---------------------------------------------------------------------------*/
53
54 /*---------------------------------------------------------------------------
55 |    LOCAL CONSTANT DEFINITIONS:                                                                                        |
56 ---------------------------------------------------------------------------*/
57
58 /*---------------------------------------------------------------------------
59 |    LOCAL DATA TYPE DEFINITIONS:                                                                                       |
60 ---------------------------------------------------------------------------*/
61
62 /*---------------------------------------------------------------------------
63 |    GLOBAL VARIABLE DEFINITIONS:                                                                                       |
64 ---------------------------------------------------------------------------*/
65
66 /*---------------------------------------------------------------------------
67 |    LOCAL VARIABLE DEFINITIONS:                                                                                        |
68 ---------------------------------------------------------------------------*/
69
70 /*---------------------------------------------------------------------------
71 |    LOCAL FUNCTION PROTOTYPES:                                                                                         |
72 ---------------------------------------------------------------------------*/
73
74 /*===========================================================================================
75 |                                                                                                                                                                                       |
76 |  FUNCTION DEFINITIONS                                                                                                                                         |
77 |                                                                                                                                                                                       |
78 ========================================================================================== */
79 /* NOTE : be careful with calling this api. please refer to below glib comment
80  * glib comment : Note that there is a bug in GObject that makes this function much
81  * less useful than it might seem otherwise. Once gobject is disposed, the callback
82  * will no longer be called, but, the signal handler is not currently disconnected.
83  * If the instance is itself being freed at the same time than this doesn't matter,
84  * since the signal will automatically be removed, but if instance persists,
85  * then the signal handler will leak. You should not remove the signal yourself
86  * because in a future versions of GObject, the handler will automatically be
87  * disconnected.
88  *
89  * It's possible to work around this problem in a way that will continue to work
90  * with future versions of GObject by checking that the signal handler is still
91  * connected before disconnected it:
92  *
93  *      if (g_signal_handler_is_connected (instance, id))
94  *        g_signal_handler_disconnect (instance, id);
95  */
96 void
97 __mmplayer_release_signal_connection(mm_player_t* player)
98 {
99         GList* sig_list = player->signals;
100         MMPlayerSignalItem* item = NULL;
101
102         debug_fenter();
103
104         return_if_fail( player );
105
106         for ( ; sig_list; sig_list = sig_list->next )
107         {
108                 item = sig_list->data;
109
110                 if ( item && item->obj && GST_IS_ELEMENT(item->obj) )
111                 {
112                         debug_log("checking signal connection : [%lud] from [%s]\n", item->sig, GST_OBJECT_NAME( item->obj ));
113
114                         if ( g_signal_handler_is_connected ( item->obj, item->sig ) )
115                         {
116                                 debug_log("signal disconnecting : [%lud] from [%s]\n", item->sig, GST_OBJECT_NAME( item->obj ));
117                                 g_signal_handler_disconnect ( item->obj, item->sig );
118                         }
119                 }
120
121                 MMPLAYER_FREEIF( item );
122
123         }
124         g_list_free ( player->signals );
125         player->signals = NULL;
126
127         debug_fleave();
128
129         return;
130 }
131
132 gboolean
133 __mmplayer_dump_pipeline_state( mm_player_t* player )
134 {
135         GstIterator*iter = NULL;
136         gboolean done = FALSE;
137
138         GstElement *item = NULL;
139         GstElementFactory *factory = NULL;
140
141         GstState state = GST_STATE_VOID_PENDING;
142         GstState pending = GST_STATE_VOID_PENDING;
143         GstClockTime time = 200*GST_MSECOND;
144
145         debug_fenter();
146
147         return_val_if_fail ( player &&
148                 player->pipeline &&
149                 player->pipeline->mainbin,
150                 FALSE );
151
152         iter = gst_bin_iterate_recurse(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst) );
153
154         if ( iter != NULL )
155         {
156                 while (!done) {
157                          switch ( gst_iterator_next (iter, (gpointer)&item) )
158                          {
159                            case GST_ITERATOR_OK:
160                                 gst_element_get_state(GST_ELEMENT (item),&state, &pending,time);
161
162                                 factory = gst_element_get_factory (item) ;
163                                 if (!factory)
164                                 {
165                                          debug_error("%s:%s : From:%s To:%s   refcount : %d\n", GST_OBJECT_NAME(factory) , GST_ELEMENT_NAME(item) ,
166                                                 gst_element_state_get_name(state), gst_element_state_get_name(pending) , GST_OBJECT_REFCOUNT_VALUE(item));
167                                 }
168                                  gst_object_unref (item);
169                                  break;
170                            case GST_ITERATOR_RESYNC:
171                                  gst_iterator_resync (iter);
172                                  break;
173                            case GST_ITERATOR_ERROR:
174                                  done = TRUE;
175                                  break;
176                            case GST_ITERATOR_DONE:
177                                  done = TRUE;
178                                  break;
179                          }
180                 }
181         }
182
183         item = GST_ELEMENT(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
184
185         gst_element_get_state(GST_ELEMENT (item),&state, &pending,time);
186
187         factory = gst_element_get_factory (item) ;
188
189         if (!factory)
190         {
191                 debug_error("%s:%s : From:%s To:%s  refcount : %d\n",
192                         GST_OBJECT_NAME(factory),
193                         GST_ELEMENT_NAME(item),
194                         gst_element_state_get_name(state),
195                         gst_element_state_get_name(pending),
196                         GST_OBJECT_REFCOUNT_VALUE(item) );
197         }
198
199         if ( iter )
200                 gst_iterator_free (iter);
201
202         debug_fleave();
203
204         return FALSE;
205 }
206
207 int
208 __mmplayer_gst_set_state (mm_player_t* player, GstElement * element,  GstState state, gboolean async, gint timeout) // @
209 {
210         GstState element_state = GST_STATE_VOID_PENDING;
211         GstState element_pending_state = GST_STATE_VOID_PENDING;
212         GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
213
214         debug_fenter();
215
216         return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
217         return_val_if_fail ( element, MM_ERROR_INVALID_ARGUMENT );
218
219         debug_log("setting [%s] element state to : %d\n", GST_ELEMENT_NAME(element),  state);
220
221         /* set state */
222         ret = gst_element_set_state(element, state);
223
224         if ( ret == GST_STATE_CHANGE_FAILURE )
225         {
226                 debug_error("failed to set  [%s] state to [%d]\n", GST_ELEMENT_NAME(element), state);
227
228                 /* dump state of all element */
229                 __mmplayer_dump_pipeline_state( player );
230
231                 return MM_ERROR_PLAYER_INTERNAL;
232         }
233
234         /* return here so state transition to be done in async mode */
235         if ( async )
236         {
237                 debug_log("async state transition. not waiting for state complete.\n");
238                 return MM_ERROR_NONE;
239         }
240
241         /* wait for state transition */
242         ret = gst_element_get_state( element, &element_state, &element_pending_state, timeout * GST_SECOND );
243
244         if ( ret == GST_STATE_CHANGE_FAILURE || ( state != element_state ) )
245         {
246                 debug_error("failed to change [%s] element state to [%s] within %d sec\n",
247                         GST_ELEMENT_NAME(element),
248                         gst_element_state_get_name(state), timeout );
249
250                 debug_error(" [%s] state : %s   pending : %s \n",
251                         GST_ELEMENT_NAME(element),
252                         gst_element_state_get_name(element_state),
253                         gst_element_state_get_name(element_pending_state) );
254
255                 /* dump state of all element */
256                 __mmplayer_dump_pipeline_state( player );
257
258                 return MM_ERROR_PLAYER_INTERNAL;
259         }
260
261         debug_log("[%s] element state has changed to %s \n",
262                 GST_ELEMENT_NAME(element),
263                 gst_element_state_get_name(element_state));
264
265         debug_fleave();
266
267         return MM_ERROR_NONE;
268 }
269
270 void
271 __mmplayer_cancel_delayed_eos( mm_player_t* player )
272 {
273         debug_fenter();
274
275         return_if_fail( player );
276
277         if ( player->eos_timer )
278         {
279                 g_source_remove( player->eos_timer );
280         }
281
282         player->eos_timer = 0;
283
284         debug_fleave();
285
286         return;
287 }
288
289 gboolean
290 __mmplayer_check_subtitle( mm_player_t* player )
291 {
292         MMHandleType attrs = 0;
293         char *subtitle_uri = NULL;
294
295         debug_fenter();
296
297         return_val_if_fail( player, FALSE );
298
299         /* get subtitle attribute */
300         attrs = MMPLAYER_GET_ATTRS(player);
301         if ( !attrs )
302                 return FALSE;
303
304         mm_attrs_get_string_by_name(attrs, "subtitle_uri", &subtitle_uri);
305         if ( !subtitle_uri || !strlen(subtitle_uri))
306                 return FALSE;
307
308         debug_log ("subtite uri is %s[%d]\n", subtitle_uri, strlen(subtitle_uri));
309
310         debug_fleave();
311
312         return TRUE;
313 }
314
315 /* NOTE: post "not supported codec message" to application
316  * when one codec is not found during AUTOPLUGGING in MSL.
317  * So, it's separated with error of __mmplayer_gst_callback().
318  * And, if any codec is not found, don't send message here.
319  * Because GST_ERROR_MESSAGE is posted by other plugin internally.
320  */
321 int
322 __mmplayer_handle_missed_plugin(mm_player_t* player)
323 {
324         MMMessageParamType msg_param;
325         memset (&msg_param, 0, sizeof(MMMessageParamType));
326         gboolean post_msg_direct = FALSE;
327
328         debug_fenter();
329
330         return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
331
332         debug_log("not_supported_codec = 0x%02x, can_support_codec = 0x%02x\n",
333                         player->not_supported_codec, player->can_support_codec);
334
335         if( player->not_found_demuxer )
336         {
337                 msg_param.code = MM_ERROR_PLAYER_CODEC_NOT_FOUND;
338                 msg_param.data = g_strdup_printf("%s", player->unlinked_demuxer_mime);
339
340                 MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
341                 MMPLAYER_FREEIF(msg_param.data);
342
343                 return MM_ERROR_NONE;
344         }
345
346         if (player->not_supported_codec)
347         {
348                 if ( player->can_support_codec ) // There is one codec to play
349                 {
350                         post_msg_direct = TRUE;
351                 }
352                 else
353                 {
354                         if ( player->pipeline->audiobin ) // Some content has only PCM data in container.
355                                 post_msg_direct = TRUE;
356                 }
357
358                 if ( post_msg_direct )
359                 {
360                         MMMessageParamType msg_param;
361                         memset (&msg_param, 0, sizeof(MMMessageParamType));
362
363                         if ( player->not_supported_codec ==  MISSING_PLUGIN_AUDIO )
364                         {
365                                 debug_warning("not found AUDIO codec, posting error code to application.\n");
366
367                                 msg_param.code = MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
368                                 msg_param.data = g_strdup_printf("%s", player->unlinked_audio_mime);
369                         }
370                         else if ( player->not_supported_codec ==  MISSING_PLUGIN_VIDEO )
371                         {
372                                 debug_warning("not found VIDEO codec, posting error code to application.\n");
373
374                                 msg_param.code = MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
375                                 msg_param.data = g_strdup_printf("%s", player->unlinked_video_mime);
376                         }
377
378                         MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
379
380                         MMPLAYER_FREEIF(msg_param.data);
381
382                         return MM_ERROR_NONE;
383                 }
384                 else // no any supported codec case
385                 {
386                         debug_warning("not found any codec, posting error code to application.\n");
387
388                         if ( player->not_supported_codec ==  MISSING_PLUGIN_AUDIO )
389                         {
390                                 msg_param.code = MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
391                                 msg_param.data = g_strdup_printf("%s", player->unlinked_audio_mime);
392                         }
393                         else
394                         {
395                                 msg_param.code = MM_ERROR_PLAYER_CODEC_NOT_FOUND;
396                                 msg_param.data = g_strdup_printf("%s, %s", player->unlinked_video_mime, player->unlinked_audio_mime);
397                         }
398
399                         MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
400
401                         MMPLAYER_FREEIF(msg_param.data);
402                 }
403         }
404
405         debug_fleave();
406
407         return MM_ERROR_NONE;
408 }
409
410 gboolean
411 __mmplayer_link_decoder( mm_player_t* player, GstPad *srcpad)
412 {
413         const gchar* name = NULL;
414         GstStructure* str = NULL;
415         GstCaps* srccaps = NULL;
416
417         debug_fenter();
418
419         return_val_if_fail( player, FALSE );
420         return_val_if_fail ( srcpad, FALSE );
421
422         /* to check any of the decoder (video/audio) need to be linked  to parser*/
423 #ifdef GST_API_VERSION_1
424         srccaps = gst_pad_get_current_caps( srcpad );
425 #else
426         srccaps = gst_pad_get_caps( srcpad );
427 #endif
428         if ( !srccaps )
429                 goto ERROR;
430
431         str = gst_caps_get_structure( srccaps, 0 );
432         if ( ! str )
433                 goto ERROR;
434
435         name = gst_structure_get_name(str);
436         if ( ! name )
437                 goto ERROR;
438
439         if (strstr(name, "video"))
440         {
441                 if(player->videodec_linked)
442                 {
443                     debug_msg("Video decoder already linked\n");
444                         return FALSE;
445                 }
446         }
447         if (strstr(name, "audio"))
448         {
449                 if(player->audiodec_linked)
450                 {
451                     debug_msg("Audio decoder already linked\n");
452                         return FALSE;
453                 }
454         }
455
456         gst_caps_unref( srccaps );
457
458         debug_fleave();
459
460         return TRUE;
461
462 ERROR:
463         if ( srccaps )
464                 gst_caps_unref( srccaps );
465
466         return FALSE;
467 }
468
469 gboolean
470 __mmplayer_link_sink( mm_player_t* player , GstPad *srcpad)
471 {
472         const gchar* name = NULL;
473         GstStructure* str = NULL;
474         GstCaps* srccaps = NULL;
475
476         debug_fenter();
477
478         return_val_if_fail ( player, FALSE );
479         return_val_if_fail ( srcpad, FALSE );
480
481         /* to check any of the decoder (video/audio) need to be linked  to parser*/
482 #ifdef GST_API_VERSION_1
483         srccaps = gst_pad_get_current_caps( srcpad );
484 #else
485         srccaps = gst_pad_get_caps( srcpad );
486 #endif
487         if ( !srccaps )
488                 goto ERROR;
489
490         str = gst_caps_get_structure( srccaps, 0 );
491         if ( ! str )
492                 goto ERROR;
493
494         name = gst_structure_get_name(str);
495         if ( ! name )
496                 goto ERROR;
497
498         if (strstr(name, "video"))
499         {
500                 if(player->videosink_linked)
501                 {
502                         debug_msg("Video Sink already linked\n");
503                         return FALSE;
504                 }
505         }
506         if (strstr(name, "audio"))
507         {
508                 if(player->audiosink_linked)
509                 {
510                         debug_msg("Audio Sink already linked\n");
511                         return FALSE;
512                 }
513         }
514         if (strstr(name, "text"))
515         {
516                 if(player->textsink_linked)
517                 {
518                         debug_msg("Text Sink already linked\n");
519                         return FALSE;
520                 }
521         }
522
523         gst_caps_unref( srccaps );
524
525         debug_fleave();
526
527         return TRUE;
528         //return (!player->videosink_linked || !player->audiosink_linked);
529
530 ERROR:
531         if ( srccaps )
532                 gst_caps_unref( srccaps );
533
534         return FALSE;
535 }
536
537 gint
538 __gst_handle_core_error( mm_player_t* player, int code )
539 {
540         gint trans_err = MM_ERROR_NONE;
541
542         debug_fenter();
543
544         return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
545
546         switch ( code )
547         {
548                 case GST_CORE_ERROR_STATE_CHANGE:
549                 case GST_CORE_ERROR_MISSING_PLUGIN:
550                 case GST_CORE_ERROR_SEEK:
551                 case GST_CORE_ERROR_NOT_IMPLEMENTED:
552                 case GST_CORE_ERROR_FAILED:
553                 case GST_CORE_ERROR_TOO_LAZY:
554                 case GST_CORE_ERROR_PAD:
555                 case GST_CORE_ERROR_THREAD:
556                 case GST_CORE_ERROR_NEGOTIATION:
557                 case GST_CORE_ERROR_EVENT:
558                 case GST_CORE_ERROR_CAPS:
559                 case GST_CORE_ERROR_TAG:
560                 case GST_CORE_ERROR_CLOCK:
561                 case GST_CORE_ERROR_DISABLED:
562                 default:
563                         trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
564                 break;
565         }
566
567         debug_fleave();
568
569         return trans_err;
570 }
571
572 gint
573 __gst_handle_library_error( mm_player_t* player, int code )
574 {
575         gint trans_err = MM_ERROR_NONE;
576
577         debug_fenter();
578
579         return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
580
581         switch ( code )
582         {
583                 case GST_LIBRARY_ERROR_FAILED:
584                 case GST_LIBRARY_ERROR_TOO_LAZY:
585                 case GST_LIBRARY_ERROR_INIT:
586                 case GST_LIBRARY_ERROR_SHUTDOWN:
587                 case GST_LIBRARY_ERROR_SETTINGS:
588                 case GST_LIBRARY_ERROR_ENCODE:
589                 default:
590                         trans_err =  MM_ERROR_PLAYER_INVALID_STREAM;
591                 break;
592         }
593
594         debug_fleave();
595
596         return trans_err;
597 }
598
599 gint
600 __gst_handle_resource_error( mm_player_t* player, int code )
601 {
602         gint trans_err = MM_ERROR_NONE;
603
604         debug_fenter();
605
606         return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
607
608         switch ( code )
609         {
610                 case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
611                         trans_err = MM_ERROR_PLAYER_NO_FREE_SPACE;
612                         break;
613                 case GST_RESOURCE_ERROR_NOT_FOUND:
614                 case GST_RESOURCE_ERROR_OPEN_READ:
615                         if ( MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_HTTP_LIVE_STREAMING ( player )
616                                 || MMPLAYER_IS_RTSP_STREAMING(player))
617                         {
618                                 trans_err = MM_ERROR_PLAYER_STREAMING_CONNECTION_FAIL;
619                                 break;
620                         }
621                 case GST_RESOURCE_ERROR_READ:
622                         if ( MMPLAYER_IS_HTTP_STREAMING(player) ||  MMPLAYER_IS_HTTP_LIVE_STREAMING ( player )
623                                 || MMPLAYER_IS_RTSP_STREAMING(player))
624                         {
625                                 trans_err = MM_ERROR_PLAYER_STREAMING_FAIL;
626                                 break;
627                         }
628                 case GST_RESOURCE_ERROR_WRITE:
629                 case GST_RESOURCE_ERROR_FAILED:
630                         trans_err = MM_ERROR_PLAYER_INTERNAL;
631                         break;
632
633                 case GST_RESOURCE_ERROR_SEEK:
634                 case GST_RESOURCE_ERROR_TOO_LAZY:
635                 case GST_RESOURCE_ERROR_BUSY:
636                 case GST_RESOURCE_ERROR_OPEN_WRITE:
637                 case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
638                 case GST_RESOURCE_ERROR_CLOSE:
639                 case GST_RESOURCE_ERROR_SYNC:
640                 case GST_RESOURCE_ERROR_SETTINGS:
641                 default:
642                         trans_err = MM_ERROR_PLAYER_FILE_NOT_FOUND;
643                 break;
644         }
645
646         debug_fleave();
647
648         return trans_err;
649 }
650
651 gint
652 __gst_handle_stream_error( mm_player_t* player, GError* error, GstMessage * message )
653 {
654         gint trans_err = MM_ERROR_NONE;
655
656         debug_fenter();
657
658         return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
659         return_val_if_fail( error, MM_ERROR_INVALID_ARGUMENT );
660         return_val_if_fail ( message, MM_ERROR_INVALID_ARGUMENT );
661
662         switch ( error->code )
663         {
664                 case GST_STREAM_ERROR_FAILED:
665                 case GST_STREAM_ERROR_TYPE_NOT_FOUND:
666                 case GST_STREAM_ERROR_DECODE:
667                 case GST_STREAM_ERROR_WRONG_TYPE:
668                 case GST_STREAM_ERROR_DECRYPT:
669                 case GST_STREAM_ERROR_DECRYPT_NOKEY:
670                          trans_err = __gst_transform_gsterror( player, message, error );
671                 break;
672
673                 case GST_STREAM_ERROR_CODEC_NOT_FOUND:
674                 case GST_STREAM_ERROR_NOT_IMPLEMENTED:
675                 case GST_STREAM_ERROR_TOO_LAZY:
676                 case GST_STREAM_ERROR_ENCODE:
677                 case GST_STREAM_ERROR_DEMUX:
678                 case GST_STREAM_ERROR_MUX:
679                 case GST_STREAM_ERROR_FORMAT:
680                 default:
681                         trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
682                 break;
683         }
684
685         debug_fleave();
686
687         return trans_err;
688 }
689
690 /* NOTE : decide gstreamer state whether there is some playable track or not. */
691 gint
692 __gst_transform_gsterror( mm_player_t* player, GstMessage * message, GError* error )
693 {
694         gchar *src_element_name = NULL;
695         GstElement *src_element = NULL;
696         GstElementFactory *factory = NULL;
697         const gchar* klass = NULL;
698
699         debug_fenter();
700
701         /* FIXIT */
702         return_val_if_fail ( message, MM_ERROR_INVALID_ARGUMENT );
703         return_val_if_fail ( message->src, MM_ERROR_INVALID_ARGUMENT );
704         return_val_if_fail ( error, MM_ERROR_INVALID_ARGUMENT );
705
706         src_element = GST_ELEMENT_CAST(message->src);
707         if ( !src_element )
708                 goto INTERNAL_ERROR;
709
710         src_element_name = GST_ELEMENT_NAME(src_element);
711         if ( !src_element_name )
712                 goto INTERNAL_ERROR;
713
714         factory = gst_element_get_factory(src_element);
715         if ( !factory )
716                 goto INTERNAL_ERROR;
717
718         klass = gst_element_factory_get_klass(factory);
719         if ( !klass )
720                 goto INTERNAL_ERROR;
721
722         debug_log("error code=%d, msg=%s, src element=%s, class=%s\n",
723                         error->code, error->message, src_element_name, klass);
724
725         switch ( error->code )
726         {
727                 case GST_STREAM_ERROR_DECODE:
728                 {
729                         /* Demuxer can't parse one track because it's corrupted.
730                          * So, the decoder for it is not linked.
731                          * But, it has one playable track.
732                          */
733                         if ( g_strrstr(klass, "Demux") )
734                         {
735                                 if ( player->can_support_codec == FOUND_PLUGIN_VIDEO )
736                                 {
737                                         return MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
738                                 }
739                                 else if ( player->can_support_codec == FOUND_PLUGIN_AUDIO )
740                                 {
741                                         return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
742                                 }
743                                 else
744                                 {
745                                         if ( player->pipeline->audiobin ) // PCM
746                                         {
747                                                 return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
748                                         }
749                                         else
750                                         {
751                                                 goto CODEC_NOT_FOUND;
752                                         }
753                                 }
754                         }
755                         return MM_ERROR_PLAYER_INVALID_STREAM;
756                 }
757                 break;
758
759                 case GST_STREAM_ERROR_WRONG_TYPE:
760                 {
761                         return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
762                 }
763                 break;
764
765                 case GST_STREAM_ERROR_FAILED:
766                 {
767                         /* Decoder Custom Message */
768                         if ( strstr(error->message, "ongoing") )
769                         {
770                                 if ( strncasecmp(klass, "audio", 5) )
771                                 {
772                                         if ( ( player->can_support_codec & FOUND_PLUGIN_VIDEO ) )
773                                         {
774                                                 debug_log("Video can keep playing.\n");
775                                                 return MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
776                                         }
777                                         else
778                                         {
779                                                 goto CODEC_NOT_FOUND;
780                                         }
781
782                                 }
783                                 else if ( strncasecmp(klass, "video", 5) )
784                                 {
785                                         if ( ( player->can_support_codec & FOUND_PLUGIN_AUDIO ) )
786                                         {
787                                                 debug_log("Audio can keep playing.\n");
788                                                 return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
789                                         }
790                                         else
791                                         {
792                                                 goto CODEC_NOT_FOUND;
793                                         }
794                                 }
795                         }
796                         return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
797                 }
798                 break;
799
800                 case GST_STREAM_ERROR_TYPE_NOT_FOUND:
801                         return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
802                 break;
803
804                 case GST_STREAM_ERROR_DECRYPT:
805                 case GST_STREAM_ERROR_DECRYPT_NOKEY:
806                 {
807                         debug_error("decryption error, [%s] failed, reason : [%s]\n", src_element_name, error->message);
808
809                         if ( strstr(error->message, "rights expired") )
810                         {
811                                 return MM_ERROR_PLAYER_DRM_EXPIRED;
812                         }
813                         else if ( strstr(error->message, "no rights") )
814                         {
815                                 return MM_ERROR_PLAYER_DRM_NO_LICENSE;
816                         }
817                         else if ( strstr(error->message, "has future rights") )
818                         {
819                                 return MM_ERROR_PLAYER_DRM_FUTURE_USE;
820                         }
821                         else if ( strstr(error->message, "opl violation") )
822                         {
823                                 return MM_ERROR_PLAYER_DRM_OUTPUT_PROTECTION;
824                         }
825                         return MM_ERROR_PLAYER_DRM_NOT_AUTHORIZED;
826                 }
827                 break;
828
829                 default:
830                 break;
831         }
832
833         debug_fleave();
834
835         return MM_ERROR_PLAYER_INVALID_STREAM;
836
837 INTERNAL_ERROR:
838         return MM_ERROR_PLAYER_INTERNAL;
839
840 CODEC_NOT_FOUND:
841         debug_log("not found any available codec. Player should be destroyed.\n");
842         return MM_ERROR_PLAYER_CODEC_NOT_FOUND;
843 }
844
845 gboolean
846 __mmplayer_handle_gst_error ( mm_player_t* player, GstMessage * message, GError* error )
847 {
848         MMMessageParamType msg_param;
849        gchar *msg_src_element;
850
851         debug_fenter();
852
853         return_val_if_fail( player, FALSE );
854         return_val_if_fail( error, FALSE );
855
856         /* NOTE : do somthing necessary inside of __gst_handle_XXX_error. not here */
857
858         memset (&msg_param, 0, sizeof(MMMessageParamType));
859
860         if ( error->domain == GST_CORE_ERROR )
861         {
862                 msg_param.code = __gst_handle_core_error( player, error->code );
863         }
864         else if ( error->domain == GST_LIBRARY_ERROR )
865         {
866                 msg_param.code = __gst_handle_library_error( player, error->code );
867         }
868         else if ( error->domain == GST_RESOURCE_ERROR )
869         {
870                 msg_param.code = __gst_handle_resource_error( player, error->code );
871         }
872         else if ( error->domain == GST_STREAM_ERROR )
873         {
874                 msg_param.code = __gst_handle_stream_error( player, error, message );
875         }
876         else
877         {
878                 debug_warning("This error domain is not defined.\n");
879
880                 /* we treat system error as an internal error */
881                 msg_param.code = MM_ERROR_PLAYER_INVALID_STREAM;
882         }
883
884         if ( message->src )
885         {
886                 msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( message->src ) );
887
888                 msg_param.data = (void *) error->message;
889
890                 debug_error("-Msg src : [%s]    Domain : [%s]   Error : [%s]  Code : [%d] is tranlated to error code : [0x%x]\n",
891                         msg_src_element, g_quark_to_string (error->domain), error->message, error->code, msg_param.code);
892         }
893
894         /* post error to application */
895         if ( ! player->msg_posted )
896         {
897                 MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
898                 /* don't post more if one was sent already */
899                 player->msg_posted = TRUE;
900         }
901         else
902         {
903                 debug_log("skip error post because it's sent already.\n");
904         }
905
906         debug_fleave();
907
908         return TRUE;
909 }
910
911 gboolean
912 __mmplayer_handle_streaming_error  ( mm_player_t* player, GstMessage * message )
913 {
914         debug_log("\n");
915         MMMessageParamType msg_param;
916         gchar *msg_src_element = NULL;
917         GstStructure *s = NULL;
918         guint error_id = 0;
919         gchar *error_string = NULL;
920
921         debug_fenter();
922
923         return_val_if_fail ( player, FALSE );
924         return_val_if_fail ( message, FALSE );
925
926         s = malloc( sizeof(GstStructure) );
927         memcpy ( s, gst_message_get_structure ( message ), sizeof(GstStructure));
928
929         if ( !gst_structure_get_uint (s, "error_id", &error_id) )
930                 error_id = MMPLAYER_STREAMING_ERROR_NONE;
931
932         switch ( error_id )
933         {
934                 case MMPLAYER_STREAMING_ERROR_UNSUPPORTED_AUDIO:
935                         msg_param.code = MM_ERROR_PLAYER_STREAMING_UNSUPPORTED_AUDIO;
936                         break;
937                 case MMPLAYER_STREAMING_ERROR_UNSUPPORTED_VIDEO:
938                         msg_param.code = MM_ERROR_PLAYER_STREAMING_UNSUPPORTED_VIDEO;
939                         break;
940                 case MMPLAYER_STREAMING_ERROR_CONNECTION_FAIL:
941                         msg_param.code = MM_ERROR_PLAYER_STREAMING_CONNECTION_FAIL;
942                         break;
943                 case MMPLAYER_STREAMING_ERROR_DNS_FAIL:
944                         msg_param.code = MM_ERROR_PLAYER_STREAMING_DNS_FAIL;
945                         break;
946                 case MMPLAYER_STREAMING_ERROR_SERVER_DISCONNECTED:
947                         msg_param.code = MM_ERROR_PLAYER_STREAMING_SERVER_DISCONNECTED;
948                         break;
949                 case MMPLAYER_STREAMING_ERROR_BAD_SERVER:
950                         msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_SERVER;
951                         break;
952                 case MMPLAYER_STREAMING_ERROR_INVALID_PROTOCOL:
953                         msg_param.code = MM_ERROR_PLAYER_STREAMING_INVALID_PROTOCOL;
954                         break;
955                 case MMPLAYER_STREAMING_ERROR_INVALID_URL:
956                         msg_param.code = MM_ERROR_PLAYER_STREAMING_INVALID_URL;
957                         break;
958                 case MMPLAYER_STREAMING_ERROR_UNEXPECTED_MSG:
959                         msg_param.code = MM_ERROR_PLAYER_STREAMING_UNEXPECTED_MSG;
960                         break;
961                 case MMPLAYER_STREAMING_ERROR_OUT_OF_MEMORIES:
962                         msg_param.code = MM_ERROR_PLAYER_STREAMING_OUT_OF_MEMORIES;
963                         break;
964                 case MMPLAYER_STREAMING_ERROR_RTSP_TIMEOUT:
965                         msg_param.code = MM_ERROR_PLAYER_STREAMING_RTSP_TIMEOUT;
966                         break;
967                 case MMPLAYER_STREAMING_ERROR_BAD_REQUEST:
968                         msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_REQUEST;
969                         break;
970                 case MMPLAYER_STREAMING_ERROR_NOT_AUTHORIZED:
971                         msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_AUTHORIZED;
972                         break;
973                 case MMPLAYER_STREAMING_ERROR_PAYMENT_REQUIRED:
974                         msg_param.code = MM_ERROR_PLAYER_STREAMING_PAYMENT_REQUIRED;
975                         break;
976                 case MMPLAYER_STREAMING_ERROR_FORBIDDEN:
977                         msg_param.code = MM_ERROR_PLAYER_STREAMING_FORBIDDEN;
978                         break;
979                 case MMPLAYER_STREAMING_ERROR_CONTENT_NOT_FOUND:
980                         msg_param.code = MM_ERROR_PLAYER_STREAMING_CONTENT_NOT_FOUND;
981                         break;
982                 case MMPLAYER_STREAMING_ERROR_METHOD_NOT_ALLOWED:
983                         msg_param.code = MM_ERROR_PLAYER_STREAMING_METHOD_NOT_ALLOWED;
984                         break;
985                 case MMPLAYER_STREAMING_ERROR_NOT_ACCEPTABLE:
986                         msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_ACCEPTABLE;
987                         break;
988                 case MMPLAYER_STREAMING_ERROR_PROXY_AUTHENTICATION_REQUIRED:
989                         msg_param.code = MM_ERROR_PLAYER_STREAMING_PROXY_AUTHENTICATION_REQUIRED;
990                         break;
991                 case MMPLAYER_STREAMING_ERROR_SERVER_TIMEOUT:
992                         msg_param.code = MM_ERROR_PLAYER_STREAMING_SERVER_TIMEOUT;
993                         break;
994                 case MMPLAYER_STREAMING_ERROR_GONE:
995                         msg_param.code = MM_ERROR_PLAYER_STREAMING_GONE;
996                         break;
997                 case MMPLAYER_STREAMING_ERROR_LENGTH_REQUIRED:
998                         msg_param.code = MM_ERROR_PLAYER_STREAMING_LENGTH_REQUIRED;
999                         break;
1000                 case MMPLAYER_STREAMING_ERROR_PRECONDITION_FAILED:
1001                         msg_param.code = MM_ERROR_PLAYER_STREAMING_PRECONDITION_FAILED;
1002                         break;
1003                 case MMPLAYER_STREAMING_ERROR_REQUEST_ENTITY_TOO_LARGE:
1004                         msg_param.code = MM_ERROR_PLAYER_STREAMING_REQUEST_ENTITY_TOO_LARGE;
1005                         break;
1006                 case MMPLAYER_STREAMING_ERROR_REQUEST_URI_TOO_LARGE:
1007                         msg_param.code = MM_ERROR_PLAYER_STREAMING_REQUEST_URI_TOO_LARGE;
1008                         break;
1009                 case MMPLAYER_STREAMING_ERROR_UNSUPPORTED_MEDIA_TYPE:
1010                         msg_param.code = MM_ERROR_PLAYER_STREAMING_UNSUPPORTED_MEDIA_TYPE;
1011                         break;
1012                 case MMPLAYER_STREAMING_ERROR_PARAMETER_NOT_UNDERSTOOD:
1013                         msg_param.code = MM_ERROR_PLAYER_STREAMING_PARAMETER_NOT_UNDERSTOOD;
1014                         break;
1015                 case MMPLAYER_STREAMING_ERROR_CONFERENCE_NOT_FOUND:
1016                         msg_param.code = MM_ERROR_PLAYER_STREAMING_CONFERENCE_NOT_FOUND;
1017                         break;
1018                 case MMPLAYER_STREAMING_ERROR_NOT_ENOUGH_BANDWIDTH:
1019                         msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_ENOUGH_BANDWIDTH;
1020                         break;
1021                 case MMPLAYER_STREAMING_ERROR_NO_SESSION_ID:
1022                         msg_param.code = MM_ERROR_PLAYER_STREAMING_NO_SESSION_ID;
1023                         break;
1024                 case MMPLAYER_STREAMING_ERROR_METHOD_NOT_VALID_IN_THIS_STATE:
1025                         msg_param.code = MM_ERROR_PLAYER_STREAMING_METHOD_NOT_VALID_IN_THIS_STATE;
1026                         break;
1027                 case MMPLAYER_STREAMING_ERROR_HEADER_FIELD_NOT_VALID_FOR_SOURCE:
1028                         msg_param.code = MM_ERROR_PLAYER_STREAMING_HEADER_FIELD_NOT_VALID_FOR_SOURCE;
1029                         break;
1030                 case MMPLAYER_STREAMING_ERROR_INVALID_RANGE:
1031                         msg_param.code = MM_ERROR_PLAYER_STREAMING_INVALID_RANGE;
1032                         break;
1033                 case MMPLAYER_STREAMING_ERROR_PARAMETER_IS_READONLY:
1034                         msg_param.code = MM_ERROR_PLAYER_STREAMING_PARAMETER_IS_READONLY;
1035                         break;
1036                 case MMPLAYER_STREAMING_ERROR_AGGREGATE_OP_NOT_ALLOWED:
1037                         msg_param.code = MM_ERROR_PLAYER_STREAMING_AGGREGATE_OP_NOT_ALLOWED;
1038                         break;
1039                 case MMPLAYER_STREAMING_ERROR_ONLY_AGGREGATE_OP_ALLOWED:
1040                         msg_param.code = MM_ERROR_PLAYER_STREAMING_ONLY_AGGREGATE_OP_ALLOWED;
1041                         break;
1042                 case MMPLAYER_STREAMING_ERROR_BAD_TRANSPORT:
1043                         msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_TRANSPORT;
1044                         break;
1045                 case MMPLAYER_STREAMING_ERROR_DESTINATION_UNREACHABLE:
1046                         msg_param.code = MM_ERROR_PLAYER_STREAMING_DESTINATION_UNREACHABLE;
1047                         break;
1048                 case MMPLAYER_STREAMING_ERROR_INTERNAL_SERVER_ERROR:
1049                         msg_param.code = MM_ERROR_PLAYER_STREAMING_INTERNAL_SERVER_ERROR;
1050                         break;
1051                 case MMPLAYER_STREAMING_ERROR_NOT_IMPLEMENTED:
1052                         msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_IMPLEMENTED;
1053                         break;
1054                 case MMPLAYER_STREAMING_ERROR_BAD_GATEWAY:
1055                         msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_GATEWAY;
1056                         break;
1057                 case MMPLAYER_STREAMING_ERROR_SERVICE_UNAVAILABLE:
1058                         msg_param.code = MM_ERROR_PLAYER_STREAMING_SERVICE_UNAVAILABLE;
1059                         break;
1060                 case MMPLAYER_STREAMING_ERROR_GATEWAY_TIME_OUT:
1061                         msg_param.code = MM_ERROR_PLAYER_STREAMING_GATEWAY_TIME_OUT;
1062                         break;
1063                 case MMPLAYER_STREAMING_ERROR_RTSP_VERSION_NOT_SUPPORTED:
1064                         msg_param.code = MM_ERROR_PLAYER_STREAMING_RTSP_VERSION_NOT_SUPPORTED;
1065                         break;
1066                 case MMPLAYER_STREAMING_ERROR_OPTION_NOT_SUPPORTED:
1067                         msg_param.code = MM_ERROR_PLAYER_STREAMING_OPTION_NOT_SUPPORTED;
1068                         break;
1069                 default:
1070                         return MM_ERROR_PLAYER_STREAMING_FAIL;
1071         }
1072
1073         error_string = g_strdup(gst_structure_get_string (s, "error_string"));
1074         if ( error_string )
1075                 msg_param.data = (void *) error_string;
1076
1077         if ( message->src )
1078         {
1079                 msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( message->src ) );
1080
1081                 debug_error("-Msg src : [%s] Code : [%x] Error : [%s]  \n",
1082                         msg_src_element, msg_param.code, (char*)msg_param.data );
1083         }
1084
1085         /* post error to application */
1086         if ( ! player->msg_posted )
1087         {
1088                 MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
1089
1090                 /* don't post more if one was sent already */
1091                 player->msg_posted = TRUE;
1092         }
1093         else
1094         {
1095                 debug_log("skip error post because it's sent already.\n");
1096         }
1097
1098         debug_fleave();
1099
1100         return TRUE;
1101
1102 }
1103
1104 void
1105 __mmplayer_add_sink( mm_player_t* player, GstElement* sink )
1106 {
1107         debug_fenter();
1108
1109         return_if_fail ( player );
1110         return_if_fail ( sink );
1111
1112         player->sink_elements =
1113                 g_list_append(player->sink_elements, sink);
1114
1115         debug_fleave();
1116 }
1117
1118 void
1119 __mmplayer_del_sink( mm_player_t* player, GstElement* sink )
1120 {
1121         debug_fenter();
1122
1123         return_if_fail ( player );
1124         return_if_fail ( sink );
1125
1126         player->sink_elements =
1127                         g_list_remove(player->sink_elements, sink);
1128
1129         debug_fleave();
1130 }
1131
1132 gboolean
1133 __is_rtsp_streaming ( mm_player_t* player )
1134 {
1135         return_val_if_fail ( player, FALSE );
1136
1137         return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_RTSP ) ? TRUE : FALSE;
1138 }
1139
1140 gboolean
1141 __is_http_streaming ( mm_player_t* player )
1142 {
1143         return_val_if_fail ( player, FALSE );
1144
1145         return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_HTTP ) ? TRUE : FALSE;
1146 }
1147
1148 gboolean
1149 __is_streaming ( mm_player_t* player )
1150 {
1151         return_val_if_fail ( player, FALSE );
1152
1153         return ( __is_rtsp_streaming ( player ) || __is_http_streaming ( player ) || __is_http_live_streaming ( player )) ? TRUE : FALSE;
1154 }
1155
1156 gboolean
1157 __is_live_streaming ( mm_player_t* player )
1158 {
1159         return_val_if_fail ( player, FALSE );
1160
1161         return ( __is_rtsp_streaming ( player ) && player->streaming_type == STREAMING_SERVICE_LIVE ) ? TRUE : FALSE;
1162 }
1163
1164 gboolean
1165 __is_http_live_streaming( mm_player_t* player )
1166 {
1167         return_val_if_fail( player, FALSE );
1168
1169         return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS ) ? TRUE : FALSE;
1170 }
1171
1172 gboolean
1173 __is_http_progressive_down(mm_player_t* player)
1174 {
1175         return_val_if_fail( player, FALSE );
1176
1177         return ((player->pd_mode) ? TRUE:FALSE);
1178 }
1179