Index: plugins/mtpdevice/rb-mtp-source.c
===================================================================
--- plugins/mtpdevice/rb-mtp-source.c	(revision 5171)
+++ plugins/mtpdevice/rb-mtp-source.c	(working copy)
@@ -73,10 +73,21 @@ static char* impl_build_dest_uri (RBRemo
 
 static RhythmDB * get_db_for_source (RBMtpSource *source);
 
+
+
+typedef struct {
+	LIBMTP_track_t *track;
+	int fd[2];
+} TrackTransferData;
+
+static void _free_track_transfer_data (TrackTransferData *data);
+
+
 typedef struct
 {
 	LIBMTP_mtpdevice_t *device;
 	GHashTable *entry_map;
+	GHashTable *active_transfers;
 	char *udi;
 } RBMtpSourcePrivate;
 
@@ -142,6 +153,10 @@ rb_mtp_source_init (RBMtpSource *source)
 
 	priv->entry_map = g_hash_table_new (g_direct_hash,
 					    g_direct_equal);
+	priv->active_transfers = g_hash_table_new_full (g_direct_hash,
+							g_direct_equal,
+							(GDestroyNotify)rhythmdb_entry_unref,
+							(GDestroyNotify)_free_track_transfer_data);
 
 	g_signal_connect (G_OBJECT (source), "notify::name",
 			  (GCallback)rb_mtp_source_name_changed_cb, NULL);
@@ -178,6 +193,13 @@ rb_mtp_source_constructor (GType type, g
 static void
 rb_mtp_source_finalize (GObject *object)
 {
+	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (object);
+
+	g_hash_table_destroy (priv->entry_map);
+	g_hash_table_destroy (priv->active_transfers);
+
+	g_free (priv->udi);
+
 	G_OBJECT_CLASS (rb_mtp_source_parent_class)->finalize (object);
 }
 
@@ -643,44 +665,6 @@ get_db_for_source (RBMtpSource *source)
 	return db;
 }
 
-static LIBMTP_track_t *
-transfer_track (RBMtpSource *source,
-		LIBMTP_mtpdevice_t *device,
-		RhythmDBEntry *entry,
-		const char *filename,
-		const char *mimetype)
-{
-	LIBMTP_track_t *trackmeta = LIBMTP_new_track_t ();
-	GDate d;
-
-	trackmeta->title = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_TITLE);
-	trackmeta->album = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ALBUM);
-	trackmeta->artist = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ARTIST);
-	trackmeta->genre = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_GENRE);
-	trackmeta->filename = g_strdup (filename);
-
-	if (rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DATE) > 0) { /* Entries without a date returns 0, g_date_set_julian don't accept that */
-		g_date_set_julian (&d, rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DATE));
-		trackmeta->date	= gdate_to_char (&d);
-	}
-	trackmeta->tracknumber = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_TRACK_NUMBER);
-	trackmeta->duration = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DURATION) * 1000;
-	trackmeta->filesize = rhythmdb_entry_get_uint64 (entry, RHYTHMDB_PROP_FILE_SIZE);
-	if (mimetype == NULL) {
-		trackmeta->filetype = mimetype_to_filetype (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MIMETYPE));
-	} else {
-		trackmeta->filetype = mimetype_to_filetype (mimetype);
-	}
-
-	if (LIBMTP_Send_Track_From_File (device, filename, trackmeta, NULL, NULL, 0) != 0) {
-		LIBMTP_destroy_track_t (trackmeta);
-		rb_debug ("Tracktransfer failed\n");
-		return NULL;
-	}
-
-	return trackmeta;
-}
-
 static GList *
 impl_get_mime_types (RBRemovableMediaSource *source)
 {
@@ -705,6 +689,15 @@ impl_get_mime_types (RBRemovableMediaSou
 	return list;
 }
 
+
+
+static void
+_free_track_transfer_data (TrackTransferData *data)
+{
+	close (data->fd[1]);
+	close (data->fd[0]);
+}
+
 static gboolean
 impl_track_added (RBRemovableMediaSource *isource,
 		  RhythmDBEntry *entry,
@@ -713,19 +706,19 @@ impl_track_added (RBRemovableMediaSource
 {
 	RBMtpSource *source = RB_MTP_SOURCE (isource);
 	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
-	char *filename = NULL;
-	LIBMTP_track_t *track = NULL;
+	TrackTransferData *data;
 
-	filename = g_filename_from_uri (dest, NULL, NULL);
-	track = transfer_track (source, priv->device, entry, filename, mimetype);
-	gnome_vfs_unlink (filename);
-	g_free (filename);
-
-	if (track != NULL) {
-		/*request_artwork (isource, entry, song);*/
-		add_mtp_track_to_db (source, track);
+	data = g_hash_table_lookup (priv->active_transfers, entry);
+	if (data == NULL) {
+		rb_debug ("couldn't find transfer data for added track");
+		return FALSE;
 	}
 
+	g_hash_table_remove (priv->active_transfers, entry);
+
+	/*request_artwork (isource, entry, song);*/
+	add_mtp_track_to_db (source, data->track);
+
 	return FALSE;
 }
 
@@ -735,12 +728,54 @@ impl_build_dest_uri (RBRemovableMediaSou
 		     const char *mimetype,
 		     const char *extension)
 {
-	char* file = g_strdup_printf ("%s/%s-%s.%s", g_get_tmp_dir (),
-				      rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ARTIST),
-				      rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_TITLE),
-				      extension);
-	char* uri = g_filename_to_uri (file, NULL, NULL);
-	g_free (file);
-	return uri;
+	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
+	TrackTransferData *data;
+	char *fd_uri;
+	char *temp;
+	GDate d;
+
+	data = g_new0 (TrackTransferData, 1);
+	data->track = LIBMTP_new_track_t ();
+
+	data->track->title = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_TITLE);
+	data->track->album = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ALBUM);
+	data->track->artist = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ARTIST);
+	data->track->genre = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_GENRE);
+
+	temp = g_filename_from_uri (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION), NULL, NULL);
+	data->track->filename = g_path_get_basename (temp);
+	g_free (temp);
+
+	/* Entries without a date returns 0, g_date_set_julian don't accept that */
+	if (rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DATE) > 0) {
+		g_date_set_julian (&d, rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DATE));
+		data->track->date = gdate_to_char (&d);
+	}
+	data->track->tracknumber = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_TRACK_NUMBER);
+	data->track->duration = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DURATION) * 1000;
+	data->track->filesize = rhythmdb_entry_get_uint64 (entry, RHYTHMDB_PROP_FILE_SIZE);
+	if (mimetype == NULL) {
+		data->track->filetype = mimetype_to_filetype (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MIMETYPE));
+	} else {
+		data->track->filetype = mimetype_to_filetype (mimetype);
+	}
+
+	/* create a pipe, and use it to send data from the encoder to libmtp */
+	pipe (data->fd);
+	if (LIBMTP_Send_Track_From_File_Descriptor (priv->device, data->fd[0], data->track, NULL, NULL, 0) != 0) {
+		rb_debug ("Track transfer failed");
+
+		LIBMTP_destroy_track_t (data->track);
+		_free_track_transfer_data (data);
+		return NULL;
+	}
+
+	fd_uri = g_strdup_printf ("fd://%d", data->fd[1]);
+	rb_debug ("prepared for transfer of %s to %s",
+			rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION),
+			fd_uri);
+	g_hash_table_insert (priv->active_transfers, rhythmdb_entry_ref (entry), data);
+
+	return fd_uri;
 }
 
