4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>,
7 * Seungbae Shin <seungbae.shin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 /*===========================================================================================
27 ========================================================================================== */
29 #include <gst/wayland/wayland.h>
31 #include <gst/video/videooverlay.h>
35 #include <mm_attrs_private.h>
37 #include "mm_player_priv.h"
38 #include "mm_player_attrs.h"
39 #include "mm_player_utils.h"
41 /*===========================================================================================
43 | LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE |
45 ========================================================================================== */
47 /*---------------------------------------------------------------------------
48 | GLOBAL CONSTANT DEFINITIONS: |
49 ---------------------------------------------------------------------------*/
51 /*---------------------------------------------------------------------------
52 | IMPORTED VARIABLE DECLARATIONS: |
53 ---------------------------------------------------------------------------*/
55 /*---------------------------------------------------------------------------
56 | IMPORTED FUNCTION DECLARATIONS: |
57 ---------------------------------------------------------------------------*/
59 /*---------------------------------------------------------------------------
61 ---------------------------------------------------------------------------*/
63 /*---------------------------------------------------------------------------
64 | LOCAL CONSTANT DEFINITIONS: |
65 ---------------------------------------------------------------------------*/
67 /*---------------------------------------------------------------------------
68 | LOCAL DATA TYPE DEFINITIONS: |
69 ---------------------------------------------------------------------------*/
71 /*---------------------------------------------------------------------------
72 | GLOBAL VARIABLE DEFINITIONS: |
73 ---------------------------------------------------------------------------*/
75 /*---------------------------------------------------------------------------
76 | LOCAL VARIABLE DEFINITIONS: |
77 ---------------------------------------------------------------------------*/
79 /*---------------------------------------------------------------------------
80 | LOCAL FUNCTION PROTOTYPES: |
81 ---------------------------------------------------------------------------*/
82 static gint __gst_transform_gsterror( mm_player_t* player, GstMessage * message, GError* error);
84 /*===========================================================================================
86 | FUNCTION DEFINITIONS |
88 ========================================================================================== */
90 __mmplayer_check_state(mm_player_t* player, enum PlayerCommandState command)
92 MMPlayerStateType current_state = MM_PLAYER_STATE_NUM;
93 MMPlayerStateType pending_state = MM_PLAYER_STATE_NUM;
95 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
97 //LOGD("incomming command : %d \n", command );
99 current_state = MMPLAYER_CURRENT_STATE(player);
100 pending_state = MMPLAYER_PENDING_STATE(player);
102 MMPLAYER_PRINT_STATE(player);
106 case MMPLAYER_COMMAND_CREATE:
108 MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_NULL;
110 if ( current_state == MM_PLAYER_STATE_NULL ||
111 current_state == MM_PLAYER_STATE_READY ||
112 current_state == MM_PLAYER_STATE_PAUSED ||
113 current_state == MM_PLAYER_STATE_PLAYING )
118 case MMPLAYER_COMMAND_DESTROY:
120 /* destroy can called anytime */
122 MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_NONE;
126 case MMPLAYER_COMMAND_REALIZE:
128 MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_READY;
130 if ( pending_state != MM_PLAYER_STATE_NONE )
136 /* need ready state to realize */
137 if ( current_state == MM_PLAYER_STATE_READY )
140 if ( current_state != MM_PLAYER_STATE_NULL )
146 case MMPLAYER_COMMAND_UNREALIZE:
148 MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_NULL;
150 if ( current_state == MM_PLAYER_STATE_NULL )
155 case MMPLAYER_COMMAND_START:
157 MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PLAYING;
159 if ( pending_state == MM_PLAYER_STATE_NONE )
161 if ( current_state == MM_PLAYER_STATE_PLAYING )
163 else if ( current_state != MM_PLAYER_STATE_READY &&
164 current_state != MM_PLAYER_STATE_PAUSED )
167 else if ( pending_state == MM_PLAYER_STATE_PLAYING )
171 else if ( pending_state == MM_PLAYER_STATE_PAUSED )
173 LOGD("player is going to paused state, just change the pending state as playing");
182 case MMPLAYER_COMMAND_STOP:
184 MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_READY;
186 if ( current_state == MM_PLAYER_STATE_READY )
189 /* need playing/paused state to stop */
190 if ( current_state != MM_PLAYER_STATE_PLAYING &&
191 current_state != MM_PLAYER_STATE_PAUSED )
196 case MMPLAYER_COMMAND_PAUSE:
198 if ( MMPLAYER_IS_LIVE_STREAMING( player ) )
201 if (player->doing_seek)
202 goto NOT_COMPLETED_SEEK;
204 MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PAUSED;
206 if ( pending_state == MM_PLAYER_STATE_NONE )
208 if ( current_state == MM_PLAYER_STATE_PAUSED )
210 else if ( current_state != MM_PLAYER_STATE_PLAYING && current_state != MM_PLAYER_STATE_READY ) // support loading state of broswer
213 else if ( pending_state == MM_PLAYER_STATE_PAUSED )
217 else if ( pending_state == MM_PLAYER_STATE_PLAYING )
219 if ( current_state == MM_PLAYER_STATE_PAUSED ) {
220 LOGD("player is PAUSED going to PLAYING, just change the pending state as PAUSED");
228 case MMPLAYER_COMMAND_RESUME:
231 if (player->doing_seek)
232 goto NOT_COMPLETED_SEEK;
234 MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PLAYING;
236 if ( pending_state == MM_PLAYER_STATE_NONE )
238 if ( current_state == MM_PLAYER_STATE_PLAYING )
240 else if ( current_state != MM_PLAYER_STATE_PAUSED )
243 else if ( pending_state == MM_PLAYER_STATE_PLAYING )
247 else if ( pending_state == MM_PLAYER_STATE_PAUSED )
249 LOGD("player is going to paused state, just change the pending state as playing");
261 player->cmd = command;
263 return MM_ERROR_NONE;
266 LOGW("since player is in wrong state(%s). it's not able to apply the command(%d)",
267 MMPLAYER_STATE_GET_NAME(current_state), command);
268 return MM_ERROR_PLAYER_INVALID_STATE;
271 LOGW("not completed seek");
272 return MM_ERROR_PLAYER_DOING_SEEK;
275 LOGW("player is in the desired state(%s). doing noting", MMPLAYER_STATE_GET_NAME(current_state));
276 return MM_ERROR_PLAYER_NO_OP;
279 LOGW("player is already going to %s, doing nothing", MMPLAYER_STATE_GET_NAME(pending_state));
280 return MM_ERROR_PLAYER_NO_OP;
284 __mmplayer_gst_set_state (mm_player_t* player, GstElement * element, GstState state, gboolean async, gint timeout)
286 GstState element_state = GST_STATE_VOID_PENDING;
287 GstState element_pending_state = GST_STATE_VOID_PENDING;
288 GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
292 MMPLAYER_RETURN_VAL_IF_FAIL ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
293 MMPLAYER_RETURN_VAL_IF_FAIL ( element, MM_ERROR_INVALID_ARGUMENT );
295 LOGD("setting [%s] element state to : %s\n", GST_ELEMENT_NAME(element), gst_element_state_get_name(state));
298 ret = gst_element_set_state(element, state);
300 if ( ret == GST_STATE_CHANGE_FAILURE )
302 LOGE("failed to set [%s] state\n", GST_ELEMENT_NAME(element));
304 /* dump state of all element */
305 __mmplayer_dump_pipeline_state( player );
307 return MM_ERROR_PLAYER_INTERNAL;
310 /* return here so state transition to be done in async mode */
313 LOGD("async state transition. not waiting for state complete.\n");
314 return MM_ERROR_NONE;
317 /* wait for state transition */
318 ret = gst_element_get_state( element, &element_state, &element_pending_state, timeout * GST_SECOND );
320 if ( ret == GST_STATE_CHANGE_FAILURE || ( state != element_state ) )
322 LOGE("failed to change [%s] element state to [%s] within %d sec\n",
323 GST_ELEMENT_NAME(element),
324 gst_element_state_get_name(state), timeout );
326 LOGE(" [%s] state : %s pending : %s \n",
327 GST_ELEMENT_NAME(element),
328 gst_element_state_get_name(element_state),
329 gst_element_state_get_name(element_pending_state) );
331 /* dump state of all element */
332 __mmplayer_dump_pipeline_state( player );
334 return MM_ERROR_PLAYER_INTERNAL;
337 LOGD("[%s] element state has changed\n", GST_ELEMENT_NAME(element));
341 return MM_ERROR_NONE;
344 void __mmplayer_remove_g_source_from_context(GMainContext *context, guint source_id)
346 GSource *source = NULL;
350 source = g_main_context_find_source_by_id (context, source_id);
354 LOGW("context: %p, source id: %d, source: %p", context, source_id, source);
355 g_source_destroy(source);
362 __mmplayer_dump_pipeline_state( mm_player_t* player )
364 GstIterator*iter = NULL;
365 gboolean done = FALSE;
368 GstElement *element = NULL;
369 GstElementFactory *factory = NULL;
371 GstState state = GST_STATE_VOID_PENDING;
372 GstState pending = GST_STATE_VOID_PENDING;
373 GstClockTime time = 200*GST_MSECOND;
377 MMPLAYER_RETURN_VAL_IF_FAIL ( player &&
379 player->pipeline->mainbin,
382 iter = gst_bin_iterate_recurse(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst) );
387 switch ( gst_iterator_next (iter, &item) )
389 case GST_ITERATOR_OK:
390 element = g_value_get_object(&item);
391 gst_element_get_state(element,&state, &pending,time);
393 factory = gst_element_get_factory (element) ;
396 LOGE("%s:%s : From:%s To:%s refcount : %d\n", GST_OBJECT_NAME(factory) , GST_ELEMENT_NAME(element) ,
397 gst_element_state_get_name(state), gst_element_state_get_name(pending) , GST_OBJECT_REFCOUNT_VALUE(element));
399 g_value_reset (&item);
401 case GST_ITERATOR_RESYNC:
402 gst_iterator_resync (iter);
404 case GST_ITERATOR_ERROR:
407 case GST_ITERATOR_DONE:
414 element = GST_ELEMENT(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
416 gst_element_get_state(element,&state, &pending,time);
418 factory = gst_element_get_factory (element) ;
422 LOGE("%s:%s : From:%s To:%s refcount : %d\n",
423 GST_OBJECT_NAME(factory),
424 GST_ELEMENT_NAME(element),
425 gst_element_state_get_name(state),
426 gst_element_state_get_name(pending),
427 GST_OBJECT_REFCOUNT_VALUE(element) );
430 g_value_unset(&item);
433 gst_iterator_free (iter);
441 __get_state_name ( int state )
445 case MM_PLAYER_STATE_NULL:
447 case MM_PLAYER_STATE_READY:
449 case MM_PLAYER_STATE_PAUSED:
451 case MM_PLAYER_STATE_PLAYING:
453 case MM_PLAYER_STATE_NONE:
461 __is_rtsp_streaming ( mm_player_t* player )
463 MMPLAYER_RETURN_VAL_IF_FAIL ( player, FALSE );
465 return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_RTSP ) ? TRUE : FALSE;
469 __is_wfd_streaming ( mm_player_t* player )
471 MMPLAYER_RETURN_VAL_IF_FAIL ( player, FALSE );
473 return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_WFD ) ? TRUE : FALSE;
477 __is_http_streaming ( mm_player_t* player )
479 MMPLAYER_RETURN_VAL_IF_FAIL ( player, FALSE );
481 return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_HTTP ) ? TRUE : FALSE;
485 __is_streaming ( mm_player_t* player )
487 MMPLAYER_RETURN_VAL_IF_FAIL ( player, FALSE );
489 return ( __is_http_progressive_down( player ) || __is_rtsp_streaming ( player ) || __is_wfd_streaming ( player ) || __is_http_streaming ( player )
490 || __is_http_live_streaming ( player ) || __is_dash_streaming ( player ) || __is_smooth_streaming(player) ) ? TRUE : FALSE;
494 __is_live_streaming ( mm_player_t* player )
496 MMPLAYER_RETURN_VAL_IF_FAIL ( player, FALSE );
498 return ( __is_rtsp_streaming ( player ) && player->streaming_type == STREAMING_SERVICE_LIVE ) ? TRUE : FALSE;
502 __is_http_live_streaming( mm_player_t* player )
504 MMPLAYER_RETURN_VAL_IF_FAIL( player, FALSE );
506 return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS ) ? TRUE : FALSE;
510 __is_dash_streaming ( mm_player_t* player )
512 MMPLAYER_RETURN_VAL_IF_FAIL ( player, FALSE );
514 return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_DASH ) ? TRUE : FALSE;
518 __is_smooth_streaming ( mm_player_t* player )
520 MMPLAYER_RETURN_VAL_IF_FAIL ( player, FALSE );
522 return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_SS ) ? TRUE : FALSE;
527 __is_http_progressive_down(mm_player_t* player)
529 MMPLAYER_RETURN_VAL_IF_FAIL( player, FALSE );
531 return ((player->pd_mode) ? TRUE:FALSE);
534 /* if retval is FALSE, it will be dropped for perfomance. */
536 __mmplayer_check_useful_message(mm_player_t *player, GstMessage * message)
538 gboolean retval = FALSE;
540 if ( !(player->pipeline && player->pipeline->mainbin) )
542 LOGE("player pipeline handle is null");
546 switch (GST_MESSAGE_TYPE (message))
548 case GST_MESSAGE_TAG:
549 case GST_MESSAGE_EOS:
550 case GST_MESSAGE_ERROR:
551 case GST_MESSAGE_WARNING:
552 case GST_MESSAGE_CLOCK_LOST:
553 case GST_MESSAGE_NEW_CLOCK:
554 case GST_MESSAGE_ELEMENT:
555 case GST_MESSAGE_DURATION_CHANGED:
556 case GST_MESSAGE_ASYNC_START:
559 case GST_MESSAGE_ASYNC_DONE:
560 case GST_MESSAGE_STATE_CHANGED:
561 /* we only handle messages from pipeline */
562 if(( message->src == (GstObject *)player->pipeline->mainbin[MMPLAYER_M_PIPE].gst ) && (!player->gapless.reconfigure))
567 case GST_MESSAGE_BUFFERING:
569 gint buffer_percent = 0;
571 gst_message_parse_buffering (message, &buffer_percent);
573 if ((MMPLAYER_IS_STREAMING(player)) &&
574 (player->streamer) &&
575 (player->streamer->is_buffering == TRUE) &&
576 (buffer_percent == MAX_BUFFER_PERCENT))
578 LOGD (">>> [%s] Buffering DONE is detected !!\n", GST_OBJECT_NAME(GST_MESSAGE_SRC(message)));
579 player->streamer->is_buffering_done = TRUE;
594 __mmplayer_post_message(mm_player_t* player, enum MMMessageType msgtype, MMMessageParamType* param)
596 MMPLAYER_RETURN_VAL_IF_FAIL( player, FALSE );
598 if ( !player->msg_cb )
603 //LOGD("Message (type : %d) will be posted using msg-cb(%p). \n", msgtype, player->msg_cb);
605 player->msg_cb(msgtype, param, player->msg_cb_param);
611 __mmplayer_handle_gst_error ( mm_player_t* player, GstMessage * message, GError* error )
613 MMMessageParamType msg_param;
614 gchar *msg_src_element;
618 MMPLAYER_RETURN_VAL_IF_FAIL( player, FALSE );
619 MMPLAYER_RETURN_VAL_IF_FAIL( error, FALSE );
621 /* NOTE : do somthing necessary inside of __gst_handle_XXX_error. not here */
623 memset (&msg_param, 0, sizeof(MMMessageParamType));
625 if ( error->domain == GST_CORE_ERROR )
627 msg_param.code = __gst_handle_core_error( player, error->code );
629 else if ( error->domain == GST_LIBRARY_ERROR )
631 msg_param.code = __gst_handle_library_error( player, error->code );
633 else if ( error->domain == GST_RESOURCE_ERROR )
635 msg_param.code = __gst_handle_resource_error( player, error->code );
637 else if ( error->domain == GST_STREAM_ERROR )
639 msg_param.code = __gst_handle_stream_error( player, error, message );
643 LOGW("This error domain is not defined.\n");
645 /* we treat system error as an internal error */
646 msg_param.code = MM_ERROR_PLAYER_INVALID_STREAM;
651 msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( message->src ) );
653 msg_param.data = (void *) error->message;
655 LOGE("-Msg src : [%s] Domain : [%s] Error : [%s] Code : [%d] is tranlated to error code : [0x%x]\n",
656 msg_src_element, g_quark_to_string (error->domain), error->message, error->code, msg_param.code);
660 if (msg_param.code == MM_ERROR_NONE)
663 /* post error to application */
664 if ( ! player->msg_posted )
666 MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
667 /* don't post more if one was sent already */
668 player->msg_posted = TRUE;
672 LOGD("skip error post because it's sent already.\n");
681 __gst_handle_core_error( mm_player_t* player, int code )
683 gint trans_err = MM_ERROR_NONE;
687 MMPLAYER_RETURN_VAL_IF_FAIL( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
691 case GST_CORE_ERROR_MISSING_PLUGIN:
692 return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
693 case GST_CORE_ERROR_STATE_CHANGE:
694 case GST_CORE_ERROR_SEEK:
695 case GST_CORE_ERROR_NOT_IMPLEMENTED:
696 case GST_CORE_ERROR_FAILED:
697 case GST_CORE_ERROR_TOO_LAZY:
698 case GST_CORE_ERROR_PAD:
699 case GST_CORE_ERROR_THREAD:
700 case GST_CORE_ERROR_NEGOTIATION:
701 case GST_CORE_ERROR_EVENT:
702 case GST_CORE_ERROR_CAPS:
703 case GST_CORE_ERROR_TAG:
704 case GST_CORE_ERROR_CLOCK:
705 case GST_CORE_ERROR_DISABLED:
707 trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
717 __gst_handle_library_error( mm_player_t* player, int code )
719 gint trans_err = MM_ERROR_NONE;
723 MMPLAYER_RETURN_VAL_IF_FAIL( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
727 case GST_LIBRARY_ERROR_FAILED:
728 case GST_LIBRARY_ERROR_TOO_LAZY:
729 case GST_LIBRARY_ERROR_INIT:
730 case GST_LIBRARY_ERROR_SHUTDOWN:
731 case GST_LIBRARY_ERROR_SETTINGS:
732 case GST_LIBRARY_ERROR_ENCODE:
734 trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
744 __gst_handle_resource_error( mm_player_t* player, int code )
746 gint trans_err = MM_ERROR_NONE;
750 MMPLAYER_RETURN_VAL_IF_FAIL( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
754 case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
755 trans_err = MM_ERROR_PLAYER_NO_FREE_SPACE;
757 case GST_RESOURCE_ERROR_NOT_FOUND:
758 case GST_RESOURCE_ERROR_OPEN_READ:
759 if ( MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_HTTP_LIVE_STREAMING ( player )
760 || MMPLAYER_IS_RTSP_STREAMING(player))
762 trans_err = MM_ERROR_PLAYER_STREAMING_CONNECTION_FAIL;
765 case GST_RESOURCE_ERROR_READ:
766 if ( MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_HTTP_LIVE_STREAMING ( player )
767 || MMPLAYER_IS_RTSP_STREAMING(player))
769 trans_err = MM_ERROR_PLAYER_STREAMING_FAIL;
772 case GST_RESOURCE_ERROR_WRITE:
773 case GST_RESOURCE_ERROR_FAILED:
774 case GST_RESOURCE_ERROR_SEEK:
775 case GST_RESOURCE_ERROR_TOO_LAZY:
776 case GST_RESOURCE_ERROR_BUSY:
777 case GST_RESOURCE_ERROR_OPEN_WRITE:
778 case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
779 case GST_RESOURCE_ERROR_CLOSE:
780 case GST_RESOURCE_ERROR_SYNC:
781 case GST_RESOURCE_ERROR_SETTINGS:
783 trans_err = MM_ERROR_PLAYER_INTERNAL;
793 __gst_handle_stream_error( mm_player_t* player, GError* error, GstMessage * message )
795 gint trans_err = MM_ERROR_NONE;
799 MMPLAYER_RETURN_VAL_IF_FAIL( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
800 MMPLAYER_RETURN_VAL_IF_FAIL( error, MM_ERROR_INVALID_ARGUMENT );
801 MMPLAYER_RETURN_VAL_IF_FAIL ( message, MM_ERROR_INVALID_ARGUMENT );
803 switch ( error->code )
805 case GST_STREAM_ERROR_FAILED:
806 case GST_STREAM_ERROR_TYPE_NOT_FOUND:
807 case GST_STREAM_ERROR_DECODE:
808 case GST_STREAM_ERROR_WRONG_TYPE:
809 case GST_STREAM_ERROR_DECRYPT:
810 case GST_STREAM_ERROR_DECRYPT_NOKEY:
811 case GST_STREAM_ERROR_CODEC_NOT_FOUND:
812 trans_err = __gst_transform_gsterror( player, message, error );
815 case GST_STREAM_ERROR_NOT_IMPLEMENTED:
816 case GST_STREAM_ERROR_TOO_LAZY:
817 case GST_STREAM_ERROR_ENCODE:
818 case GST_STREAM_ERROR_DEMUX:
819 case GST_STREAM_ERROR_MUX:
820 case GST_STREAM_ERROR_FORMAT:
822 trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
831 /* NOTE : decide gstreamer state whether there is some playable track or not. */
833 __gst_transform_gsterror( mm_player_t* player, GstMessage * message, GError* error )
835 gchar *src_element_name = NULL;
836 GstElement *src_element = NULL;
837 GstElementFactory *factory = NULL;
838 const gchar* klass = NULL;
842 MMPLAYER_RETURN_VAL_IF_FAIL ( message, MM_ERROR_INVALID_ARGUMENT );
843 MMPLAYER_RETURN_VAL_IF_FAIL ( message->src, MM_ERROR_INVALID_ARGUMENT );
844 MMPLAYER_RETURN_VAL_IF_FAIL ( error, MM_ERROR_INVALID_ARGUMENT );
846 src_element = GST_ELEMENT_CAST(message->src);
850 src_element_name = GST_ELEMENT_NAME(src_element);
851 if ( !src_element_name )
854 factory = gst_element_get_factory(src_element);
858 klass = gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
862 LOGD("error code=%d, msg=%s, src element=%s, class=%s\n",
863 error->code, error->message, src_element_name, klass);
867 if (player->pipeline->mainbin[MMPLAYER_M_A_INPUT_SELECTOR].gst) {
869 gint active_pad_index = player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].active_pad_index;
870 LOGD ("current active pad index -%d", active_pad_index);
872 if (src_element_name) {
875 if (player->audio_decoders) {
876 GList *adec = player->audio_decoders;
877 for ( ;adec ; adec = g_list_next(adec)) {
878 gchar *name = adec->data;
880 LOGD("found audio decoder name = %s", name);
881 if (g_strrstr(name, src_element_name)) {
888 LOGD("active pad = %d, error src index = %d", active_pad_index, msg_src_pos);
891 if (active_pad_index != msg_src_pos) {
892 LOGD("skip error because error is posted from no activated track");
893 return MM_ERROR_NONE;
897 //-> check!! if needed or not
899 switch ( error->code )
901 case GST_STREAM_ERROR_DECODE:
903 /* Demuxer can't parse one track because it's corrupted.
904 * So, the decoder for it is not linked.
905 * But, it has one playable track.
907 if ( g_strrstr(klass, "Demux") )
909 if ( player->can_support_codec == FOUND_PLUGIN_VIDEO )
911 return MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
913 else if ( player->can_support_codec == FOUND_PLUGIN_AUDIO )
915 return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
919 if ( player->pipeline->audiobin ) // PCM
921 return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
925 goto CODEC_NOT_FOUND;
929 return MM_ERROR_PLAYER_INVALID_STREAM;
933 case GST_STREAM_ERROR_CODEC_NOT_FOUND:
934 case GST_STREAM_ERROR_TYPE_NOT_FOUND:
935 case GST_STREAM_ERROR_WRONG_TYPE:
936 return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
938 case GST_STREAM_ERROR_FAILED:
940 /* Decoder Custom Message */
941 if ( strstr(error->message, "ongoing") )
943 if ( strncasecmp(klass, "audio", 5) )
945 if ( ( player->can_support_codec & FOUND_PLUGIN_VIDEO ) )
947 LOGD("Video can keep playing.\n");
948 return MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
952 goto CODEC_NOT_FOUND;
956 else if ( strncasecmp(klass, "video", 5) )
958 if ( ( player->can_support_codec & FOUND_PLUGIN_AUDIO ) )
960 LOGD("Audio can keep playing.\n");
961 return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
965 goto CODEC_NOT_FOUND;
969 return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
973 case GST_STREAM_ERROR_DECRYPT:
974 case GST_STREAM_ERROR_DECRYPT_NOKEY:
976 LOGE("decryption error, [%s] failed, reason : [%s]\n", src_element_name, error->message);
978 if ( strstr(error->message, "rights expired") )
980 return MM_ERROR_PLAYER_DRM_EXPIRED;
982 else if ( strstr(error->message, "no rights") )
984 return MM_ERROR_PLAYER_DRM_NO_LICENSE;
986 else if ( strstr(error->message, "has future rights") )
988 return MM_ERROR_PLAYER_DRM_FUTURE_USE;
990 else if ( strstr(error->message, "opl violation") )
992 return MM_ERROR_PLAYER_DRM_OUTPUT_PROTECTION;
994 return MM_ERROR_PLAYER_DRM_NOT_AUTHORIZED;
1004 return MM_ERROR_PLAYER_INVALID_STREAM;
1007 return MM_ERROR_PLAYER_INTERNAL;
1010 LOGD("not found any available codec. Player should be destroyed.\n");
1011 return MM_ERROR_PLAYER_CODEC_NOT_FOUND;
1015 __mmplayer_get_video_angle(mm_player_t* player, int *user_angle, int *org_angle)
1017 int user_angle_type= 0;
1018 gchar *org_orient = NULL;
1019 MMHandleType attrs = MMPLAYER_GET_ATTRS(player);
1023 LOGE("cannot get content attribute");
1024 return MM_ERROR_PLAYER_INTERNAL;
1027 /* update user roation */
1028 mm_attrs_get_int_by_name(attrs, "display_rotation", &user_angle_type);
1030 /* get angle with user type */
1031 switch(user_angle_type)
1033 case MM_DISPLAY_ROTATION_NONE:
1036 case MM_DISPLAY_ROTATION_90: // counter-clockwise 90
1039 case MM_DISPLAY_ROTATION_180:
1042 case MM_DISPLAY_ROTATION_270: // clockwise 90
1047 /* get original orientation */
1048 mm_attrs_get_string_by_name(attrs, "content_video_orientation", &org_orient);
1052 if (!strcmp (org_orient, "rotate-90"))
1054 else if (!strcmp (org_orient, "rotate-180"))
1056 else if (!strcmp (org_orient, "rotate-270"))
1059 LOGD ("original rotation is %s", org_orient);
1063 LOGD ("content_video_orientation get fail");
1066 LOGD("check user angle: %d, orientation: %d", *user_angle, *org_angle);
1068 return MM_ERROR_NONE;