libgnomevfs2-mythtv/modules/mythtv-method.c
author rosfran
Wed Feb 14 21:35:23 2007 +0000 (2007-02-14)
branchtrunk
changeset 361 7140b2c2e63c
parent 357 194c44ef8da4
child 363 49e3e9bfc3ab
permissions -rwxr-xr-x
[svn r363] Optimizations on the GnomeVFS internal buffer filling.
melunko@38
     1
/*
melunko@38
     2
 * @author Hallyson Melo <hallyson.melo@indt.org.br>
melunko@38
     3
 *
melunko@38
     4
 * This program is free software; you can redistribute it and/or modify
melunko@38
     5
 * it under the terms of the GNU Lesser General Public License as published by
melunko@38
     6
 * the Free Software Foundation; either version 2 of the License, or
melunko@38
     7
 * (at your option) any later version.
melunko@38
     8
 *
melunko@38
     9
 * This program is distributed in the hope that it will be useful,
melunko@38
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
melunko@38
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
melunko@38
    12
 * GNU General Public License for more details.
melunko@38
    13
 *
melunko@38
    14
 * You should have received a copy of the GNU Lesser General Public License
melunko@38
    15
 * along with this program; if not, write to the Free Software
melunko@38
    16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
melunko@38
    17
 */
melunko@38
    18
melunko@38
    19
#ifdef HAVE_CONFIG_H
melunko@38
    20
#include <config.h>
melunko@38
    21
#endif
melunko@38
    22
melunko@38
    23
#include <string.h>
melunko@38
    24
#include <glib.h>
melunko@38
    25
#include <math.h>
melunko@38
    26
melunko@38
    27
#include <libgnomevfs/gnome-vfs-module.h>
melunko@38
    28
#include <libgnomevfs/gnome-vfs-utils.h>
melunko@38
    29
rosfran@277
    30
#include <gmyth/gmyth_file_transfer.h>
rosfran@277
    31
#include <gmyth/gmyth_livetv.h>
rosfran@277
    32
#include <gmyth/gmyth_uri.h>
rosfran@277
    33
#include <gmyth/gmyth_recorder.h>
rosfran@277
    34
#include <gmyth/gmyth_backendinfo.h>
rosfran@277
    35
#include <gmyth/gmyth_util.h>
rosfran@332
    36
#include <gmyth/gmyth_remote_util.h>
rosfran@332
    37
#include <gmyth/gmyth_tvchain.h>
rosfran@357
    38
#include <gmyth/gmyth_programinfo.h>
melunko@38
    39
melunko@38
    40
#define GST_MYTHTV_ID_NUM               1
melunko@38
    41
#define MYTHTV_VERSION_DEFAULT          30
rosfran@277
    42
#define MYTHTV_TRANSFER_MAX_WAITS       100
melunko@38
    43
rosfran@361
    44
/* internal GnomeVFS plug-in buffer size ( 120 Kbytes ) */
rosfran@361
    45
#define MYTHTV_BUFFER_SIZE							1024*120
rosfran@361
    46
/* internally sized GnomeVFS plug-in buffer ( 4 Kbytes ) */
rosfran@354
    47
#define MYTHTV_MAX_VFS_BUFFER_SIZE			4096
rosfran@361
    48
/* maximum number of bytes to be requested to the MythTV backend ( 64 Kbytes ) */
rosfran@354
    49
#define MYTHTV_MAX_REQUEST_SIZE					1024*64
melunko@111
    50
melunko@38
    51
static GnomeVFSResult do_read (GnomeVFSMethod *method,
melunko@38
    52
                               GnomeVFSMethodHandle *method_handle,
melunko@38
    53
                               gpointer buffer,
melunko@38
    54
                               GnomeVFSFileSize num_bytes,
melunko@38
    55
                               GnomeVFSFileSize *bytes_read,
melunko@38
    56
                               GnomeVFSContext *context);
melunko@38
    57
melunko@38
    58
typedef struct {
melunko@48
    59
    GMythFileTransfer *file_transfer;
rosfran@277
    60
    GMythLiveTV 			*livetv;
rosfran@327
    61
    gchar 						*channel_name;
melunko@38
    62
    
melunko@38
    63
    gint mythtv_version;
rosfran@297
    64
    gint64 content_size;
melunko@38
    65
    guint64 bytes_read;
melunko@111
    66
rosfran@116
    67
    GByteArray *buffer;
melunko@111
    68
    gsize buffer_remain;
rosfran@338
    69
    gboolean	is_livetv;
rosfran@338
    70
    
rosfran@357
    71
    gboolean configured;
rosfran@357
    72
    
melunko@38
    73
} MythtvHandle;
melunko@38
    74
rosfran@357
    75
//static MythtvHandle *myth_handle = NULL;
rosfran@357
    76
melunko@38
    77
static GnomeVFSResult
melunko@38
    78
do_open (GnomeVFSMethod *method,
melunko@38
    79
         GnomeVFSMethodHandle **method_handle,
melunko@38
    80
         GnomeVFSURI *uri,
melunko@38
    81
         GnomeVFSOpenMode mode,
melunko@38
    82
         GnomeVFSContext *context)
rosfran@357
    83
{ 
rosfran@357
    84
		MythtvHandle *myth_handle = NULL;   
rosfran@357
    85
    GMythBackendInfo *backend_info = NULL;
rosfran@277
    86
    GMythURI *gmyth_uri = NULL;
rosfran@277
    87
    gboolean ret = TRUE;
melunko@38
    88
melunko@38
    89
    _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL);
melunko@38
    90
    _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL);
melunko@38
    91
melunko@38
    92
    if (mode & GNOME_VFS_OPEN_WRITE) {
melunko@38
    93
        return GNOME_VFS_ERROR_NOT_PERMITTED;
melunko@38
    94
    }
melunko@38
    95
renatofilho@149
    96
    if (gnome_vfs_uri_get_host_name (uri) == NULL) {
renatofilho@149
    97
    	return GNOME_VFS_ERROR_INVALID_HOST_NAME;
melunko@38
    98
    }
rosfran@357
    99
    
rosfran@357
   100
    /*
rosfran@357
   101
    if ( method_handle != NULL && *method_handle != NULL )
rosfran@357
   102
    {
rosfran@357
   103
    	myth_handle = (MythtvHandle*)*method_handle;
rosfran@357
   104
    	//if ( !myth_handle->configured )    	
rosfran@357
   105
    }
rosfran@357
   106
    */
rosfran@357
   107
    
rosfran@357
   108
    if ( ( NULL == myth_handle ) || !myth_handle->configured ) {
rosfran@357
   109
    	myth_handle = g_new0 (MythtvHandle, 1);
rosfran@357
   110
    	
rosfran@357
   111
    	myth_handle->configured = FALSE;
rosfran@357
   112
	    
rosfran@357
   113
	    myth_handle->is_livetv = FALSE;
rosfran@357
   114
	    
rosfran@357
   115
	    /* Initialize mythtv handler*/
rosfran@357
   116
	    myth_handle->file_transfer = NULL;
rosfran@357
   117
	    myth_handle->livetv = NULL;
rosfran@357
   118
	    myth_handle->mythtv_version = MYTHTV_VERSION_DEFAULT;
rosfran@357
   119
	    myth_handle->bytes_read = 0;
rosfran@357
   120
	    myth_handle->content_size = (GnomeVFSFileSize) - 1;
rosfran@357
   121
	
rosfran@357
   122
	    /* Creates and fills out the backend info structure */    
rosfran@357
   123
		  backend_info = gmyth_backend_info_new_with_uri ( 
rosfran@357
   124
		  			gnome_vfs_unescape_string( gnome_vfs_uri_to_string( uri, GNOME_VFS_URI_HIDE_NONE ), "" ) );
rosfran@357
   125
		  
rosfran@357
   126
		  /* creates an instance of  */  
rosfran@357
   127
		  gmyth_uri = gmyth_uri_new_with_value( 
rosfran@357
   128
		  		gnome_vfs_unescape_string( gnome_vfs_uri_to_string( uri, GNOME_VFS_URI_HIDE_NONE ), "" ) );
rosfran@357
   129
	
rosfran@357
   130
		  myth_handle->is_livetv = gmyth_uri_is_livetv( gmyth_uri );
rosfran@357
   131
	
rosfran@357
   132
		  /* Connect to the backend */	  
rosfran@357
   133
		  if ( gmyth_uri != NULL && myth_handle->is_livetv == TRUE ) {
rosfran@357
   134
		  	
rosfran@357
   135
		  	if ( NULL == myth_handle->livetv )
rosfran@357
   136
		  	{
rosfran@357
   137
		    	myth_handle->livetv = gmyth_livetv_new ();
rosfran@357
   138
		    
rosfran@357
   139
			    myth_handle->channel_name = gmyth_uri_get_channel_name( gmyth_uri );
rosfran@357
   140
			    
rosfran@357
   141
			    g_debug( "[%s] Channel name = %s\n", __FUNCTION__, myth_handle->channel_name );
rosfran@357
   142
			
rosfran@357
   143
			    if ( myth_handle->channel_name != NULL ) {
rosfran@357
   144
			      if (gmyth_livetv_channel_name_setup (myth_handle->livetv, myth_handle->channel_name,
rosfran@357
   145
			              backend_info) == FALSE) {
rosfran@357
   146
			        g_object_unref( gmyth_uri );
rosfran@357
   147
			        ret = FALSE;
rosfran@357
   148
			      }
rosfran@357
   149
			    } else {
rosfran@357
   150
			      if ( gmyth_livetv_setup (myth_handle->livetv, backend_info) == FALSE ) {
rosfran@357
   151
			      	g_object_unref( gmyth_uri );
rosfran@357
   152
			        ret = FALSE;
rosfran@357
   153
			      }
rosfran@357
   154
			    }
rosfran@357
   155
		  	}
rosfran@357
   156
		  	
rosfran@357
   157
		  	if ( NULL == myth_handle->file_transfer )	{
rosfran@357
   158
		    	myth_handle->file_transfer = gmyth_livetv_create_file_transfer (myth_handle->livetv);
rosfran@357
   159
		
rosfran@357
   160
			    if (NULL == myth_handle->file_transfer) {
rosfran@357
   161
			      ret = FALSE;
rosfran@357
   162
				    g_debug ("MythTV FileTransfer is NULL!\n");
rosfran@357
   163
				    return GNOME_VFS_ERROR_NOT_OPEN;
rosfran@357
   164
			    }
rosfran@357
   165
			    
rosfran@357
   166
		  		if ( !gmyth_file_transfer_open( myth_handle->file_transfer, myth_handle->livetv->uri != NULL ? 
rosfran@357
   167
										gmyth_uri_get_path(myth_handle->livetv->uri) : 
rosfran@357
   168
										myth_handle->livetv->proginfo->pathname->str ) )
rosfran@357
   169
					{
rosfran@357
   170
						g_debug ("Couldn't open MythTV FileTransfer is NULL!\n");
rosfran@357
   171
						g_object_unref( myth_handle->file_transfer );
rosfran@357
   172
						myth_handle->file_transfer = NULL;
rosfran@357
   173
						ret = FALSE;
rosfran@357
   174
					}
rosfran@357
   175
		  	} /* if - FileTransfer is NULL, or not */
rosfran@357
   176
		    
rosfran@357
   177
		  } else {
rosfran@357
   178
		  	
rosfran@357
   179
		  	if (NULL == myth_handle->file_transfer ) {
rosfran@357
   180
		
rosfran@357
   181
			    myth_handle->file_transfer = gmyth_file_transfer_new (backend_info);
rosfran@357
   182
			    
rosfran@357
   183
			    /* Verifies if the file exists */
rosfran@357
   184
			    if (!gmyth_util_file_exists (backend_info, gmyth_uri_get_path (gmyth_uri))) {
rosfran@357
   185
			        g_object_unref (backend_info);
rosfran@357
   186
							ret = FALSE;
rosfran@357
   187
			    }
rosfran@357
   188
			    
rosfran@357
   189
			    /* sets the Playback monitor connection */
rosfran@357
   190
			    ret = gmyth_file_transfer_open ( myth_handle->file_transfer, 
rosfran@357
   191
			    		gmyth_uri_get_path (gmyth_uri) );
rosfran@357
   192
			    		
rosfran@357
   193
		  	}
rosfran@357
   194
			
rosfran@357
   195
		  } /* if - LiveTV or not? */
rosfran@357
   196
		  
rosfran@357
   197
	    if (ret == FALSE) {
rosfran@357
   198
		    g_debug ("MythTV FileTransfer open error.\n");
rosfran@357
   199
		    return GNOME_VFS_ERROR_NOT_OPEN;
rosfran@357
   200
		  }
rosfran@357
   201
		  
rosfran@357
   202
		  myth_handle->configured = TRUE;
rosfran@357
   203
	
rosfran@357
   204
	    g_object_unref (backend_info);
rosfran@357
   205
	    
rosfran@357
   206
		  if ( gmyth_uri != NULL )
rosfran@357
   207
		  	g_object_unref( gmyth_uri );
rosfran@357
   208
		  
rosfran@357
   209
	    myth_handle->buffer = g_byte_array_sized_new (MYTHTV_BUFFER_SIZE);
rosfran@357
   210
	    myth_handle->buffer_remain = 0;
rosfran@357
   211
	    
rosfran@357
   212
		  g_return_val_if_fail (myth_handle->file_transfer != NULL, GNOME_VFS_ERROR_NOT_OPEN);
rosfran@357
   213
		  
rosfran@357
   214
		  if ( /*myth_handle->file_transfer->filesize <= 0 && */myth_handle->is_livetv ) {
rosfran@357
   215
		  	myth_handle->content_size = gmyth_recorder_get_file_position(myth_handle->livetv->recorder);
rosfran@357
   216
		  } else {
rosfran@357
   217
	    	myth_handle->content_size = myth_handle->file_transfer->filesize;
rosfran@357
   218
		  }
rosfran@357
   219
		  
rosfran@357
   220
    } /* if - configured or not? */
rosfran@277
   221
	  
melunko@38
   222
    *method_handle = (GnomeVFSMethodHandle *) myth_handle;
melunko@38
   223
melunko@38
   224
    return GNOME_VFS_OK;
melunko@38
   225
}
melunko@38
   226
melunko@38
   227
static GnomeVFSResult
melunko@38
   228
do_read (GnomeVFSMethod *method,
melunko@38
   229
         GnomeVFSMethodHandle *method_handle,
melunko@38
   230
         gpointer buffer,
melunko@38
   231
         GnomeVFSFileSize num_bytes,
melunko@38
   232
         GnomeVFSFileSize *bytes_read,
melunko@38
   233
         GnomeVFSContext *context)
melunko@38
   234
{
rosfran@327
   235
  MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
rosfran@357
   236
  GnomeVFSFileSize bytes_to_read = num_bytes;
melunko@38
   237
rosfran@340
   238
  if ( !myth_handle->is_livetv && ( myth_handle->bytes_read >= myth_handle->content_size ) )
rosfran@327
   239
      return GNOME_VFS_ERROR_EOF;
melunko@38
   240
rosfran@361
   241
  /* fixme: change this to min math function */
rosfran@357
   242
  if (( myth_handle->content_size > 0 ) ) 
rosfran@357
   243
  {
rosfran@357
   244
  	if ( !myth_handle->is_livetv && 
rosfran@341
   245
  				( num_bytes > ( myth_handle->content_size - myth_handle->bytes_read ) ) )
rosfran@357
   246
  	{
rosfran@357
   247
    	bytes_to_read = myth_handle->content_size - myth_handle->bytes_read;
rosfran@361
   248
  	}
rosfran@357
   249
  }
melunko@38
   250
rosfran@327
   251
  /* Loop sending the Myth File Transfer request:
rosfran@355
   252
   * Retry whilst authentication fails and we supply it. */
rosfran@357
   253
  if ( ( myth_handle->buffer_remain = myth_handle->buffer->len ) < bytes_to_read ) 
rosfran@355
   254
  {
rosfran@355
   255
  	gint buffer_size;
rosfran@354
   256
  	
rosfran@361
   257
  	while ( MYTHTV_BUFFER_SIZE != myth_handle->buffer_remain ) {
rosfran@355
   258
  		
rosfran@355
   259
	  	/* resize buffer length request to no more than MYTHTV_MAX_REQUEST_SIZE */
rosfran@355
   260
	  	if ( ( MYTHTV_BUFFER_SIZE - myth_handle->buffer_remain ) <= MYTHTV_MAX_REQUEST_SIZE )
rosfran@355
   261
	  		buffer_size = MYTHTV_BUFFER_SIZE - myth_handle->buffer_remain;
rosfran@355
   262
	  	else
rosfran@355
   263
	  		buffer_size = MYTHTV_MAX_REQUEST_SIZE;
rosfran@355
   264
	
rosfran@355
   265
	  	GByteArray *tmp_buffer = g_byte_array_new();
rosfran@355
   266
	
rosfran@355
   267
			g_debug ("XXXXXXXXXX Asking %d bytes (there is %d bytes in the buffer)\n", 
rosfran@355
   268
					buffer_size, myth_handle->buffer_remain);
rosfran@355
   269
	
rosfran@355
   270
	    gint len = gmyth_file_transfer_read (myth_handle->file_transfer,
rosfran@355
   271
	          tmp_buffer, buffer_size, TRUE);
rosfran@355
   272
	
rosfran@355
   273
			if (!myth_handle->is_livetv && len < 0) {
rosfran@327
   274
		    g_byte_array_free (tmp_buffer, TRUE);
rosfran@355
   275
		    g_debug ("Fail to read bytes");
rosfran@355
   276
		    return GNOME_VFS_ERROR_IO;
rosfran@355
   277
		  } /*else if (len == 0) {
rosfran@355
   278
			    g_byte_array_free (tmp_buffer, TRUE);
rosfran@355
   279
			    g_warning ("End of file probably achieved");
rosfran@355
   280
			    return GNOME_VFS_ERROR_EOF;
rosfran@355
   281
			}*/
rosfran@327
   282
	
rosfran@357
   283
	    myth_handle->buffer = g_byte_array_append ( myth_handle->buffer,
rosfran@357
   284
	    		tmp_buffer->data, len );
rosfran@327
   285
	
rosfran@327
   286
			myth_handle->buffer_remain += len;
melunko@111
   287
rosfran@354
   288
			if ( tmp_buffer != NULL )
rosfran@354
   289
			{
rosfran@357
   290
	      g_byte_array_free ( tmp_buffer, TRUE );
rosfran@354
   291
	    	tmp_buffer = NULL;
rosfran@354
   292
			}
rosfran@361
   293
  	} /* while - iterates until fills the internal buffer */
rosfran@355
   294
  	
rosfran@355
   295
  } /* if - got from the network, or not */
rosfran@355
   296
  
rosfran@357
   297
  bytes_to_read = ( bytes_to_read > myth_handle->buffer_remain ) ? myth_handle->buffer_remain : bytes_to_read;
rosfran@355
   298
  /* gets the first buffer_size bytes from the byte array buffer variable */ 
rosfran@116
   299
rosfran@355
   300
  g_memmove (buffer, myth_handle->buffer->data, bytes_to_read);
rosfran@116
   301
rosfran@355
   302
  myth_handle->bytes_read += bytes_to_read;
rosfran@355
   303
  myth_handle->buffer_remain -= bytes_to_read;
rosfran@116
   304
rosfran@355
   305
	/* flushs the newly buffer got from byte array */
rosfran@355
   306
	myth_handle->buffer = g_byte_array_remove_range (myth_handle->buffer, 0, bytes_to_read);
rosfran@355
   307
	g_debug ("Got from %llu bytes from internal buffer. (there are %d bytes in the buffer, from a total of %llu dispatched.)\n", 
rosfran@355
   308
				bytes_to_read, myth_handle->buffer_remain, myth_handle->bytes_read );
rosfran@357
   309
	
rosfran@357
   310
 	*bytes_read = bytes_to_read;
rosfran@355
   311
rosfran@355
   312
  return GNOME_VFS_OK;
melunko@38
   313
}
melunko@38
   314
melunko@38
   315
static GnomeVFSResult
melunko@38
   316
do_close (GnomeVFSMethod *method,
melunko@38
   317
          GnomeVFSMethodHandle *method_handle,
melunko@38
   318
          GnomeVFSContext *context)
melunko@38
   319
{
melunko@111
   320
rosfran@357
   321
  MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
rosfran@357
   322
  
rosfran@357
   323
  //if ( NULL == myth_handle || myth_handle->configured ) {
rosfran@357
   324
	
rosfran@357
   325
	  if (myth_handle->file_transfer != NULL) {
rosfran@357
   326
	    g_object_unref (myth_handle->file_transfer);
rosfran@357
   327
	  	myth_handle->file_transfer = NULL;
rosfran@357
   328
	  }
rosfran@357
   329
	  
rosfran@357
   330
	  if (myth_handle->is_livetv && myth_handle->livetv != NULL) {
rosfran@357
   331
	    g_object_unref (myth_handle->livetv);
rosfran@357
   332
	  	myth_handle->livetv = NULL;
rosfran@357
   333
	  }
rosfran@357
   334
	  
rosfran@357
   335
	  if (myth_handle->buffer) {
rosfran@357
   336
			g_byte_array_free (myth_handle->buffer, TRUE);
rosfran@357
   337
			myth_handle->buffer = NULL;
rosfran@357
   338
	  }
rosfran@357
   339
	
rosfran@357
   340
	  myth_handle->configured = FALSE;
rosfran@357
   341
	
rosfran@357
   342
	  g_free (myth_handle);
rosfran@357
   343
	  
rosfran@357
   344
	  myth_handle = NULL;	    
rosfran@357
   345
	  
rosfran@357
   346
 // }
rosfran@127
   347
    
rosfran@357
   348
  return GNOME_VFS_OK;
melunko@38
   349
}
melunko@38
   350
melunko@38
   351
static GnomeVFSResult
melunko@38
   352
do_get_file_info (GnomeVFSMethod *method,
melunko@38
   353
                  GnomeVFSURI *uri,
melunko@38
   354
                  GnomeVFSFileInfo *file_info,
melunko@38
   355
                  GnomeVFSFileInfoOptions options,
melunko@38
   356
                  GnomeVFSContext *context)
melunko@38
   357
{
renatofilho@188
   358
    GMythFileTransfer *file_transfer = NULL;
rosfran@340
   359
    GMythRecorder			*recorder 		 = NULL;
rosfran@346
   360
    GMythTVChain			*tvchain	 		 = NULL;
rosfran@297
   361
    GMythBackendInfo  *backend_info  = NULL;
rosfran@297
   362
    GMythURI					*gmyth_uri		 = NULL;
rosfran@340
   363
		GMythSocket 			*socket 			 = NULL;		 
rosfran@297
   364
    gboolean 					is_livetv 		 = FALSE;
rosfran@301
   365
    gboolean					ret						 = TRUE;
rosfran@346
   366
    gboolean 					res 					 = TRUE;
rosfran@297
   367
    
rosfran@297
   368
    /* Creates and fills out the backend info structure */    
rosfran@297
   369
	  backend_info = gmyth_backend_info_new_with_uri ( 
rosfran@297
   370
	  			gnome_vfs_unescape_string( gnome_vfs_uri_to_string( uri, GNOME_VFS_URI_HIDE_NONE ), "" ) );
rosfran@297
   371
	  
rosfran@297
   372
	  /* creates an instance of */  
rosfran@297
   373
	  gmyth_uri = gmyth_uri_new_with_value( 
rosfran@297
   374
	  		gnome_vfs_unescape_string( gnome_vfs_uri_to_string( uri, GNOME_VFS_URI_HIDE_NONE ), "" ) );
renatofilho@188
   375
rosfran@297
   376
	  is_livetv = gmyth_uri_is_livetv( gmyth_uri );
rosfran@297
   377
melunko@38
   378
    file_info->valid_fields = file_info->valid_fields
melunko@38
   379
        | GNOME_VFS_FILE_INFO_FIELDS_TYPE
melunko@38
   380
        | GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE
melunko@38
   381
        | GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
melunko@38
   382
    file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
rosfran@297
   383
    /* fixme: get from file extension? */
melunko@111
   384
    file_info->mime_type = g_strdup ("video/x-nuv");
melunko@38
   385
    file_info->permissions =
melunko@38
   386
        GNOME_VFS_PERM_USER_READ |
melunko@38
   387
        GNOME_VFS_PERM_OTHER_READ |
melunko@38
   388
        GNOME_VFS_PERM_GROUP_READ;
rosfran@331
   389
        
rosfran@332
   390
    g_print( "gnome_vfs_uri == %s | gmyth_uri == %s.\n",
rosfran@331
   391
    				gnome_vfs_uri_get_path (uri),
rosfran@331
   392
    				gmyth_uri_get_path (gmyth_uri) );
melunko@38
   393
rosfran@301
   394
	  /* Connect to the backend */
rosfran@297
   395
	  if ( gmyth_uri != NULL && is_livetv == TRUE ) {
rosfran@332
   396
	  	
rosfran@338
   397
	  	/* start to get file info from LiveTV remote encoder */	  	
rosfran@332
   398
			socket = gmyth_socket_new ();
rosfran@332
   399
			
rosfran@332
   400
			/* FIME: Implement this at gmyth_socket */
rosfran@332
   401
			res = gmyth_socket_connect_to_backend (socket, backend_info->hostname,
rosfran@332
   402
					backend_info->port, TRUE);
rosfran@332
   403
			if (!res) {
rosfran@333
   404
				g_print ("[%s] LiveTV can not connect to backend", __FUNCTION__);	
rosfran@332
   405
				res = FALSE;
rosfran@332
   406
				goto error;
rosfran@332
   407
			}
rosfran@332
   408
rosfran@332
   409
			if ( gmyth_remote_util_get_free_recorder_count (socket) <= 0 ) {
rosfran@333
   410
				g_print ("No free remote encoder available.");
rosfran@332
   411
				res = FALSE;
rosfran@332
   412
				goto error;
rosfran@332
   413
			}
rosfran@332
   414
		
rosfran@332
   415
			/* Gets the recorder num */
rosfran@332
   416
			recorder = remote_request_next_free_recorder (socket, -1);
rosfran@335
   417
			
rosfran@346
   418
			//if ( socket != NULL )
rosfran@346
   419
			//	g_object_unref (socket);
rosfran@332
   420
		
rosfran@332
   421
			if ( recorder == NULL ) {
rosfran@333
   422
				g_print ("[%s] None remote encoder available", __FUNCTION__);
rosfran@332
   423
				res = FALSE;
rosfran@332
   424
				goto error;
rosfran@332
   425
			}
rosfran@332
   426
			
rosfran@332
   427
			/* Init remote encoder. Opens its control socket. */
rosfran@332
   428
			res = gmyth_recorder_setup(recorder);
rosfran@332
   429
			if ( !res ) {
rosfran@333
   430
				g_print ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
rosfran@332
   431
				res = FALSE;
rosfran@332
   432
				goto error;
rosfran@346
   433
			}
rosfran@346
   434
			
rosfran@346
   435
			/* Creates livetv chain handler */
rosfran@346
   436
			tvchain = gmyth_tvchain_new();
rosfran@346
   437
			gmyth_tvchain_initialize ( tvchain, backend_info );
rosfran@346
   438
		
rosfran@346
   439
			if ( tvchain == NULL || tvchain->tvchain_id == NULL ) {
rosfran@346
   440
				res = FALSE;
rosfran@346
   441
				goto error;
rosfran@346
   442
			}
rosfran@346
   443
			
rosfran@346
   444
			// Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
rosfran@346
   445
			res = gmyth_recorder_spawntv ( recorder,
rosfran@346
   446
					gmyth_tvchain_get_id(tvchain) );
rosfran@346
   447
			if (!res) {
rosfran@346
   448
				g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__);
rosfran@346
   449
				res = FALSE;
rosfran@346
   450
				goto error;
rosfran@355
   451
			}	
rosfran@332
   452
			
rosfran@357
   453
		  //gchar* channel_name = gmyth_uri_get_channel_name( gmyth_uri );		  
rosfran@338
   454
	
rosfran@338
   455
		  /* DEBUG message */
rosfran@332
   456
			GMythProgramInfo* prog_info = gmyth_recorder_get_current_program_info( recorder );
rosfran@332
   457
			
rosfran@332
   458
			if ( prog_info != NULL )
rosfran@332
   459
			{
rosfran@357
   460
				//gmyth_program_info_print( prog_info );
rosfran@357
   461
				g_debug( "Program Info: %s\n", gmyth_program_info_to_string( prog_info ) ); 
rosfran@332
   462
  
rosfran@332
   463
		    g_print( "path = %s",  prog_info->pathname->str );
rosfran@332
   464
		    
rosfran@332
   465
		    file_info->name = g_strdup ( g_strrstr( prog_info->pathname->str, "/" ) );
rosfran@332
   466
		    
rosfran@332
   467
			} else {
rosfran@341
   468
				file_info->name = g_strdup ( "LiveTV.nuv" );
rosfran@332
   469
				file_info->size = gmyth_recorder_get_file_position( recorder );
rosfran@332
   470
			}
rosfran@333
   471
			
rosfran@332
   472
	    if ( recorder != NULL )
rosfran@338
   473
	    	g_object_unref (recorder);
rosfran@333
   474
	    
rosfran@333
   475
	    if ( prog_info != NULL )
rosfran@333
   476
	    	g_object_unref( prog_info );
rosfran@346
   477
rosfran@346
   478
	    if ( tvchain != NULL )
rosfran@346
   479
	    	g_object_unref (tvchain);
rosfran@338
   480
	    
rosfran@340
   481
	    file_info->size = (GnomeVFSFileSize) - 1;
rosfran@331
   482
rosfran@297
   483
	  } else {
rosfran@332
   484
	  	
rosfran@332
   485
	  	/* start to get file info from remote file encoder */	
rosfran@297
   486
	    file_transfer = gmyth_file_transfer_new (backend_info);
rosfran@297
   487
	    
rosfran@297
   488
	    /* Verifies if the file exists */
rosfran@297
   489
	    if (!gmyth_util_file_exists (backend_info, gmyth_uri_get_path (gmyth_uri))) {
rosfran@297
   490
	        g_object_unref (backend_info);
rosfran@297
   491
					return GNOME_VFS_ERROR_NOT_FOUND;
rosfran@297
   492
	    }
rosfran@297
   493
	    
rosfran@297
   494
	    /* sets the Playback monitor connection */
rosfran@297
   495
	    ret = gmyth_file_transfer_open ( file_transfer, gmyth_uri_get_path (gmyth_uri) );
rosfran@331
   496
	    
rosfran@338
   497
	    file_info->name = g_strdup ( gnome_vfs_uri_get_path (uri) );
rosfran@297
   498
		
rosfran@335
   499
	  } /* if - LiveTV or not? */	  
rosfran@297
   500
	  
rosfran@297
   501
    if (ret == FALSE) {
rosfran@335
   502
	    g_debug ("MythTV FileTransfer open error\n");
rosfran@297
   503
	    return GNOME_VFS_ERROR_NOT_OPEN;
rosfran@297
   504
	  }
rosfran@335
   505
	  
rosfran@332
   506
		if ( ret == TRUE  && file_transfer != NULL ) {
rosfran@323
   507
    	file_info->size = gmyth_file_transfer_get_filesize (file_transfer);
rosfran@331
   508
	    if ( file_transfer )
rosfran@338
   509
	    	g_object_unref (file_transfer);
rosfran@331
   510
   	}
rosfran@338
   511
rosfran@331
   512
    file_info->block_count = GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT;
rosfran@331
   513
	  file_info->io_block_size = GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE;
rosfran@332
   514
	  
rosfran@340
   515
error:
rosfran@331
   516
    if (backend_info)
rosfran@331
   517
   		g_object_unref (backend_info);
rosfran@346
   518
   		
rosfran@346
   519
   	if (!res)
rosfran@346
   520
   		return GNOME_VFS_ERROR_IO;
rosfran@301
   521
melunko@38
   522
    return GNOME_VFS_OK;
melunko@38
   523
}
melunko@38
   524
melunko@38
   525
static gboolean
melunko@38
   526
do_is_local (GnomeVFSMethod *method,
melunko@38
   527
             const GnomeVFSURI *uri)
melunko@38
   528
{
melunko@38
   529
	return FALSE;
melunko@38
   530
}
melunko@38
   531
melunko@38
   532
static GnomeVFSMethod method = {
melunko@38
   533
	sizeof (GnomeVFSMethod),
melunko@38
   534
	do_open,
melunko@38
   535
	NULL,
melunko@38
   536
	do_close,
melunko@38
   537
	do_read,
melunko@38
   538
	NULL,
melunko@38
   539
	NULL,
melunko@38
   540
	NULL,
melunko@38
   541
	NULL,
melunko@38
   542
	NULL,
melunko@38
   543
	NULL,
melunko@38
   544
	NULL,
melunko@38
   545
	do_get_file_info,
melunko@38
   546
	NULL,
melunko@38
   547
	do_is_local,
melunko@38
   548
	NULL,
melunko@38
   549
	NULL,
melunko@38
   550
	NULL,
melunko@38
   551
	NULL,
melunko@38
   552
	NULL,
melunko@38
   553
	NULL,
melunko@38
   554
	NULL,
melunko@38
   555
	NULL,
melunko@38
   556
	NULL,
melunko@38
   557
	NULL,
melunko@38
   558
	NULL,
melunko@38
   559
	NULL,
melunko@38
   560
};
melunko@38
   561
melunko@38
   562
melunko@38
   563
GnomeVFSMethod *
melunko@38
   564
vfs_module_init (const char *method_name, const char *args)
melunko@38
   565
{
melunko@38
   566
	return &method;
melunko@38
   567
}
melunko@38
   568
melunko@38
   569
void
melunko@38
   570
vfs_module_shutdown (GnomeVFSMethod *method)
melunko@38
   571
{
melunko@38
   572
}