[v0.3.23] sync cb invoke context with tizen 2.4 and apply tizen coding rule 06/89906/1 accepted/tizen/common/20160928.163904
authorEunhae Choi <eunhae1.choi@samsung.com>
Tue, 27 Sep 2016 10:58:50 +0000 (19:58 +0900)
committerEunhae Choi <eunhae1.choi@samsung.com>
Tue, 27 Sep 2016 10:58:50 +0000 (19:58 +0900)
Change-Id: I234bad689b578303024bb896d8430363d2609144

include/common/player_internal.h
include/player_private.h
include/wearable/player_internal.h
packaging/capi-media-player.spec
src/player.c

index 91675d5..5f267c2 100644 (file)
@@ -187,6 +187,7 @@ int player_set_streaming_playback_rate(player_h player, float rate);
  * @brief Registers a callback function to be invoked when buffer underrun or overflow is occurred.
  * @since_tizen 3.0
  * @remarks This API is used for media stream playback only.
+ * @remarks The registered callback is issued in the internal thread of the player.
  * @param[in] player   The handle to the media player
  * @param[in] type     The type of target stream
  * @param[in] callback The buffer status callback function to register
@@ -277,14 +278,6 @@ typedef void (*player_buffer_enough_data_cb) (void *user_data);
 typedef void (*player_buffer_need_data_cb) (unsigned int size, void *user_data);
 
 /**
- * @brief Called to notify the resource conflict
- * @since_tizen 3.0
- * @param[in] user_data    The user data passed from the callback registration function
- * @see player_set_resourceconflict_cb()
- */
-typedef void (*player_resourceconflict_cb)(void *user_data);
-
-/**
  * @brief Submits packet to appsrc, used in external demux mode
  * @since_tizen 3.0
  * @param[in]  player   The handle to media player
@@ -317,6 +310,7 @@ int player_set_audio_stream_info(player_h player, player_audio_stream_info_s *in
 /**
  * @brief Registers the callback function.
  * @since_tizen 3.0
+ * @remarks The registered callback is issued in the internal thread of the player.
  * @param[in] player The handle to media player
  * @param[in] callback  The callback function to register
  * @param[in] user_data The user data to be passed to the callback function
@@ -330,6 +324,7 @@ int player_set_buffer_enough_video_data_cb(player_h player, player_buffer_enough
 /**
  * @brief Registers the callback function.
  * @since_tizen 3.0
+ * @remarks The registered callback is issued in the internal thread of the player.
  * @param[in] player The handle to media player
  * @param[in] callback  The callback function to register
  * @param[in] user_data The user data to be passed to the callback function
@@ -343,6 +338,7 @@ int player_set_buffer_enough_audio_data_cb(player_h player, player_buffer_enough
 /**
  * @brief Registers the callback function.
  * @since_tizen 3.0
+ * @remarks The registered callback is issued in the internal thread of the player.
  * @param[in] player The handle to media player
  * @param[in] callback  The callback function to register
  * @param[in] user_data The user data to be passed to the callback function
@@ -356,6 +352,7 @@ int player_set_buffer_need_video_data_cb(player_h player, player_buffer_need_dat
 /**
  * @brief Registers the callback function.
  * @since_tizen 3.0
+ * @remarks The registered callback is issued in the internal thread of the player.
  * @param[in] player The handle to media player
  * @param[in] callback  The callback function to register
  * @param[in] user_data The user data to be passed to the callback function
@@ -367,33 +364,6 @@ int player_set_buffer_need_video_data_cb(player_h player, player_buffer_need_dat
 int player_set_buffer_need_audio_data_cb(player_h player, player_buffer_need_data_cb callback, void *user_data);
 
 /**
- * @brief Registers a callback function to be invoked when the resource conflict is detected.
- * @since_tizen 3.0
- * @param[in] player   The handle to the media player
- * @param[in] callback The callback function to register
- * @param[in] user_data        The user data to be passed to the callback function
- * @return @c 0 on success,
- *         otherwise a negative error value
- * @retval #PLAYER_ERROR_NONE Successful
- * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
- * @post player_resourceconflict_cb() will be invoked.
- * @see player_unset_resourceconflict_cb()
- */
-int player_set_resourceconflict_cb(player_h player, player_resourceconflict_cb callback, void *user_data);
-
-/**
- * @brief Unregisters the callback function.
- * @since_tizen 3.0
- * @param[in] player   The handle to the media player
- * @return @c 0 on success,
- *         otherwise a negative error value
- * @retval #PLAYER_ERROR_NONE Successful
- * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
- * @see player_set_resourceconflict_cb()
- */
-int player_unset_resourceconflict_cb(player_h player);
-
-/**
  * @brief Display the first video frame at the player_prepare() function to improve the playback performance.
  * @since_tizen 3.0
  * @details This is only availble when you want to start playback from 0 position.
index b97357a..24beb65 100644 (file)
@@ -78,6 +78,9 @@ typedef struct {
        GMutex mutex;
        GCond cond;
        gboolean running;
+
+       GMutex idle_ev_mutex;
+       GList *idle_ev_list;
 } player_event_queue;
 
 typedef struct {
index 33d9961..a1b01dd 100644 (file)
@@ -123,6 +123,7 @@ int player_set_streaming_playback_rate(player_h player, float rate);
  * @brief Registers a callback function to be invoked when buffer underrun or overflow is occurred.
  * @since_tizen 3.0
  * @remarks This API is used for media stream playback only.
+ * @remarks The registered callback is issued in the internal thread of the player.
  * @param[in] player   The handle to the media player
  * @param[in] type     The type of target stream
  * @param[in] callback The buffer status callback function to register
index 782770c..89699da 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-player
 Summary:    A Media Player API
-Version:    0.3.22
+Version:    0.3.23
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 026b0e1..f6769a4 100644 (file)
@@ -51,6 +51,7 @@ typedef struct {
        int int_data;
        char *buf;
        callback_cb_info_s *cb_info;
+       GMutex event_mutex;
 } _player_cb_data;
 
 typedef struct {
@@ -424,25 +425,25 @@ static void __complete_cb_handler(callback_cb_info_s * cb_info, char *recvMsg)
 static char* _convert_code_to_str(int code)
 {
        switch (code) {
-               case PLAYER_INTERRUPTED_COMPLETED:          /* Deprecated since 3.0 */
-                       return "PLAYER_INTERRUPTED_COMPLETED";
-               case PLAYER_INTERRUPTED_BY_MEDIA:           /* Deprecated since 3.0 */
-                       return "PLAYER_INTERRUPTED_BY_MEDIA";
-               case PLAYER_INTERRUPTED_BY_CALL:            /* Deprecated since 3.0 */
-                       return "PLAYER_INTERRUPTED_BY_CALL";
-               case PLAYER_INTERRUPTED_BY_EARJACK_UNPLUG:  /* Deprecated since 3.0 */
-                       return "PLAYER_INTERRUPTED_BY_EARJACK_UNPLUG";
-               case PLAYER_INTERRUPTED_BY_RESOURCE_CONFLICT:
-                       return "PLAYER_INTERRUPTED_BY_RESOURCE_CONFLICT";
-               case PLAYER_INTERRUPTED_BY_ALARM:           /* Deprecated since 3.0 */
-                       return "PLAYER_INTERRUPTED_BY_ALARM";
-               case PLAYER_INTERRUPTED_BY_EMERGENCY:       /* Deprecated since 3.0 */
-                       return "PLAYER_INTERRUPTED_BY_EMERGENCY";
-               case PLAYER_INTERRUPTED_BY_NOTIFICATION:    /* Deprecated since 3.0 */
-                       return "PLAYER_INTERRUPTED_BY_NOTIFICATION";
-               default:
-                       LOGE("Invalid interrupted code %d (Never enter here)", code);
-                       return NULL;
+       case PLAYER_INTERRUPTED_COMPLETED:          /* Deprecated since 3.0 */
+               return "PLAYER_INTERRUPTED_COMPLETED";
+       case PLAYER_INTERRUPTED_BY_MEDIA:           /* Deprecated since 3.0 */
+               return "PLAYER_INTERRUPTED_BY_MEDIA";
+       case PLAYER_INTERRUPTED_BY_CALL:            /* Deprecated since 3.0 */
+               return "PLAYER_INTERRUPTED_BY_CALL";
+       case PLAYER_INTERRUPTED_BY_EARJACK_UNPLUG:  /* Deprecated since 3.0 */
+               return "PLAYER_INTERRUPTED_BY_EARJACK_UNPLUG";
+       case PLAYER_INTERRUPTED_BY_RESOURCE_CONFLICT:
+               return "PLAYER_INTERRUPTED_BY_RESOURCE_CONFLICT";
+       case PLAYER_INTERRUPTED_BY_ALARM:           /* Deprecated since 3.0 */
+               return "PLAYER_INTERRUPTED_BY_ALARM";
+       case PLAYER_INTERRUPTED_BY_EMERGENCY:       /* Deprecated since 3.0 */
+               return "PLAYER_INTERRUPTED_BY_EMERGENCY";
+       case PLAYER_INTERRUPTED_BY_NOTIFICATION:    /* Deprecated since 3.0 */
+               return "PLAYER_INTERRUPTED_BY_NOTIFICATION";
+       default:
+               LOGE("Invalid interrupted code %d (Never enter here)", code);
+               return NULL;
        }
 }
 
@@ -992,16 +993,54 @@ static void (*_user_callbacks[MUSE_PLAYER_EVENT_TYPE_NUM]) (callback_cb_info_s *
        __video_stream_changed_cb_handler,              /* MUSE_PLAYER_EVENT_TYPE_VIDEO_STREAM_CHANGED */
 };
 
-static void _player_event_job_function(_player_cb_data * data)
+gboolean _player_event_job_function(void *user_data)
 {
+       _player_cb_data *data = (_player_cb_data *)user_data;
+
+       if (data == NULL) {
+               LOGE("data is null");
+               return FALSE;
+       }
+
+       LOGD("enter ev:%d", data->int_data);
+
+       g_mutex_lock(&data->event_mutex);
+
        muse_player_event_e ev = data->int_data;
+
+       /* remove event from list */
+       g_mutex_lock(&data->cb_info->event_queue.idle_ev_mutex);
+       LOGD("remove idle event %p, %p", data, data->cb_info->event_queue.idle_ev_list);
+       if (data->cb_info->event_queue.idle_ev_list)
+               data->cb_info->event_queue.idle_ev_list = g_list_remove(data->cb_info->event_queue.idle_ev_list, (gpointer)data);
+       g_mutex_unlock(&data->cb_info->event_queue.idle_ev_mutex);
+
        if (data->cb_info->user_cb[ev])
                _user_callbacks[ev] (data->cb_info, data->buf);
        else
                LOGW("user callback is unset. type : %d", ev);
 
+       /* unlock and release event */
+       g_mutex_unlock(&data->event_mutex);
+       g_mutex_clear(&data->event_mutex);
+
        g_free(data->buf);
        g_free(data);
+
+       return FALSE; /* remove from the event list */
+}
+
+static bool _player_need_sync_context(int event_id)
+{
+       if ((event_id == MUSE_PLAYER_EVENT_TYPE_INTERRUPT) ||
+               (event_id == MUSE_PLAYER_EVENT_TYPE_BUFFERING) ||
+               (event_id == MUSE_PLAYER_EVENT_TYPE_PD) ||
+               (event_id == MUSE_PLAYER_EVENT_TYPE_COMPLETE)) {
+               LOGD("%d callback will be issued in the mainloop.", event_id);
+               return TRUE;
+       } else {
+               return FALSE;
+       }
 }
 
 static void *_player_event_queue_loop(void *param)
@@ -1012,7 +1051,7 @@ static void *_player_event_queue_loop(void *param)
        }
        callback_cb_info_s *cb_info = param;
        player_event_queue *ev = &cb_info->event_queue;
-       _player_cb_data *event_data;
+       _player_cb_data *event_data = NULL;
 
        g_mutex_lock(&ev->mutex);
        while (ev->running) {
@@ -1029,10 +1068,24 @@ static void *_player_event_queue_loop(void *param)
                        g_mutex_lock(&ev->qlock);
                        event_data = (_player_cb_data *) g_queue_pop_head(ev->queue);
                        g_mutex_unlock(&ev->qlock);
-                       if (event_data)
-                               _player_event_job_function(event_data);
-                       else
+                       if (event_data) {
+                               if (_player_need_sync_context(event_data->int_data)) {
+                                               g_mutex_lock(&ev->idle_ev_mutex);
+                                               ev->idle_ev_list = g_list_append(ev->idle_ev_list, (gpointer)event_data);
+                                               g_mutex_unlock(&ev->idle_ev_mutex);
+
+                                               LOGD("add ev %d to main loop", event_data->int_data);
+
+                                               g_idle_add_full(G_PRIORITY_DEFAULT,
+                                                                               (GSourceFunc)_player_event_job_function,
+                                                                               (gpointer)event_data,
+                                                                               NULL);
+                               } else {
+                                       _player_event_job_function(event_data);
+                               }
+                       } else {
                                break;
+                       }
                }
        }
        g_mutex_unlock(&ev->mutex);
@@ -1052,6 +1105,9 @@ static gboolean _player_event_queue_new(callback_cb_info_s * cb_info)
        g_mutex_init(&ev->mutex);
        g_cond_init(&ev->cond);
        ev->running = TRUE;
+
+       g_mutex_init(&ev->idle_ev_mutex);
+
        ev->thread = g_thread_new("cb_event_thread", _player_event_queue_loop, (gpointer) cb_info);
        g_return_val_if_fail(ev->thread, FALSE);
        LOGI("event queue thread %p", ev->thread);
@@ -1060,6 +1116,67 @@ static gboolean _player_event_queue_new(callback_cb_info_s * cb_info)
 
 }
 
+static void _player_remove_idle_event_all(callback_cb_info_s *cb_info)
+{
+       g_return_if_fail(cb_info);
+       player_event_queue *ev = &cb_info->event_queue;
+       _player_cb_data *event_data = NULL;
+
+       g_mutex_lock(&ev->idle_ev_mutex);
+
+       if (ev->idle_ev_list == NULL) {
+               LOGD("No idle event is remained.");
+       } else {
+               GList *list = NULL;
+               list = ev->idle_ev_list;
+
+               while (list) {
+                       event_data = list->data;
+
+                       if (!event_data) {
+                               list = g_list_next(list);
+                               LOGW("Fail to remove idle event. The data is NULL");
+                       } else {
+                               if (g_mutex_trylock(&event_data->event_mutex)) {
+                                       bool ret = FALSE;
+
+                                       list = g_list_next(list);
+                                       ret = g_idle_remove_by_data(event_data);
+
+                                       LOGD("remove idle event [%p], ret[%d]", event_data, ret);
+
+                                       if (ret == FALSE) {
+                                               event_data->cb_info = NULL;
+                                               LOGW("idle callback for event %p will be called later", event_data);
+                                       }
+
+                                       ev->idle_ev_list = g_list_remove(ev->idle_ev_list, (gpointer)event_data);
+
+                                       g_mutex_unlock(&event_data->event_mutex);
+
+                                       if (ret == TRUE) {
+                                               g_mutex_clear(&event_data->event_mutex);
+
+                                               g_free(event_data);
+                                               event_data = NULL;
+
+                                               LOGD("remove idle event done");
+                                       }
+                               } else {
+                                       LOGW("event(%d) lock failed. it's being called...", event_data->int_data);
+                               }
+                       }
+               }
+
+               g_list_free(ev->idle_ev_list);
+               ev->idle_ev_list = NULL;
+       }
+
+       g_mutex_unlock(&ev->idle_ev_mutex);
+
+       return;
+}
+
 static void _player_event_queue_destroy(callback_cb_info_s * cb_info)
 {
        g_return_if_fail(cb_info);
@@ -1087,7 +1204,7 @@ static void _player_event_queue_destroy(callback_cb_info_s * cb_info)
        g_mutex_clear(&ev->qlock);
        g_mutex_clear(&ev->mutex);
        g_cond_clear(&ev->cond);
-
+       g_mutex_clear(&ev->idle_ev_mutex);
 }
 
 static void _player_event_queue_remove(player_event_queue * ev_queue, int ev)
@@ -1138,6 +1255,7 @@ static void _user_callback_handler(callback_cb_info_s * cb_info, muse_player_eve
                        data->int_data = (int)event;
                        data->cb_info = cb_info;
                        data->buf = buffer;
+                       g_mutex_init(&data->event_mutex);
                        _player_event_queue_add(&cb_info->event_queue, data);
                }
        }
@@ -1537,6 +1655,7 @@ int player_destroy(player_h player)
 
        if (CALLBACK_INFO(pc)) {
                __player_remove_tsurf_list(pc);
+               _player_remove_idle_event_all(CALLBACK_INFO(pc));
                _player_event_queue_destroy(CALLBACK_INFO(pc));
                tbm_bufmgr_deinit(TBM_BUFMGR(pc));
 
@@ -1644,11 +1763,10 @@ void _player_replace_old_path(const char *in_path, char *out_path)
 
        LOGD("input file_path : %s", in_path);
 
-       if (strncmp(in_path, old_path, strlen(old_path)) == 0) {
+       if (strncmp(in_path, old_path, strlen(old_path)) == 0)
                snprintf(out_path, MAX_URL_LEN, "%s%s", tzplatform_getenv(TZ_USER_CONTENT), in_path+strlen(old_path));
-       } else {
+       else
                snprintf(out_path, MAX_URL_LEN, "%s", in_path);
-       }
 
        LOGD("replaced path : %s", out_path);
        return;
@@ -2260,11 +2378,10 @@ int player_set_display_mode(player_h player, player_display_mode_e mode)
 #ifdef TIZEN_FEATURE_EVAS_RENDERER
        if (EVAS_HANDLE(pc)) {
                ret = mm_evas_renderer_set_geometry(EVAS_HANDLE(pc), mode);
-               if (ret != MM_ERROR_NONE) {
+               if (ret != MM_ERROR_NONE)
                        return PLAYER_ERROR_INVALID_OPERATION;
-               } else {
+               else
                        return PLAYER_ERROR_NONE;
-               }
        }
 #endif
        player_msg_send1(api, pc, ret_buf, ret, INT, mode);
@@ -2287,11 +2404,10 @@ int player_get_display_mode(player_h player, player_display_mode_e * pmode)
        if (EVAS_HANDLE(pc)) {
                ret = mm_evas_renderer_get_geometry(EVAS_HANDLE(pc), &mode);
                *pmode = (player_display_mode_e) mode;
-               if (ret != MM_ERROR_NONE) {
+               if (ret != MM_ERROR_NONE)
                        return PLAYER_ERROR_INVALID_OPERATION;
-               } else {
+               else
                        return PLAYER_ERROR_NONE;
-               }
        }
 #endif
        player_msg_send(api, pc, ret_buf, ret);
@@ -2322,13 +2438,12 @@ int player_set_display_roi_area(player_h player, int x, int y, int width, int he
 #ifdef TIZEN_FEATURE_EVAS_RENDERER
        if (EVAS_HANDLE(pc)) {
                ret = mm_evas_renderer_set_roi_area(EVAS_HANDLE(pc), x, y, width, height);
-               if (ret == MM_ERROR_INVALID_ARGUMENT) {
+               if (ret == MM_ERROR_INVALID_ARGUMENT)
                        return PLAYER_ERROR_INVALID_PARAMETER;
-               } else if (ret != MM_ERROR_NONE) {
+               else if (ret != MM_ERROR_NONE)
                        return PLAYER_ERROR_INVALID_OPERATION;
-               } else {
+               else
                        return PLAYER_ERROR_NONE;
-               }
        }
 #endif
        wl_win.wl_window_x = x;
@@ -2369,11 +2484,10 @@ int player_set_display_rotation(player_h player, player_display_rotation_e rotat
 #ifdef TIZEN_FEATURE_EVAS_RENDERER
        if (EVAS_HANDLE(pc)) {
                ret = mm_evas_renderer_set_rotation(EVAS_HANDLE(pc), rotation);
-               if (ret != MM_ERROR_NONE) {
+               if (ret != MM_ERROR_NONE)
                        return PLAYER_ERROR_INVALID_OPERATION;
-               } else {
+               else
                        return PLAYER_ERROR_NONE;
-               }
        }
 #endif
        player_msg_send1(api, pc, ret_buf, ret, INT, rotation);
@@ -2396,11 +2510,10 @@ int player_get_display_rotation(player_h player, player_display_rotation_e * pro
        if (EVAS_HANDLE(pc)) {
                ret = mm_evas_renderer_get_rotation(EVAS_HANDLE(pc), &rotation);
                *protation = (player_display_rotation_e) rotation;
-               if (ret != MM_ERROR_NONE) {
+               if (ret != MM_ERROR_NONE)
                        return PLAYER_ERROR_INVALID_OPERATION;
-               } else {
+               else
                        return PLAYER_ERROR_NONE;
-               }
        }
 #endif
        player_msg_send(api, pc, ret_buf, ret);
@@ -2425,11 +2538,10 @@ int player_set_display_visible(player_h player, bool visible)
 #ifdef TIZEN_FEATURE_EVAS_RENDERER
        if (EVAS_HANDLE(pc)) {
                ret = mm_evas_renderer_set_visible(EVAS_HANDLE(pc), visible);
-               if (ret != MM_ERROR_NONE) {
+               if (ret != MM_ERROR_NONE)
                        return PLAYER_ERROR_INVALID_OPERATION;
-               } else {
+               else
                        return PLAYER_ERROR_NONE;
-               }
        }
 #endif
 
@@ -2459,11 +2571,10 @@ int player_is_display_visible(player_h player, bool * pvisible)
                else
                        *pvisible = FALSE;
 
-               if (ret != MM_ERROR_NONE) {
+               if (ret != MM_ERROR_NONE)
                        return PLAYER_ERROR_INVALID_OPERATION;
-               } else {
+               else
                        return PLAYER_ERROR_NONE;
-               }
        }
 #endif
        player_msg_send(api, pc, ret_buf, ret);