+ player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(original_uri));
+ player->uri_info.uri_idx = 0;
+
+ SECURE_LOGD("add original path at first : %s", original_uri);
+ }
+ }
+
+ player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(uri));
+ SECURE_LOGD("add new path : %s(total num of list = %d)", uri, g_list_length(player->uri_info.uri_list));
+ }
+
+ MMPLAYER_FLEAVE();
+ return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_get_next_uri(MMHandleType hplayer, char **uri)
+{
+ mmplayer_t *player = (mmplayer_t *)hplayer;
+ char *next_uri = NULL;
+ guint num_of_list = 0;
+
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+ num_of_list = g_list_length(player->uri_info.uri_list);
+
+ if (num_of_list > 0) {
+ gint uri_idx = player->uri_info.uri_idx;
+
+ if (uri_idx < num_of_list-1)
+ uri_idx++;
+ else
+ uri_idx = 0;
+
+ next_uri = g_list_nth_data(player->uri_info.uri_list, uri_idx);
+ LOGE("next uri idx : %d, uri = %s", uri_idx, next_uri);
+
+ *uri = g_strdup(next_uri);
+ }
+
+ MMPLAYER_FLEAVE();
+ return MM_ERROR_NONE;
+}
+
+static void
+__mmplayer_gst_decode_unknown_type(GstElement *elem, GstPad *pad,
+ GstCaps *caps, gpointer data)
+{
+ mmplayer_t *player = (mmplayer_t *)data;
+ const gchar *klass = NULL;
+ const gchar *mime = NULL;
+ gchar *caps_str = NULL;
+
+ klass = gst_element_factory_get_metadata(gst_element_get_factory(elem), GST_ELEMENT_METADATA_KLASS);
+ mime = gst_structure_get_name(gst_caps_get_structure(caps, 0));
+ caps_str = gst_caps_to_string(caps);
+
+ LOGW("unknown type of caps : %s from %s",
+ caps_str, GST_ELEMENT_NAME(elem));
+
+ MMPLAYER_FREEIF(caps_str);
+
+ /* There is no available codec. */
+ __mmplayer_check_not_supported_codec(player, klass, mime);
+}
+
+static gboolean
+__mmplayer_gst_decode_autoplug_continue(GstElement *bin, GstPad *pad,
+ GstCaps *caps, gpointer data)
+{
+ mmplayer_t *player = (mmplayer_t *)data;
+ const char *mime = NULL;
+ gboolean ret = TRUE;
+
+ MMPLAYER_LOG_GST_CAPS_TYPE(caps);
+ mime = gst_structure_get_name(gst_caps_get_structure(caps, 0));
+
+ if (g_str_has_prefix(mime, "audio")) {
+ GstStructure *caps_structure = NULL;
+ gint samplerate = 0;
+ gint channels = 0;
+ gchar *caps_str = NULL;
+
+ caps_structure = gst_caps_get_structure(caps, 0);
+ gst_structure_get_int(caps_structure, "rate", &samplerate);
+ gst_structure_get_int(caps_structure, "channels", &channels);
+
+ if ((channels > 0 && samplerate == 0)) {
+ LOGD("exclude audio...");
+ ret = FALSE;
+ }
+
+ caps_str = gst_caps_to_string(caps);
+ /* set it directly because not sent by TAG */
+ if (g_strrstr(caps_str, "mobile-xmf"))
+ mm_player_set_attribute((MMHandleType)player, NULL,
+ "content_audio_codec", "mobile-xmf", strlen("mobile-xmf"), NULL);
+
+ MMPLAYER_FREEIF(caps_str);
+ } else if (g_str_has_prefix(mime, "video") && !player->ini.video_playback_supported) {
+ MMMessageParamType msg_param;
+ memset(&msg_param, 0, sizeof(MMMessageParamType));
+ msg_param.code = MM_ERROR_NOT_SUPPORT_API;
+ MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
+ LOGD("video file is not supported on this device");
+ ret = FALSE;
+ } else if (g_str_has_prefix(mime, "video") && player->videodec_linked) {
+ LOGD("already video linked");
+ ret = FALSE;
+ } else {
+ LOGD("found new stream");
+ }
+
+ return ret;
+}
+
+static gboolean
+__mmplayer_is_audio_offload_device_type(mmplayer_t *player)
+{
+ gboolean ret = TRUE;
+ GDBusConnection *conn = NULL;
+ GError *err = NULL;
+ GVariant *result = NULL;
+ const gchar *dbus_device_type = NULL;
+ const gchar *dbus_ret = NULL;
+ gint idx = 0;
+
+ conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+ if (!conn || err) {
+ LOGE("failed g_bus_get_sync() (%s)", err ? err->message : NULL);
+ g_error_free(err);
+ ret = FALSE;
+ goto DONE;
+ }
+
+ result = g_dbus_connection_call_sync(conn,
+ "org.pulseaudio.Server",
+ "/org/pulseaudio/StreamManager",
+ "org.pulseaudio.StreamManager",
+ "GetCurrentMediaRoutingPath",
+ g_variant_new("(s)", "out"),
+ G_VARIANT_TYPE("(ss)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ 2000,
+ NULL,
+ &err);
+ if (!result || err) {
+ LOGE("failed g_dbus_connection_call_sync() (%s)", err ? err->message : NULL);
+ g_error_free(err);
+ ret = FALSE;
+ goto DONE;
+ }
+
+ /* device type is listed in stream-map.json at mmfw-sysconf */
+ g_variant_get(result, "(&s&s)", &dbus_device_type, &dbus_ret);
+
+ LOGI("g_dbus_connection_call_sync() success (%s, %s)", dbus_device_type, dbus_ret);
+ if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
+ ret = FALSE;
+ goto DONE;
+ }
+
+ /* the device type is listed in ini file among audio-jack, bt-a2dp, usb-audio, builtin-speaker */
+ for (idx = 0; player->ini.audio_offload_device_type[idx][0] != '\0'; idx++) {
+ if (strstr(dbus_device_type, player->ini.audio_offload_device_type[idx])) {
+ LOGD("audio offload is supportable");
+ ret = TRUE;
+ goto DONE;
+ }
+ }
+
+ LOGD("audio offload is not supportable");
+ ret = FALSE;
+
+DONE:
+ g_variant_unref(result);
+ g_object_unref(conn);
+
+ return ret;
+}
+
+static void __mmplayer_rebuild_audio_pipeline(mmplayer_t *player)
+{
+ mmplayer_state_e current_state = MM_PLAYER_STATE_NONE;
+ gint64 position = 0;
+
+ MMPLAYER_RETURN_IF_FAIL(player && player->attrs &&
+ player->pipeline && player->pipeline->mainbin);
+
+ MMPLAYER_CMD_LOCK(player);
+ current_state = MMPLAYER_CURRENT_STATE(player);
+
+ if (!gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &position))
+ LOGW("getting current position failed in paused");
+
+ _mmplayer_unrealize((MMHandleType)player);
+ _mmplayer_realize((MMHandleType)player);
+
+ _mmplayer_set_position((MMHandleType)player, position);
+
+ /* async not to be blocked in streaming case */
+ mm_player_set_attribute((MMHandleType)player, NULL, "profile_prepare_async", TRUE, NULL);
+
+ _mmplayer_pause((MMHandleType)player);
+
+ if (current_state == MM_PLAYER_STATE_PLAYING)
+ _mmplayer_start((MMHandleType)player);
+ MMPLAYER_CMD_UNLOCK(player);
+
+ LOGD("rebuilding audio pipeline is completed.");
+}
+
+void __mmplayer_audio_device_connected_cb(MMSoundDevice_t device_h, bool is_connected, void *user_data)
+{
+ mmplayer_t *player = (mmplayer_t *)user_data;
+ mm_sound_device_type_e dev_type = MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER;
+ gboolean is_supportable = FALSE;
+
+ if (mm_sound_get_device_type(device_h, &dev_type) != MM_ERROR_NONE)
+ LOGW("failed to get device type");
+ else
+ LOGD("dev type (%d), connected (%d)", dev_type, is_connected);
+
+ if ((dev_type != MM_SOUND_DEVICE_TYPE_BLUETOOTH_A2DP) &&
+ (dev_type != MM_SOUND_DEVICE_TYPE_AUDIOJACK) &&
+ (dev_type != MM_SOUND_DEVICE_TYPE_USB_AUDIO)) {
+ LOGD("ignore this dev connected info");
+ return;
+ }
+
+ is_supportable = __mmplayer_is_audio_offload_device_type(player);
+ if (player->build_audio_offload == is_supportable) {
+ LOGD("keep current pipeline without re-building");
+ return;
+ }
+
+ /* rebuild pipeline */
+ LOGD("re-build pipeline - offload: %d", is_supportable);
+ player->build_audio_offload = FALSE;
+ __mmplayer_rebuild_audio_pipeline(player);