diff -r a30f59f76bda -r 04cead6ae39b libgnomevfs2-mythtv/modules/mythtv-method.c --- a/libgnomevfs2-mythtv/modules/mythtv-method.c Tue Oct 24 15:34:48 2006 +0100 +++ b/libgnomevfs2-mythtv/modules/mythtv-method.c Mon Nov 27 19:24:43 2006 +0000 @@ -32,6 +32,8 @@ #define GST_MYTHTV_ID_NUM 1 #define MYTHTV_VERSION_DEFAULT 30 +#define MYTHTV_BUFFER_SIZE 1024*64 + static GnomeVFSResult do_read (GnomeVFSMethod *method, GnomeVFSMethodHandle *method_handle, gpointer buffer, @@ -45,8 +47,10 @@ gint mythtv_version; guint64 content_size; guint64 bytes_read; - guint64 read_offset; - gboolean live_tv; + + guint8 *buffer; + gsize buffer_offset; + gsize buffer_remain; } MythtvHandle; @@ -58,9 +62,11 @@ GnomeVFSOpenMode mode, GnomeVFSContext *context) { - MythtvHandle *myth_handle = g_new0 (MythtvHandle, 1); const gchar *user, *password, *host, *transfer_uri; + MythtvHandle *myth_handle; + + GString *uri_str; guint port; gchar *path; gboolean ret; @@ -68,6 +74,10 @@ _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL); _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL); + g_debug ("[%s] Calling do_open function", __FUNCTION__); + + myth_handle = g_new0 (MythtvHandle, 1); + if (mode & GNOME_VFS_OPEN_WRITE) { return GNOME_VFS_ERROR_NOT_PERMITTED; } @@ -90,35 +100,28 @@ myth_handle->mythtv_version = MYTHTV_VERSION_DEFAULT; myth_handle->bytes_read = 0; myth_handle->content_size = -1; - myth_handle->read_offset = 0; - myth_handle->live_tv = FALSE; /* Connect to the backend */ - myth_handle->file_transfer = gmyth_file_transfer_new ( GST_MYTHTV_ID_NUM /*mythtv->live_tv_id*/, - g_string_new( transfer_uri ), -1, myth_handle->mythtv_version ); + myth_handle->file_transfer = gmyth_file_transfer_new (); - if ( myth_handle->file_transfer == NULL ) { - return GNOME_VFS_ERROR_NOT_OPEN; - } + g_return_val_if_fail (myth_handle->file_transfer != NULL, GNOME_VFS_ERROR_NOT_OPEN); /* sets the Playback monitor connection */ - ret = gmyth_file_transfer_playback_setup( &(myth_handle->file_transfer), myth_handle->live_tv ); + uri_str = g_string_new (transfer_uri); + ret = gmyth_file_transfer_open (myth_handle->file_transfer, uri_str); if (ret == FALSE) { - g_printerr ("Mythtv FileTransfer playback setup error\n"); - return GNOME_VFS_ERROR_NOT_OPEN; + g_printerr ("Mythtv FileTransfer open error\n"); + return GNOME_VFS_ERROR_NOT_OPEN; } - - /* sets the FileTransfer instance connection (video/audio download) */ - ret = gmyth_file_transfer_setup( &(myth_handle->file_transfer), myth_handle->live_tv ); - - if ( ret == FALSE ) { - g_printerr ("MythTV FileTransfer request failed when setting up socket connection!\n" ); - return GNOME_VFS_ERROR_NOT_OPEN; - } + g_string_free (uri_str, TRUE); // TODO: Verify if file exists in the backend myth_handle->content_size = myth_handle->file_transfer->filesize; + + myth_handle->buffer = g_malloc0 (MYTHTV_BUFFER_SIZE); + myth_handle->buffer_offset = 0; + myth_handle->buffer_remain = 0; *method_handle = (GnomeVFSMethodHandle *) myth_handle; @@ -134,11 +137,11 @@ GnomeVFSContext *context) { MythtvHandle *myth_handle = (MythtvHandle *) method_handle; - guint len = 0, offset = 0; GnomeVFSFileSize bytes_to_read; - g_debug ("do_read(): file size: %llu, already read: %llu, requested: %llu", myth_handle->content_size, - myth_handle->bytes_read, num_bytes); + g_debug ("do_read(): file size: %llu, already read: %llu, requested: %llu, buffer_offset: %du, buffer_remain: %du", + myth_handle->content_size, myth_handle->bytes_read, num_bytes, + myth_handle->buffer_offset, myth_handle->buffer_remain); *bytes_read = 0; @@ -154,28 +157,43 @@ /* Loop sending the Myth File Transfer request: * Retry whilst authentication fails and we supply it. */ - // lock here ??? - while ( bytes_to_read > 0 ) { - len = gmyth_file_transfer_read( myth_handle->file_transfer, - buffer + offset, bytes_to_read, TRUE ); + if (bytes_to_read > myth_handle->buffer_remain ) { + guint8 *tmp_buffer = g_malloc0 (MYTHTV_BUFFER_SIZE); + gint len; - if ( len > 0 ) { - offset += len; - bytes_to_read -= len; - } else { - break; - } + if (myth_handle->buffer_remain > (MYTHTV_BUFFER_SIZE >> 1)) { + // Avoid overlap creating another buffer, in the case the remaining data is bigger than half buffer size + tmp_buffer = g_malloc0 (MYTHTV_BUFFER_SIZE); + memcpy (tmp_buffer, myth_handle->buffer + myth_handle->buffer_offset, myth_handle->buffer_remain); + g_free (myth_handle->buffer); + myth_handle->buffer = tmp_buffer; + } else { + memcpy (myth_handle->buffer, myth_handle->buffer + myth_handle->buffer_offset, myth_handle->buffer_remain); + } + + g_debug ("Reading %d data from backend", MYTHTV_BUFFER_SIZE- myth_handle->buffer_remain); + + len = gmyth_file_transfer_read( myth_handle->file_transfer, + myth_handle->buffer + myth_handle->buffer_remain, + MYTHTV_BUFFER_SIZE- myth_handle->buffer_remain, TRUE ); + + if (len < 0) + return GNOME_VFS_ERROR_IO; + + myth_handle->buffer_offset = 0; + myth_handle->buffer_remain += len; + + } - if ( offset == num_bytes ) - break; - } + bytes_to_read = (bytes_to_read > myth_handle->buffer_remain) ? myth_handle->buffer_remain : bytes_to_read; + + g_debug ("Returning %du bytes to gnomevfs", (int) bytes_to_read); + memcpy (buffer, myth_handle->buffer + myth_handle->buffer_offset, bytes_to_read); - if (( offset <= 0 ) && !myth_handle->live_tv ) - return GNOME_VFS_ERROR_EOF; - - myth_handle->read_offset += offset; - myth_handle->bytes_read += offset; - *bytes_read = offset; + myth_handle->bytes_read += bytes_to_read; + myth_handle->buffer_offset += bytes_to_read; + myth_handle->buffer_remain -= bytes_to_read; + *bytes_read = bytes_to_read; return GNOME_VFS_OK; } @@ -185,10 +203,14 @@ GnomeVFSMethodHandle *method_handle, GnomeVFSContext *context) { + MythtvHandle *myth_handle = (MythtvHandle *) method_handle; - if (myth_handle->file_transfer) + if (myth_handle->file_transfer) { + gmyth_file_transfer_close (myth_handle->file_transfer); g_object_unref (myth_handle->file_transfer); + myth_handle->file_transfer = NULL; + } g_free (myth_handle); @@ -202,14 +224,14 @@ GnomeVFSFileInfoOptions options, GnomeVFSContext *context) { - GString *name = g_string_new ("hallyson"); - file_info->name = g_string_free (name, FALSE);//"hallyson.txt";//get_base_from_uri (uri); + file_info->name = g_strdup ("fixme.txt"); file_info->valid_fields = file_info->valid_fields | GNOME_VFS_FILE_INFO_FIELDS_TYPE | GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE | GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS; file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; - file_info->mime_type = "video/x-nuv"; //g_strdup (gnome_vfs_mime_type_from_name (file_info->name)); + // fixme: get from file extension? + file_info->mime_type = g_strdup ("video/x-nuv"); file_info->permissions = GNOME_VFS_PERM_USER_READ | GNOME_VFS_PERM_OTHER_READ |