[0.6.219] Fix g_mutex_clear crash when destroying bus msg thread
[platform/core/multimedia/libmm-player.git] / src / mm_player_priv.c
index ef7ad05..b1559a8 100644 (file)
@@ -756,6 +756,42 @@ __mmplayer_remove_g_source_from_context(GMainContext *context, guint source_id)
 }
 
 void
+_mmplayer_watcher_removed_notify(gpointer data)
+{
+       mmplayer_t *player = (mmplayer_t *)data;
+       MMPLAYER_RETURN_IF_FAIL(player);
+
+       MMPLAYER_BUS_WATCHER_LOCK(player);
+       player->bus_watcher = 0;
+       MMPLAYER_BUS_WATCHER_SIGNAL(player);
+       MMPLAYER_BUS_WATCHER_UNLOCK(player);
+}
+
+void
+_mmplayer_bus_watcher_remove(MMHandleType hplayer)
+{
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       gint64 end_time = 0;
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player);
+
+       /* disconnecting bus watch */
+       if (player->bus_watcher > 0) {
+               __mmplayer_remove_g_source_from_context(player->context.thread_default, player->bus_watcher);
+               MMPLAYER_BUS_WATCHER_LOCK(player);
+               end_time = g_get_monotonic_time () + 2 * G_TIME_SPAN_SECOND;
+               while (player->bus_watcher > 0)
+                       MMPLAYER_BUS_WATCHER_WAIT_UNTIL(player, end_time);
+               MMPLAYER_BUS_WATCHER_UNLOCK(player);
+
+               g_mutex_clear(&player->bus_watcher_mutex);
+               g_cond_clear(&player->bus_watcher_cond);
+       }
+
+       MMPLAYER_FLEAVE();
+}
+
+void
 _mmplayer_bus_msg_thread_destroy(MMHandleType hplayer)
 {
        mmplayer_t *player = (mmplayer_t *)hplayer;
@@ -765,11 +801,6 @@ _mmplayer_bus_msg_thread_destroy(MMHandleType hplayer)
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player);
 
-       /* disconnecting bus watch */
-       if (player->bus_watcher)
-               __mmplayer_remove_g_source_from_context(player->context.thread_default, player->bus_watcher);
-       player->bus_watcher = 0;
-
        /* destroy the gst bus msg thread */
        if (player->bus_msg_thread) {
                MMPLAYER_BUS_MSG_THREAD_LOCK(player);
@@ -1177,7 +1208,6 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
        const gchar *name = NULL;
        GstPad *sinkpad = NULL;
        gboolean first_track = FALSE;
-       gboolean caps_ret = TRUE;
 
        main_element_id_e elem_idx = MMPLAYER_M_NUM;
        mmplayer_track_type_e stream_type = MM_PLAYER_TRACK_TYPE_AUDIO;
@@ -1189,8 +1219,13 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
        LOGD("pad-added signal handling");
 
        /* get mimetype from caps */
-       MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
-       if (!caps_ret)
+       caps = gst_pad_get_current_caps(pad);
+       if (caps) {
+               str = gst_caps_get_structure(caps, 0);
+               if (str)
+                       name = gst_structure_get_name(str);
+       }
+       if (!name)
                goto ERROR;
 
        MMPLAYER_LOG_GST_CAPS_TYPE(caps);
@@ -2563,18 +2598,23 @@ __mmplayer_gst_set_pulsesink_property(mmplayer_t *player)
        MMPLAYER_FLEAVE();
 }
 
-void
+int
 __mmplayer_gst_set_openalsink_property(mmplayer_t *player)
 {
        mmplayer_gst_element_t *audiobin = NULL;
 
        MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->audiobin);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+                               player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
        audiobin = player->pipeline->audiobin;
 
        g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "source-ambisonics-type", 1, NULL);
-       sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, NULL, NULL, &stream_info);
+       if (sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, NULL, NULL, &stream_info)) {
+               LOGE("failed to create media stream info");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
        g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "stream-info", stream_info, NULL);
 
        if (player->video360_yaw_radians <= M_PI &&
@@ -2591,6 +2631,7 @@ __mmplayer_gst_set_openalsink_property(mmplayer_t *player)
        }
 
        MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
 }
 
 static int
@@ -2728,10 +2769,12 @@ __mmplayer_gst_make_audio_playback_sink(mmplayer_t *player, GList **bucket)
                g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "provide-clock", FALSE,  NULL);
        }
 
-       if (g_strrstr(player->ini.audiosink_element, "pulsesink"))
+       if (g_strrstr(player->ini.audiosink_element, "pulsesink")) {
                __mmplayer_gst_set_pulsesink_property(player);
-       else if (g_strrstr(player->ini.audiosink_element, "openalsink"))
-               __mmplayer_gst_set_openalsink_property(player);
+       } else if (g_strrstr(player->ini.audiosink_element, "openalsink")) {
+               if (__mmplayer_gst_set_openalsink_property(player) != MM_ERROR_NONE)
+                       goto ERROR;
+       }
 
        /* qos on */
        g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "qos", TRUE, NULL);       /* qos on */
@@ -4169,6 +4212,7 @@ __mmplayer_gst_create_pipeline(mmplayer_t *player)
        return MM_ERROR_NONE;
 
 INIT_ERROR:
+       _mmplayer_bus_watcher_remove(player);
        __mmplayer_gst_destroy_pipeline(player);
        return MM_ERROR_PLAYER_INTERNAL;
 }
@@ -5095,6 +5139,7 @@ _mmplayer_unrealize(MMHandleType hplayer)
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
        MMPLAYER_CMD_UNLOCK(player);
+       _mmplayer_bus_watcher_remove(player);
        /* destroy the gst bus msg thread which is created during realize.
           this funct have to be called before getting cmd lock. */
        _mmplayer_bus_msg_thread_destroy(player);
@@ -7081,6 +7126,10 @@ _mmplayer_gst_decode_autoplug_sort(GstElement *bin,
                gchar (*sw_dec_info)[PLAYER_INI_MAX_STRLEN] = {NULL, };
 
                factory = g_value_get_object(g_value_array_get_nth(factories, i));
+               if (!factory) {
+                       LOGW("failed to get factory object");
+                       continue;
+               }
                klass = gst_element_factory_get_klass(factory);
                factory_name = GST_OBJECT_NAME(factory);
 
@@ -7130,7 +7179,7 @@ _mmplayer_gst_decode_autoplug_sort(GstElement *bin,
        if (codec_type == MM_PLAYER_CODEC_TYPE_HW) {
                if (hw_dec_idx < first_sw_dec_idx)
                        return NULL;
-               new_pos = first_sw_dec_idx - 1;
+               new_pos = first_sw_dec_idx;
                rm_pos = hw_dec_idx + 1;
        } else if (codec_type == MM_PLAYER_CODEC_TYPE_SW) {
                if (last_sw_dec_idx < hw_dec_idx)
@@ -7142,8 +7191,12 @@ _mmplayer_gst_decode_autoplug_sort(GstElement *bin,
        }
 
        /* change position - insert H/W decoder according to the new position */
-       new_factories = g_value_array_copy(factories);
        factory = g_value_get_object(g_value_array_get_nth(factories, hw_dec_idx));
+       if (!factory) {
+               LOGW("failed to get factory object");
+               return NULL;
+       }
+       new_factories = g_value_array_copy(factories);
        g_value_init (&val, G_TYPE_OBJECT);
        g_value_set_object (&val, factory);
        g_value_array_insert(new_factories, new_pos, &val);
@@ -7152,9 +7205,11 @@ _mmplayer_gst_decode_autoplug_sort(GstElement *bin,
 
        for (int i = 0 ; i < new_factories->n_values ; i++) {
                factory = g_value_get_object(g_value_array_get_nth(new_factories, i));
-
-               LOGD("[Re-arranged] Klass [%s] Factory [%s]",
-                       gst_element_factory_get_klass(factory), GST_OBJECT_NAME (factory));
+               if (factory)
+                       LOGD("[Re-arranged] Klass [%s] Factory [%s]",
+                               gst_element_factory_get_klass(factory), GST_OBJECT_NAME (factory));
+               else
+                       LOGE("[Re-arranged] failed to get factory object");
        }
 
        return new_factories;
@@ -9191,11 +9246,12 @@ __mmplayer_set_file_uri(mmplayer_parse_profile_t *data, const char *uri)
 
        /* if no protocol prefix exist. check file existence and then give file:// as it's prefix */
        if (ret == MM_ERROR_NONE) {
-               g_snprintf(data->uri,  MM_MAX_URL_LEN, "file://%s", path);
                if (_mmplayer_is_sdp_file(path)) {
                        LOGD("uri is actually a file but it's sdp file. giving it to rtspsrc");
+                       g_snprintf(data->uri,  MM_MAX_URL_LEN, "rtsp-sdp://%s", path);
                        data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
                } else {
+                       g_snprintf(data->uri,  MM_MAX_URL_LEN, "file://%s", path);
                        data->uri_type = MM_PLAYER_URI_TYPE_FILE;
                }
        } else if (ret == MM_ERROR_PLAYER_PERMISSION_DENIED) {