1.1 --- a/libgnomevfs2-mythtv/modules/mythtv-method.c Fri Nov 24 18:51:42 2006 +0000
1.2 +++ b/libgnomevfs2-mythtv/modules/mythtv-method.c Fri Nov 24 21:19:49 2006 +0000
1.3 @@ -32,6 +32,8 @@
1.4 #define GST_MYTHTV_ID_NUM 1
1.5 #define MYTHTV_VERSION_DEFAULT 30
1.6
1.7 +#define MYTHTV_BUFFER_SIZE 1024*64
1.8 +
1.9 static GnomeVFSResult do_read (GnomeVFSMethod *method,
1.10 GnomeVFSMethodHandle *method_handle,
1.11 gpointer buffer,
1.12 @@ -45,8 +47,10 @@
1.13 gint mythtv_version;
1.14 guint64 content_size;
1.15 guint64 bytes_read;
1.16 - guint64 read_offset;
1.17 - gboolean live_tv;
1.18 +
1.19 + guint8 *buffer;
1.20 + gsize buffer_offset;
1.21 + gsize buffer_remain;
1.22 } MythtvHandle;
1.23
1.24
1.25 @@ -58,9 +62,11 @@
1.26 GnomeVFSOpenMode mode,
1.27 GnomeVFSContext *context)
1.28 {
1.29 - MythtvHandle *myth_handle = g_new0 (MythtvHandle, 1);
1.30
1.31 const gchar *user, *password, *host, *transfer_uri;
1.32 + MythtvHandle *myth_handle;
1.33 +
1.34 + GString *uri_str;
1.35 guint port;
1.36 gchar *path;
1.37 gboolean ret;
1.38 @@ -68,6 +74,10 @@
1.39 _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL);
1.40 _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL);
1.41
1.42 + g_debug ("[%s] Calling do_open function", __FUNCTION__);
1.43 +
1.44 + myth_handle = g_new0 (MythtvHandle, 1);
1.45 +
1.46 if (mode & GNOME_VFS_OPEN_WRITE) {
1.47 return GNOME_VFS_ERROR_NOT_PERMITTED;
1.48 }
1.49 @@ -90,35 +100,28 @@
1.50 myth_handle->mythtv_version = MYTHTV_VERSION_DEFAULT;
1.51 myth_handle->bytes_read = 0;
1.52 myth_handle->content_size = -1;
1.53 - myth_handle->read_offset = 0;
1.54 - myth_handle->live_tv = FALSE;
1.55
1.56 /* Connect to the backend */
1.57 - myth_handle->file_transfer = gmyth_file_transfer_new ( GST_MYTHTV_ID_NUM /*mythtv->live_tv_id*/,
1.58 - g_string_new( transfer_uri ), -1, myth_handle->mythtv_version );
1.59 + myth_handle->file_transfer = gmyth_file_transfer_new ();
1.60
1.61 - if ( myth_handle->file_transfer == NULL ) {
1.62 - return GNOME_VFS_ERROR_NOT_OPEN;
1.63 - }
1.64 + g_return_val_if_fail (myth_handle->file_transfer != NULL, GNOME_VFS_ERROR_NOT_OPEN);
1.65
1.66 /* sets the Playback monitor connection */
1.67 - ret = gmyth_file_transfer_playback_setup( &(myth_handle->file_transfer), myth_handle->live_tv );
1.68 + uri_str = g_string_new (transfer_uri);
1.69 + ret = gmyth_file_transfer_open (myth_handle->file_transfer, uri_str);
1.70 if (ret == FALSE) {
1.71 - g_printerr ("Mythtv FileTransfer playback setup error\n");
1.72 - return GNOME_VFS_ERROR_NOT_OPEN;
1.73 + g_printerr ("Mythtv FileTransfer open error\n");
1.74 + return GNOME_VFS_ERROR_NOT_OPEN;
1.75 }
1.76 -
1.77 - /* sets the FileTransfer instance connection (video/audio download) */
1.78 - ret = gmyth_file_transfer_setup( &(myth_handle->file_transfer), myth_handle->live_tv );
1.79 -
1.80 - if ( ret == FALSE ) {
1.81 - g_printerr ("MythTV FileTransfer request failed when setting up socket connection!\n" );
1.82 - return GNOME_VFS_ERROR_NOT_OPEN;
1.83 - }
1.84 + g_string_free (uri_str, TRUE);
1.85
1.86 // TODO: Verify if file exists in the backend
1.87
1.88 myth_handle->content_size = myth_handle->file_transfer->filesize;
1.89 +
1.90 + myth_handle->buffer = g_malloc0 (MYTHTV_BUFFER_SIZE);
1.91 + myth_handle->buffer_offset = 0;
1.92 + myth_handle->buffer_remain = 0;
1.93
1.94 *method_handle = (GnomeVFSMethodHandle *) myth_handle;
1.95
1.96 @@ -134,11 +137,11 @@
1.97 GnomeVFSContext *context)
1.98 {
1.99 MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
1.100 - guint len = 0, offset = 0;
1.101 GnomeVFSFileSize bytes_to_read;
1.102
1.103 - g_debug ("do_read(): file size: %llu, already read: %llu, requested: %llu", myth_handle->content_size,
1.104 - myth_handle->bytes_read, num_bytes);
1.105 + g_debug ("do_read(): file size: %llu, already read: %llu, requested: %llu, buffer_offset: %du, buffer_remain: %du",
1.106 + myth_handle->content_size, myth_handle->bytes_read, num_bytes,
1.107 + myth_handle->buffer_offset, myth_handle->buffer_remain);
1.108
1.109 *bytes_read = 0;
1.110
1.111 @@ -154,28 +157,43 @@
1.112 /* Loop sending the Myth File Transfer request:
1.113 * Retry whilst authentication fails and we supply it. */
1.114
1.115 - // lock here ???
1.116 - while ( bytes_to_read > 0 ) {
1.117 - len = gmyth_file_transfer_read( myth_handle->file_transfer,
1.118 - buffer + offset, bytes_to_read, TRUE );
1.119 + if (bytes_to_read > myth_handle->buffer_remain ) {
1.120 + guint8 *tmp_buffer = g_malloc0 (MYTHTV_BUFFER_SIZE);
1.121 + gint len;
1.122
1.123 - if ( len > 0 ) {
1.124 - offset += len;
1.125 - bytes_to_read -= len;
1.126 - } else {
1.127 - break;
1.128 - }
1.129 + if (myth_handle->buffer_remain > (MYTHTV_BUFFER_SIZE >> 1)) {
1.130 + // Avoid overlap creating another buffer, in the case the remaining data is bigger than half buffer size
1.131 + tmp_buffer = g_malloc0 (MYTHTV_BUFFER_SIZE);
1.132 + memcpy (tmp_buffer, myth_handle->buffer + myth_handle->buffer_offset, myth_handle->buffer_remain);
1.133 + g_free (myth_handle->buffer);
1.134 + myth_handle->buffer = tmp_buffer;
1.135 + } else {
1.136 + memcpy (myth_handle->buffer, myth_handle->buffer + myth_handle->buffer_offset, myth_handle->buffer_remain);
1.137 + }
1.138 +
1.139 + g_debug ("Reading %d data from backend", MYTHTV_BUFFER_SIZE- myth_handle->buffer_remain);
1.140 +
1.141 + len = gmyth_file_transfer_read( myth_handle->file_transfer,
1.142 + myth_handle->buffer + myth_handle->buffer_remain,
1.143 + MYTHTV_BUFFER_SIZE- myth_handle->buffer_remain, TRUE );
1.144 +
1.145 + if (len < 0)
1.146 + return GNOME_VFS_ERROR_IO;
1.147 +
1.148 + myth_handle->buffer_offset = 0;
1.149 + myth_handle->buffer_remain += len;
1.150 +
1.151 + }
1.152
1.153 - if ( offset == num_bytes )
1.154 - break;
1.155 - }
1.156 + bytes_to_read = (bytes_to_read > myth_handle->buffer_remain) ? myth_handle->buffer_remain : bytes_to_read;
1.157 +
1.158 + g_debug ("Returning %du bytes to gnomevfs", (int) bytes_to_read);
1.159 + memcpy (buffer, myth_handle->buffer + myth_handle->buffer_offset, bytes_to_read);
1.160
1.161 - if (( offset <= 0 ) && !myth_handle->live_tv )
1.162 - return GNOME_VFS_ERROR_EOF;
1.163 -
1.164 - myth_handle->read_offset += offset;
1.165 - myth_handle->bytes_read += offset;
1.166 - *bytes_read = offset;
1.167 + myth_handle->bytes_read += bytes_to_read;
1.168 + myth_handle->buffer_offset += bytes_to_read;
1.169 + myth_handle->buffer_remain -= bytes_to_read;
1.170 + *bytes_read = bytes_to_read;
1.171
1.172 return GNOME_VFS_OK;
1.173 }
1.174 @@ -185,10 +203,14 @@
1.175 GnomeVFSMethodHandle *method_handle,
1.176 GnomeVFSContext *context)
1.177 {
1.178 +
1.179 MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
1.180
1.181 - if (myth_handle->file_transfer)
1.182 + if (myth_handle->file_transfer) {
1.183 + gmyth_file_transfer_close (myth_handle->file_transfer);
1.184 g_object_unref (myth_handle->file_transfer);
1.185 + myth_handle->file_transfer = NULL;
1.186 + }
1.187
1.188 g_free (myth_handle);
1.189
1.190 @@ -202,14 +224,14 @@
1.191 GnomeVFSFileInfoOptions options,
1.192 GnomeVFSContext *context)
1.193 {
1.194 - GString *name = g_string_new ("hallyson");
1.195 - file_info->name = g_string_free (name, FALSE);//"hallyson.txt";//get_base_from_uri (uri);
1.196 + file_info->name = g_strdup ("fixme.txt");
1.197 file_info->valid_fields = file_info->valid_fields
1.198 | GNOME_VFS_FILE_INFO_FIELDS_TYPE
1.199 | GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE
1.200 | GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
1.201 file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
1.202 - file_info->mime_type = "video/x-nuv"; //g_strdup (gnome_vfs_mime_type_from_name (file_info->name));
1.203 + // fixme: get from file extension?
1.204 + file_info->mime_type = g_strdup ("video/x-nuv");
1.205 file_info->permissions =
1.206 GNOME_VFS_PERM_USER_READ |
1.207 GNOME_VFS_PERM_OTHER_READ |