[v0.6.11] add buffer status cb lock and check state transition when unrealize 44/96144/1 accepted/tizen/common/20161109.140304 accepted/tizen/ivi/20161109.002844 accepted/tizen/mobile/20161109.002552 accepted/tizen/tv/20161109.002711 accepted/tizen/wearable/20161109.002800 submit/tizen/20161108.054351
authorEunhae Choi <eunhae1.choi@samsung.com>
Tue, 8 Nov 2016 04:29:27 +0000 (13:29 +0900)
committerEunhae Choi <eunhae1.choi@samsung.com>
Tue, 8 Nov 2016 04:29:27 +0000 (13:29 +0900)
Change-Id: I5926265317fa85fbdf14f28c2508bb034b6c384b

packaging/libmm-player.spec
src/include/mm_player_priv.h
src/include/mm_player_utils.h
src/mm_player_es.c
src/mm_player_priv.c

index db00eb7..90bde7d 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-player
 Summary:    Multimedia Framework Player Library
-Version:    0.6.10
+Version:    0.6.11
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index f5ddcfb..c223dc1 100644 (file)
@@ -511,6 +511,8 @@ typedef struct {
        guint media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_MAX];
        mm_player_media_stream_buffer_status_callback media_stream_buffer_status_cb[MM_PLAYER_STREAM_TYPE_MAX];
        mm_player_media_stream_seek_data_callback media_stream_seek_data_cb[MM_PLAYER_STREAM_TYPE_MAX];
+       GMutex media_stream_cb_lock;
+
        int video_num_buffers;  /* total num of buffers in vcodec */
        int video_extra_num_buffers; /* extra num of buffers in vcodec */
 
index ee2a5e2..4249afe 100644 (file)
@@ -92,6 +92,10 @@ x = NULL;
 #define MMPLAYER_VIDEO_BO_WAIT_UNTIL(x_player, end_time)     g_cond_wait_until(&((mm_player_t *)x_player)->video_bo_cond, &((mm_player_t *)x_player)->video_bo_mutex, end_time);
 #define MMPLAYER_VIDEO_BO_SIGNAL(x_player)                   g_cond_signal(&((mm_player_t *)x_player)->video_bo_cond);
 
+/* media stream lock */
+#define MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(x_player)        g_mutex_lock(&((mm_player_t *)x_player)->media_stream_cb_lock)
+#define MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(x_player)      g_mutex_unlock(&((mm_player_t *)x_player)->media_stream_cb_lock)
+
 #if 0
 #define MMPLAYER_FENTER();                                     LOGD("<ENTER>");
 #define MMPLAYER_FLEAVE();                                     LOGD("<LEAVE>");
index ef61f83..6db1e11 100644 (file)
@@ -198,6 +198,8 @@ _mmplayer_set_media_stream_buffer_status_cb(MMHandleType hplayer,
        if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
                return MM_ERROR_INVALID_ARGUMENT;
 
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
+
        if (player->media_stream_buffer_status_cb[type]) {
                if (!callback)
                        LOGD("[type:%d] will be clear.\n", type);
@@ -210,6 +212,7 @@ _mmplayer_set_media_stream_buffer_status_cb(MMHandleType hplayer,
 
        LOGD("player handle %p, type %d, callback %p\n", player, type,
                player->media_stream_buffer_status_cb[type]);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
 
        MMPLAYER_FLEAVE();
 
@@ -230,6 +233,7 @@ _mmplayer_set_media_stream_seek_data_cb(MMHandleType hplayer,
 
        if ((type < MM_PLAYER_STREAM_TYPE_DEFAULT) || (type > MM_PLAYER_STREAM_TYPE_TEXT))
                return MM_ERROR_INVALID_ARGUMENT;
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
 
        if (player->media_stream_seek_data_cb[type]) {
                if (!callback)
@@ -243,6 +247,7 @@ _mmplayer_set_media_stream_seek_data_cb(MMHandleType hplayer,
 
        LOGD("player handle %p, type %d, callback %p\n", player, type,
                player->media_stream_seek_data_cb[type]);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
 
        MMPLAYER_FLEAVE();
 
@@ -399,8 +404,11 @@ __mmplayer_check_buffer_level(mm_player_t *player, GstElement* element, MMPlayer
        }
 
        if (MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING) {
-               if (!player->media_stream_buffer_status_cb[type])
+               MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
+               if (!player->media_stream_buffer_status_cb[type]) {
+                       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
                        return MM_ERROR_NONE;
+               }
 
                current_level_per = (guint)(gst_util_guint64_to_gdouble(current_level_bytes)/gst_util_guint64_to_gdouble(max_bytes)*100);
 
@@ -412,6 +420,8 @@ __mmplayer_check_buffer_level(mm_player_t *player, GstElement* element, MMPlayer
 
                if (current_level_per < player->media_stream_buffer_min_percent[type])
                        player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param);
+
+               MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
        }
 
        MMPLAYER_FLEAVE();
@@ -437,7 +447,7 @@ _mmplayer_submit_packet(MMHandleType hplayer, media_packet_h packet)
        player->pipeline &&
        player->pipeline->mainbin &&
        player->pipeline->mainbin[MMPLAYER_M_SRC].gst,
-       MM_ERROR_PLAYER_INTERNAL);
+       MM_ERROR_PLAYER_NOT_INITIALIZED);
 
        /* get stream type if audio or video */
        media_packet_is_audio(packet, &flag);
index f897c39..c2c47fc 100644 (file)
@@ -5903,8 +5903,11 @@ __gst_appsrc_feed_data(GstElement *element, guint size, gpointer user_data) // @
        LOGI("app-src: feed data\n");
 
        g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
        if (player->media_stream_buffer_status_cb[type])
                player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param);
+
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
 }
 
 static gboolean
@@ -5916,9 +5919,11 @@ __gst_appsrc_seek_data(GstElement *element, guint64 offset, gpointer user_data)
        MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
 
        LOGI("app-src: seek data, offset: %llu\n", offset);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
 
        if (player->media_stream_seek_data_cb[type])
                player->media_stream_seek_data_cb[type](type, offset, player->buffer_cb_user_param);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
 
        return TRUE;
 }
@@ -5933,12 +5938,14 @@ __gst_appsrc_enough_data(GstElement *element, gpointer user_data) // @
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
 
-       LOGI("app-src: enough data:%p\n", player->media_stream_buffer_status_cb[type]);
-
        g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
 
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
+
+       LOGI("app-src: enough data:%p %llu\n", player->media_stream_buffer_status_cb[type], current_level_bytes);
        if (player->media_stream_buffer_status_cb[type])
                player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW, current_level_bytes, player->buffer_cb_user_param);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
 
        return TRUE;
 }
@@ -8433,6 +8440,9 @@ _mmplayer_create_player(MMHandleType handle) // @
        g_mutex_init(&player->video_bo_mutex);
        g_cond_init(&player->video_bo_cond);
 
+       /* create media stream callback mutex */
+       g_mutex_init(&player->media_stream_cb_lock);
+
        player->streaming_type = STREAMING_SERVICE_NONE;
 
        /* give default value of audio effect setting */
@@ -8621,6 +8631,51 @@ __mmplayer_destroy_streaming_ext(mm_player_t* player)
        return MM_ERROR_NONE;
 }
 
+static void
+__mmplayer_check_async_state_transition(mm_player_t* player)
+{
+       GstState element_state = GST_STATE_VOID_PENDING;
+       GstState element_pending_state = GST_STATE_VOID_PENDING;
+       GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
+       GstElement * element = NULL;
+       gboolean async = FALSE;
+
+       /* check player handle */
+       MMPLAYER_RETURN_IF_FAIL(player &&
+                                               player->pipeline &&
+                                               player->pipeline->mainbin &&
+                                               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
+
+       if (player->attrs)
+               mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async);
+
+       if (!MMPLAYER_IS_MS_BUFF_SRC(player) && (async == FALSE)) {
+               LOGD("don't need to check the pipeline state");
+               return;
+       }
+
+       MMPLAYER_PRINT_STATE(player);
+
+       /* wait for state transition */
+       element = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
+       ret = gst_element_get_state(element, &element_state, &element_pending_state, 1*GST_SECOND);
+
+       if (ret == GST_STATE_CHANGE_FAILURE) {
+               LOGE(" [%s] state : %s   pending : %s \n",
+                       GST_ELEMENT_NAME(element),
+                       gst_element_state_get_name(element_state),
+                       gst_element_state_get_name(element_pending_state));
+
+               /* dump state of all element */
+               __mmplayer_dump_pipeline_state(player);
+
+               return;
+       }
+
+       LOGD("[%s] element state has changed\n", GST_ELEMENT_NAME(element));
+       return;
+}
+
 int
 _mmplayer_destroy(MMHandleType handle) // @
 {
@@ -8634,6 +8689,9 @@ _mmplayer_destroy(MMHandleType handle) // @
        /* destroy can called at anytime */
        MMPLAYER_CHECK_STATE(player, MMPLAYER_COMMAND_DESTROY);
 
+       /* check async state transition */
+       __mmplayer_check_async_state_transition(player);
+
        __mmplayer_destroy_streaming_ext(player);
 
        /* release repeat thread */
@@ -8729,6 +8787,9 @@ _mmplayer_destroy(MMHandleType handle) // @
        g_mutex_clear(&player->video_bo_mutex);
        g_cond_clear(&player->video_bo_cond);
 
+       /* release media stream callback lock */
+       g_mutex_clear(&player->media_stream_cb_lock);
+
        MMPLAYER_FLEAVE();
 
        return MM_ERROR_NONE;
@@ -8931,6 +8992,9 @@ _mmplayer_unrealize(MMHandleType hplayer)
        /* check current state */
        MMPLAYER_CHECK_STATE(player, MMPLAYER_COMMAND_UNREALIZE);
 
+       /* check async state transition */
+       __mmplayer_check_async_state_transition(player);
+
        __mmplayer_unrealize_streaming_ext(player);
 
        /* unrealize pipeline */
@@ -12055,11 +12119,14 @@ __mmplayer_release_misc(mm_player_t* player)
                player->maximum_bitrate[i] = 0;
        }
 
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
+
        /* remove media stream cb(appsrc cb) */
        for (i = 0; i < MM_PLAYER_STREAM_TYPE_MAX; i++) {
                player->media_stream_buffer_status_cb[i] = NULL;
                player->media_stream_seek_data_cb[i] = NULL;
        }
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
 
        /* free memory related to audio effect */
        MMPLAYER_FREEIF(player->audio_effect_info.custom_ext_level_for_plugin);
@@ -14814,9 +14881,12 @@ __gst_appsrc_feed_audio_data(GstElement *element, guint size, gpointer user_data
        g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
 
        LOGI("app-src: feed audio(%llu)\n", current_level_bytes);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
 
        if (player->media_stream_buffer_status_cb[type])
                player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
+
 }
 
 void
@@ -14832,8 +14902,10 @@ __gst_appsrc_feed_video_data(GstElement *element, guint size, gpointer user_data
 
        LOGI("app-src: feed video(%llu)\n", current_level_bytes);
 
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
        if (player->media_stream_buffer_status_cb[type])
                player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
 }
 
 void
@@ -14849,8 +14921,11 @@ __gst_appsrc_feed_subtitle_data(GstElement *element, guint size, gpointer user_d
 
        g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
 
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
        if (player->media_stream_buffer_status_cb[type])
                player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param);
+
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
 }
 
 void
@@ -14866,8 +14941,12 @@ __gst_appsrc_enough_audio_data(GstElement *element, gpointer user_data)
 
        g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
 
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
+
        if (player->media_stream_buffer_status_cb[type])
                player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW, current_level_bytes, player->buffer_cb_user_param);
+
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
 }
 
 void
@@ -14883,8 +14962,11 @@ __gst_appsrc_enough_video_data(GstElement *element, gpointer user_data)
 
        g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
 
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
        if (player->media_stream_buffer_status_cb[type])
                player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW, current_level_bytes, player->buffer_cb_user_param);
+
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
 }
 
 gboolean
@@ -14896,9 +14978,11 @@ __gst_seek_audio_data(GstElement * appsrc, guint64 position, gpointer user_data)
        MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
 
        LOGD("app-src: seek audio data %llu\n", position);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
 
        if (player->media_stream_seek_data_cb[type])
                player->media_stream_seek_data_cb[type](type, position, player->buffer_cb_user_param);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
 
        return TRUE;
 }
@@ -14912,9 +14996,10 @@ __gst_seek_video_data(GstElement * appsrc, guint64 position, gpointer user_data)
        MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
 
        LOGD("app-src: seek video data %llu\n", position);
-
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
        if (player->media_stream_seek_data_cb[type])
                player->media_stream_seek_data_cb[type](type, position, player->buffer_cb_user_param);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
 
        return TRUE;
 }
@@ -14928,9 +15013,11 @@ __gst_seek_subtitle_data(GstElement * appsrc, guint64 position, gpointer user_da
        MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
 
        LOGD("app-src: seek subtitle data\n");
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
 
        if (player->media_stream_seek_data_cb[type])
                player->media_stream_seek_data_cb[type](type, position, player->buffer_cb_user_param);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
 
        return TRUE;
 }