# HG changeset patch # User rosfran # Date 1171408554 0 # Node ID 194c44ef8da4327d0405992d9448dbb5ca106296 # Parent 5486e606498bcdda8ef12c04c963031e6f4c964b [svn r359] Now it is running; removed some GStaticMutex race conditions. diff -r 5486e606498b -r 194c44ef8da4 libgnomevfs2-mythtv/modules/mythtv-method.c --- a/libgnomevfs2-mythtv/modules/mythtv-method.c Tue Feb 13 22:33:08 2007 +0000 +++ b/libgnomevfs2-mythtv/modules/mythtv-method.c Tue Feb 13 23:15:54 2007 +0000 @@ -35,12 +35,13 @@ #include #include #include +#include #define GST_MYTHTV_ID_NUM 1 #define MYTHTV_VERSION_DEFAULT 30 #define MYTHTV_TRANSFER_MAX_WAITS 100 -#define MYTHTV_BUFFER_SIZE 1024*64 +#define MYTHTV_BUFFER_SIZE 1024*140 #define MYTHTV_MAX_VFS_BUFFER_SIZE 4096 #define MYTHTV_MAX_REQUEST_SIZE 1024*64 @@ -64,27 +65,27 @@ gsize buffer_remain; gboolean is_livetv; + gboolean configured; + } MythtvHandle; +//static MythtvHandle *myth_handle = NULL; + static GnomeVFSResult do_open (GnomeVFSMethod *method, GnomeVFSMethodHandle **method_handle, GnomeVFSURI *uri, GnomeVFSOpenMode mode, GnomeVFSContext *context) -{ - MythtvHandle *myth_handle; - GMythBackendInfo *backend_info; +{ + MythtvHandle *myth_handle = NULL; + GMythBackendInfo *backend_info = NULL; GMythURI *gmyth_uri = NULL; gboolean ret = TRUE; _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL); _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL); - myth_handle = g_new0 (MythtvHandle, 1); - - myth_handle->is_livetv = FALSE; - if (mode & GNOME_VFS_OPEN_WRITE) { return GNOME_VFS_ERROR_NOT_PERMITTED; } @@ -92,110 +93,129 @@ if (gnome_vfs_uri_get_host_name (uri) == NULL) { return GNOME_VFS_ERROR_INVALID_HOST_NAME; } - - /* Initialize mythtv handler*/ - myth_handle->file_transfer = NULL; - myth_handle->livetv = NULL; - myth_handle->mythtv_version = MYTHTV_VERSION_DEFAULT; - myth_handle->bytes_read = 0; - myth_handle->content_size = (GnomeVFSFileSize) - 1; - - /* Creates and fills out the backend info structure */ - backend_info = gmyth_backend_info_new_with_uri ( - gnome_vfs_unescape_string( gnome_vfs_uri_to_string( uri, GNOME_VFS_URI_HIDE_NONE ), "" ) ); + + /* + if ( method_handle != NULL && *method_handle != NULL ) + { + myth_handle = (MythtvHandle*)*method_handle; + //if ( !myth_handle->configured ) + } + */ + + if ( ( NULL == myth_handle ) || !myth_handle->configured ) { + myth_handle = g_new0 (MythtvHandle, 1); + + myth_handle->configured = FALSE; + + myth_handle->is_livetv = FALSE; + + /* Initialize mythtv handler*/ + myth_handle->file_transfer = NULL; + myth_handle->livetv = NULL; + myth_handle->mythtv_version = MYTHTV_VERSION_DEFAULT; + myth_handle->bytes_read = 0; + myth_handle->content_size = (GnomeVFSFileSize) - 1; + + /* Creates and fills out the backend info structure */ + backend_info = gmyth_backend_info_new_with_uri ( + gnome_vfs_unescape_string( gnome_vfs_uri_to_string( uri, GNOME_VFS_URI_HIDE_NONE ), "" ) ); + + /* creates an instance of */ + gmyth_uri = gmyth_uri_new_with_value( + gnome_vfs_unescape_string( gnome_vfs_uri_to_string( uri, GNOME_VFS_URI_HIDE_NONE ), "" ) ); + + myth_handle->is_livetv = gmyth_uri_is_livetv( gmyth_uri ); + + /* Connect to the backend */ + if ( gmyth_uri != NULL && myth_handle->is_livetv == TRUE ) { + + if ( NULL == myth_handle->livetv ) + { + myth_handle->livetv = gmyth_livetv_new (); + + myth_handle->channel_name = gmyth_uri_get_channel_name( gmyth_uri ); + + g_debug( "[%s] Channel name = %s\n", __FUNCTION__, myth_handle->channel_name ); + + if ( myth_handle->channel_name != NULL ) { + if (gmyth_livetv_channel_name_setup (myth_handle->livetv, myth_handle->channel_name, + backend_info) == FALSE) { + g_object_unref( gmyth_uri ); + ret = FALSE; + } + } else { + if ( gmyth_livetv_setup (myth_handle->livetv, backend_info) == FALSE ) { + g_object_unref( gmyth_uri ); + ret = FALSE; + } + } + } + + if ( NULL == myth_handle->file_transfer ) { + myth_handle->file_transfer = gmyth_livetv_create_file_transfer (myth_handle->livetv); + + if (NULL == myth_handle->file_transfer) { + ret = FALSE; + g_debug ("MythTV FileTransfer is NULL!\n"); + return GNOME_VFS_ERROR_NOT_OPEN; + } + + if ( !gmyth_file_transfer_open( myth_handle->file_transfer, myth_handle->livetv->uri != NULL ? + gmyth_uri_get_path(myth_handle->livetv->uri) : + myth_handle->livetv->proginfo->pathname->str ) ) + { + g_debug ("Couldn't open MythTV FileTransfer is NULL!\n"); + g_object_unref( myth_handle->file_transfer ); + myth_handle->file_transfer = NULL; + ret = FALSE; + } + } /* if - FileTransfer is NULL, or not */ + + } else { + + if (NULL == myth_handle->file_transfer ) { + + myth_handle->file_transfer = gmyth_file_transfer_new (backend_info); + + /* Verifies if the file exists */ + if (!gmyth_util_file_exists (backend_info, gmyth_uri_get_path (gmyth_uri))) { + g_object_unref (backend_info); + ret = FALSE; + } + + /* sets the Playback monitor connection */ + ret = gmyth_file_transfer_open ( myth_handle->file_transfer, + gmyth_uri_get_path (gmyth_uri) ); + + } + + } /* if - LiveTV or not? */ + + if (ret == FALSE) { + g_debug ("MythTV FileTransfer open error.\n"); + return GNOME_VFS_ERROR_NOT_OPEN; + } + + myth_handle->configured = TRUE; + + g_object_unref (backend_info); + + if ( gmyth_uri != NULL ) + g_object_unref( gmyth_uri ); + + myth_handle->buffer = g_byte_array_sized_new (MYTHTV_BUFFER_SIZE); + myth_handle->buffer_remain = 0; + + g_return_val_if_fail (myth_handle->file_transfer != NULL, GNOME_VFS_ERROR_NOT_OPEN); + + if ( /*myth_handle->file_transfer->filesize <= 0 && */myth_handle->is_livetv ) { + myth_handle->content_size = gmyth_recorder_get_file_position(myth_handle->livetv->recorder); + } else { + myth_handle->content_size = myth_handle->file_transfer->filesize; + } + + } /* if - configured or not? */ - /* creates an instance of */ - gmyth_uri = gmyth_uri_new_with_value( - gnome_vfs_unescape_string( gnome_vfs_uri_to_string( uri, GNOME_VFS_URI_HIDE_NONE ), "" ) ); - - myth_handle->is_livetv = gmyth_uri_is_livetv( gmyth_uri ); - - /* Connect to the backend */ - if ( gmyth_uri != NULL && myth_handle->is_livetv == TRUE ) { - - if ( NULL == myth_handle->livetv ) - { - myth_handle->livetv = gmyth_livetv_new (); - - myth_handle->channel_name = gmyth_uri_get_channel_name( gmyth_uri ); - - g_debug( "[%s] Channel name = %s\n", __FUNCTION__, myth_handle->channel_name ); - - if ( myth_handle->channel_name != NULL ) { - if (gmyth_livetv_channel_name_setup (myth_handle->livetv, myth_handle->channel_name, - backend_info) == FALSE) { - g_object_unref( gmyth_uri ); - ret = FALSE; - } - } else { - if ( gmyth_livetv_setup (myth_handle->livetv, backend_info) == FALSE ) { - g_object_unref( gmyth_uri ); - ret = FALSE; - } - } - } - - if ( NULL == myth_handle->file_transfer ) { - myth_handle->file_transfer = gmyth_livetv_create_file_transfer (myth_handle->livetv); - - if (NULL == myth_handle->file_transfer) { - ret = FALSE; - g_debug ("MythTV FileTransfer is NULL!\n"); - return GNOME_VFS_ERROR_NOT_OPEN; - } - - if ( !gmyth_file_transfer_open( myth_handle->file_transfer, myth_handle->livetv->uri != NULL ? - gmyth_uri_get_path(myth_handle->livetv->uri) : - myth_handle->livetv->proginfo->pathname->str ) ) - { - g_debug ("Couldn't open MythTV FileTransfer is NULL!\n"); - g_object_unref( myth_handle->file_transfer ); - myth_handle->file_transfer = NULL; - ret = FALSE; - } - } /* if - FileTransfer is NULL, or not */ - - } else { - - if (NULL == myth_handle->file_transfer ) { - - myth_handle->file_transfer = gmyth_file_transfer_new (backend_info); - - /* Verifies if the file exists */ - if (!gmyth_util_file_exists (backend_info, gmyth_uri_get_path (gmyth_uri))) { - g_object_unref (backend_info); - ret = FALSE; - } - - /* sets the Playback monitor connection */ - ret = gmyth_file_transfer_open ( myth_handle->file_transfer, - gmyth_uri_get_path (gmyth_uri) ); - - } - - } /* if - LiveTV or not? */ - - if (ret == FALSE) { - g_debug ("MythTV FileTransfer open error.\n"); - return GNOME_VFS_ERROR_NOT_OPEN; - } - - //g_object_unref (backend_info); - - //if ( gmyth_uri != NULL ) - // g_object_unref( gmyth_uri ); - - g_return_val_if_fail (myth_handle->file_transfer != NULL, GNOME_VFS_ERROR_NOT_OPEN); - - if ( /*myth_handle->file_transfer->filesize <= 0 && */myth_handle->is_livetv ) { - myth_handle->content_size = (GnomeVFSFileSize) - 1; - //myth_handle->content_size = gmyth_recorder_get_file_position( myth_handle->livetv->recorder ); - } else - myth_handle->content_size = myth_handle->file_transfer->filesize; - - myth_handle->buffer = g_byte_array_sized_new (MYTHTV_BUFFER_SIZE); - myth_handle->buffer_remain = 0; - *method_handle = (GnomeVFSMethodHandle *) myth_handle; return GNOME_VFS_OK; @@ -210,31 +230,43 @@ GnomeVFSContext *context) { MythtvHandle *myth_handle = (MythtvHandle *) method_handle; - GnomeVFSFileSize bytes_to_read; + GnomeVFSFileSize bytes_to_read = num_bytes; + gint64 size_stream = *bytes_read; - *bytes_read = 0; + //*bytes_read = 0; - g_debug ("XXXXXXXXXX Requested %llu bytes (remains %d bytes on buffer...)\n", - (guint64)num_bytes, myth_handle->buffer->len ); + g_debug ("XXXXXXXXXX Requested %llu bytes (remains %d bytes on buffer...) file_size = %lld\n", + (guint64)num_bytes, myth_handle->buffer->len, *bytes_read ); if ( !myth_handle->is_livetv && ( myth_handle->bytes_read >= myth_handle->content_size ) ) return GNOME_VFS_ERROR_EOF; // fixme: change this to min math function - if (!myth_handle->is_livetv && ( myth_handle->content_size > 0 ) && + if (( myth_handle->content_size > 0 ) ) + { + if ( !myth_handle->is_livetv && ( num_bytes > ( myth_handle->content_size - myth_handle->bytes_read ) ) ) - bytes_to_read = myth_handle->content_size - myth_handle->bytes_read; - else - bytes_to_read = num_bytes; + { + bytes_to_read = myth_handle->content_size - myth_handle->bytes_read; + } else { + size_stream = gmyth_recorder_get_file_position(myth_handle->livetv->recorder); + if ( size_stream > myth_handle->content_size ) { + g_debug( "New file size %lld, old size = %lld.", size_stream, myth_handle->content_size ); + myth_handle->content_size = size_stream; + num_bytes = ( myth_handle->content_size - myth_handle->bytes_read ); + } else if ( num_bytes > ( myth_handle->content_size - myth_handle->bytes_read ) ) + num_bytes = MYTHTV_MAX_VFS_BUFFER_SIZE; + } + } /* Loop sending the Myth File Transfer request: * Retry whilst authentication fails and we supply it. */ /* if (myth_handle->buffer_remain < MYTHTV_BUFFER_SIZE) { */ - if ( ( myth_handle->buffer_remain = myth_handle->buffer->len ) < MYTHTV_MAX_VFS_BUFFER_SIZE ) + if ( ( myth_handle->buffer_remain = myth_handle->buffer->len ) < bytes_to_read ) { gint buffer_size; - while ( MYTHTV_BUFFER_SIZE != myth_handle->buffer_remain ) { + //while ( MYTHTV_BUFFER_SIZE != myth_handle->buffer_remain ) { /* resize buffer length request to no more than MYTHTV_MAX_REQUEST_SIZE */ if ( ( MYTHTV_BUFFER_SIZE - myth_handle->buffer_remain ) <= MYTHTV_MAX_REQUEST_SIZE ) @@ -260,21 +292,21 @@ return GNOME_VFS_ERROR_EOF; }*/ - myth_handle->buffer = g_byte_array_append (myth_handle->buffer, - tmp_buffer->data, len); + myth_handle->buffer = g_byte_array_append ( myth_handle->buffer, + tmp_buffer->data, len ); myth_handle->buffer_remain += len; if ( tmp_buffer != NULL ) { - g_byte_array_free (tmp_buffer, TRUE); + g_byte_array_free ( tmp_buffer, TRUE ); tmp_buffer = NULL; } - } /* while - iterates until fills the internal buffer */ + //} /* while - iterates until fills the internal buffer */ } /* if - got from the network, or not */ - bytes_to_read = (bytes_to_read > myth_handle->buffer_remain) ? myth_handle->buffer_remain : bytes_to_read; + bytes_to_read = ( bytes_to_read > myth_handle->buffer_remain ) ? myth_handle->buffer_remain : bytes_to_read; /* gets the first buffer_size bytes from the byte array buffer variable */ g_memmove (buffer, myth_handle->buffer->data, bytes_to_read); @@ -286,7 +318,8 @@ myth_handle->buffer = g_byte_array_remove_range (myth_handle->buffer, 0, bytes_to_read); g_debug ("Got from %llu bytes from internal buffer. (there are %d bytes in the buffer, from a total of %llu dispatched.)\n", bytes_to_read, myth_handle->buffer_remain, myth_handle->bytes_read ); - *bytes_read = bytes_to_read; + + *bytes_read = bytes_to_read; return GNOME_VFS_OK; } @@ -297,26 +330,34 @@ GnomeVFSContext *context) { - MythtvHandle *myth_handle = (MythtvHandle *) method_handle; - - if (myth_handle->file_transfer != NULL) { - g_object_unref (myth_handle->file_transfer); - myth_handle->file_transfer = NULL; - } + MythtvHandle *myth_handle = (MythtvHandle *) method_handle; + + //if ( NULL == myth_handle || myth_handle->configured ) { + + if (myth_handle->file_transfer != NULL) { + g_object_unref (myth_handle->file_transfer); + myth_handle->file_transfer = NULL; + } + + if (myth_handle->is_livetv && myth_handle->livetv != NULL) { + g_object_unref (myth_handle->livetv); + myth_handle->livetv = NULL; + } + + if (myth_handle->buffer) { + g_byte_array_free (myth_handle->buffer, TRUE); + myth_handle->buffer = NULL; + } + + myth_handle->configured = FALSE; + + g_free (myth_handle); + + myth_handle = NULL; + + // } - if (myth_handle->is_livetv && myth_handle->livetv != NULL) { - g_object_unref (myth_handle->livetv); - myth_handle->livetv = NULL; - } - - if (myth_handle->buffer) { - g_byte_array_free (myth_handle->buffer, TRUE); - myth_handle->buffer = NULL; - } - - g_free (myth_handle); - - return GNOME_VFS_OK; + return GNOME_VFS_OK; } static GnomeVFSResult @@ -413,7 +454,6 @@ } // Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly) - /* res = gmyth_recorder_spawntv ( recorder, gmyth_tvchain_get_id(tvchain) ); if (!res) { @@ -421,16 +461,16 @@ res = FALSE; goto error; } - */ - //gchar* channel_name = gmyth_uri_get_channel_name( gmyth_uri ); + //gchar* channel_name = gmyth_uri_get_channel_name( gmyth_uri ); /* DEBUG message */ GMythProgramInfo* prog_info = gmyth_recorder_get_current_program_info( recorder ); if ( prog_info != NULL ) { - gmyth_program_info_print( prog_info ); + //gmyth_program_info_print( prog_info ); + g_debug( "Program Info: %s\n", gmyth_program_info_to_string( prog_info ) ); g_print( "path = %s", prog_info->pathname->str );