libgnomevfs2-mythtv/modules/mythtv-method.c
branchtrunk
changeset 114 04cead6ae39b
parent 48 a30f59f76bda
child 116 e3cedfae0f2e
     1.1 --- a/libgnomevfs2-mythtv/modules/mythtv-method.c	Tue Oct 24 15:34:48 2006 +0100
     1.2 +++ b/libgnomevfs2-mythtv/modules/mythtv-method.c	Mon Nov 27 19:24:43 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 |