[svn r359] Now it is running; removed some GStaticMutex race conditions.
1.1 --- a/libgnomevfs2-mythtv/modules/mythtv-method.c Tue Feb 13 22:33:08 2007 +0000
1.2 +++ b/libgnomevfs2-mythtv/modules/mythtv-method.c Tue Feb 13 23:15:54 2007 +0000
1.3 @@ -35,12 +35,13 @@
1.4 #include <gmyth/gmyth_util.h>
1.5 #include <gmyth/gmyth_remote_util.h>
1.6 #include <gmyth/gmyth_tvchain.h>
1.7 +#include <gmyth/gmyth_programinfo.h>
1.8
1.9 #define GST_MYTHTV_ID_NUM 1
1.10 #define MYTHTV_VERSION_DEFAULT 30
1.11 #define MYTHTV_TRANSFER_MAX_WAITS 100
1.12
1.13 -#define MYTHTV_BUFFER_SIZE 1024*64
1.14 +#define MYTHTV_BUFFER_SIZE 1024*140
1.15 #define MYTHTV_MAX_VFS_BUFFER_SIZE 4096
1.16 #define MYTHTV_MAX_REQUEST_SIZE 1024*64
1.17
1.18 @@ -64,27 +65,27 @@
1.19 gsize buffer_remain;
1.20 gboolean is_livetv;
1.21
1.22 + gboolean configured;
1.23 +
1.24 } MythtvHandle;
1.25
1.26 +//static MythtvHandle *myth_handle = NULL;
1.27 +
1.28 static GnomeVFSResult
1.29 do_open (GnomeVFSMethod *method,
1.30 GnomeVFSMethodHandle **method_handle,
1.31 GnomeVFSURI *uri,
1.32 GnomeVFSOpenMode mode,
1.33 GnomeVFSContext *context)
1.34 -{
1.35 - MythtvHandle *myth_handle;
1.36 - GMythBackendInfo *backend_info;
1.37 +{
1.38 + MythtvHandle *myth_handle = NULL;
1.39 + GMythBackendInfo *backend_info = NULL;
1.40 GMythURI *gmyth_uri = NULL;
1.41 gboolean ret = TRUE;
1.42
1.43 _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL);
1.44 _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL);
1.45
1.46 - myth_handle = g_new0 (MythtvHandle, 1);
1.47 -
1.48 - myth_handle->is_livetv = FALSE;
1.49 -
1.50 if (mode & GNOME_VFS_OPEN_WRITE) {
1.51 return GNOME_VFS_ERROR_NOT_PERMITTED;
1.52 }
1.53 @@ -92,110 +93,129 @@
1.54 if (gnome_vfs_uri_get_host_name (uri) == NULL) {
1.55 return GNOME_VFS_ERROR_INVALID_HOST_NAME;
1.56 }
1.57 -
1.58 - /* Initialize mythtv handler*/
1.59 - myth_handle->file_transfer = NULL;
1.60 - myth_handle->livetv = NULL;
1.61 - myth_handle->mythtv_version = MYTHTV_VERSION_DEFAULT;
1.62 - myth_handle->bytes_read = 0;
1.63 - myth_handle->content_size = (GnomeVFSFileSize) - 1;
1.64 -
1.65 - /* Creates and fills out the backend info structure */
1.66 - backend_info = gmyth_backend_info_new_with_uri (
1.67 - gnome_vfs_unescape_string( gnome_vfs_uri_to_string( uri, GNOME_VFS_URI_HIDE_NONE ), "" ) );
1.68 +
1.69 + /*
1.70 + if ( method_handle != NULL && *method_handle != NULL )
1.71 + {
1.72 + myth_handle = (MythtvHandle*)*method_handle;
1.73 + //if ( !myth_handle->configured )
1.74 + }
1.75 + */
1.76 +
1.77 + if ( ( NULL == myth_handle ) || !myth_handle->configured ) {
1.78 + myth_handle = g_new0 (MythtvHandle, 1);
1.79 +
1.80 + myth_handle->configured = FALSE;
1.81 +
1.82 + myth_handle->is_livetv = FALSE;
1.83 +
1.84 + /* Initialize mythtv handler*/
1.85 + myth_handle->file_transfer = NULL;
1.86 + myth_handle->livetv = NULL;
1.87 + myth_handle->mythtv_version = MYTHTV_VERSION_DEFAULT;
1.88 + myth_handle->bytes_read = 0;
1.89 + myth_handle->content_size = (GnomeVFSFileSize) - 1;
1.90 +
1.91 + /* Creates and fills out the backend info structure */
1.92 + backend_info = gmyth_backend_info_new_with_uri (
1.93 + gnome_vfs_unescape_string( gnome_vfs_uri_to_string( uri, GNOME_VFS_URI_HIDE_NONE ), "" ) );
1.94 +
1.95 + /* creates an instance of */
1.96 + gmyth_uri = gmyth_uri_new_with_value(
1.97 + gnome_vfs_unescape_string( gnome_vfs_uri_to_string( uri, GNOME_VFS_URI_HIDE_NONE ), "" ) );
1.98 +
1.99 + myth_handle->is_livetv = gmyth_uri_is_livetv( gmyth_uri );
1.100 +
1.101 + /* Connect to the backend */
1.102 + if ( gmyth_uri != NULL && myth_handle->is_livetv == TRUE ) {
1.103 +
1.104 + if ( NULL == myth_handle->livetv )
1.105 + {
1.106 + myth_handle->livetv = gmyth_livetv_new ();
1.107 +
1.108 + myth_handle->channel_name = gmyth_uri_get_channel_name( gmyth_uri );
1.109 +
1.110 + g_debug( "[%s] Channel name = %s\n", __FUNCTION__, myth_handle->channel_name );
1.111 +
1.112 + if ( myth_handle->channel_name != NULL ) {
1.113 + if (gmyth_livetv_channel_name_setup (myth_handle->livetv, myth_handle->channel_name,
1.114 + backend_info) == FALSE) {
1.115 + g_object_unref( gmyth_uri );
1.116 + ret = FALSE;
1.117 + }
1.118 + } else {
1.119 + if ( gmyth_livetv_setup (myth_handle->livetv, backend_info) == FALSE ) {
1.120 + g_object_unref( gmyth_uri );
1.121 + ret = FALSE;
1.122 + }
1.123 + }
1.124 + }
1.125 +
1.126 + if ( NULL == myth_handle->file_transfer ) {
1.127 + myth_handle->file_transfer = gmyth_livetv_create_file_transfer (myth_handle->livetv);
1.128 +
1.129 + if (NULL == myth_handle->file_transfer) {
1.130 + ret = FALSE;
1.131 + g_debug ("MythTV FileTransfer is NULL!\n");
1.132 + return GNOME_VFS_ERROR_NOT_OPEN;
1.133 + }
1.134 +
1.135 + if ( !gmyth_file_transfer_open( myth_handle->file_transfer, myth_handle->livetv->uri != NULL ?
1.136 + gmyth_uri_get_path(myth_handle->livetv->uri) :
1.137 + myth_handle->livetv->proginfo->pathname->str ) )
1.138 + {
1.139 + g_debug ("Couldn't open MythTV FileTransfer is NULL!\n");
1.140 + g_object_unref( myth_handle->file_transfer );
1.141 + myth_handle->file_transfer = NULL;
1.142 + ret = FALSE;
1.143 + }
1.144 + } /* if - FileTransfer is NULL, or not */
1.145 +
1.146 + } else {
1.147 +
1.148 + if (NULL == myth_handle->file_transfer ) {
1.149 +
1.150 + myth_handle->file_transfer = gmyth_file_transfer_new (backend_info);
1.151 +
1.152 + /* Verifies if the file exists */
1.153 + if (!gmyth_util_file_exists (backend_info, gmyth_uri_get_path (gmyth_uri))) {
1.154 + g_object_unref (backend_info);
1.155 + ret = FALSE;
1.156 + }
1.157 +
1.158 + /* sets the Playback monitor connection */
1.159 + ret = gmyth_file_transfer_open ( myth_handle->file_transfer,
1.160 + gmyth_uri_get_path (gmyth_uri) );
1.161 +
1.162 + }
1.163 +
1.164 + } /* if - LiveTV or not? */
1.165 +
1.166 + if (ret == FALSE) {
1.167 + g_debug ("MythTV FileTransfer open error.\n");
1.168 + return GNOME_VFS_ERROR_NOT_OPEN;
1.169 + }
1.170 +
1.171 + myth_handle->configured = TRUE;
1.172 +
1.173 + g_object_unref (backend_info);
1.174 +
1.175 + if ( gmyth_uri != NULL )
1.176 + g_object_unref( gmyth_uri );
1.177 +
1.178 + myth_handle->buffer = g_byte_array_sized_new (MYTHTV_BUFFER_SIZE);
1.179 + myth_handle->buffer_remain = 0;
1.180 +
1.181 + g_return_val_if_fail (myth_handle->file_transfer != NULL, GNOME_VFS_ERROR_NOT_OPEN);
1.182 +
1.183 + if ( /*myth_handle->file_transfer->filesize <= 0 && */myth_handle->is_livetv ) {
1.184 + myth_handle->content_size = gmyth_recorder_get_file_position(myth_handle->livetv->recorder);
1.185 + } else {
1.186 + myth_handle->content_size = myth_handle->file_transfer->filesize;
1.187 + }
1.188 +
1.189 + } /* if - configured or not? */
1.190
1.191 - /* creates an instance of */
1.192 - gmyth_uri = gmyth_uri_new_with_value(
1.193 - gnome_vfs_unescape_string( gnome_vfs_uri_to_string( uri, GNOME_VFS_URI_HIDE_NONE ), "" ) );
1.194 -
1.195 - myth_handle->is_livetv = gmyth_uri_is_livetv( gmyth_uri );
1.196 -
1.197 - /* Connect to the backend */
1.198 - if ( gmyth_uri != NULL && myth_handle->is_livetv == TRUE ) {
1.199 -
1.200 - if ( NULL == myth_handle->livetv )
1.201 - {
1.202 - myth_handle->livetv = gmyth_livetv_new ();
1.203 -
1.204 - myth_handle->channel_name = gmyth_uri_get_channel_name( gmyth_uri );
1.205 -
1.206 - g_debug( "[%s] Channel name = %s\n", __FUNCTION__, myth_handle->channel_name );
1.207 -
1.208 - if ( myth_handle->channel_name != NULL ) {
1.209 - if (gmyth_livetv_channel_name_setup (myth_handle->livetv, myth_handle->channel_name,
1.210 - backend_info) == FALSE) {
1.211 - g_object_unref( gmyth_uri );
1.212 - ret = FALSE;
1.213 - }
1.214 - } else {
1.215 - if ( gmyth_livetv_setup (myth_handle->livetv, backend_info) == FALSE ) {
1.216 - g_object_unref( gmyth_uri );
1.217 - ret = FALSE;
1.218 - }
1.219 - }
1.220 - }
1.221 -
1.222 - if ( NULL == myth_handle->file_transfer ) {
1.223 - myth_handle->file_transfer = gmyth_livetv_create_file_transfer (myth_handle->livetv);
1.224 -
1.225 - if (NULL == myth_handle->file_transfer) {
1.226 - ret = FALSE;
1.227 - g_debug ("MythTV FileTransfer is NULL!\n");
1.228 - return GNOME_VFS_ERROR_NOT_OPEN;
1.229 - }
1.230 -
1.231 - if ( !gmyth_file_transfer_open( myth_handle->file_transfer, myth_handle->livetv->uri != NULL ?
1.232 - gmyth_uri_get_path(myth_handle->livetv->uri) :
1.233 - myth_handle->livetv->proginfo->pathname->str ) )
1.234 - {
1.235 - g_debug ("Couldn't open MythTV FileTransfer is NULL!\n");
1.236 - g_object_unref( myth_handle->file_transfer );
1.237 - myth_handle->file_transfer = NULL;
1.238 - ret = FALSE;
1.239 - }
1.240 - } /* if - FileTransfer is NULL, or not */
1.241 -
1.242 - } else {
1.243 -
1.244 - if (NULL == myth_handle->file_transfer ) {
1.245 -
1.246 - myth_handle->file_transfer = gmyth_file_transfer_new (backend_info);
1.247 -
1.248 - /* Verifies if the file exists */
1.249 - if (!gmyth_util_file_exists (backend_info, gmyth_uri_get_path (gmyth_uri))) {
1.250 - g_object_unref (backend_info);
1.251 - ret = FALSE;
1.252 - }
1.253 -
1.254 - /* sets the Playback monitor connection */
1.255 - ret = gmyth_file_transfer_open ( myth_handle->file_transfer,
1.256 - gmyth_uri_get_path (gmyth_uri) );
1.257 -
1.258 - }
1.259 -
1.260 - } /* if - LiveTV or not? */
1.261 -
1.262 - if (ret == FALSE) {
1.263 - g_debug ("MythTV FileTransfer open error.\n");
1.264 - return GNOME_VFS_ERROR_NOT_OPEN;
1.265 - }
1.266 -
1.267 - //g_object_unref (backend_info);
1.268 -
1.269 - //if ( gmyth_uri != NULL )
1.270 - // g_object_unref( gmyth_uri );
1.271 -
1.272 - g_return_val_if_fail (myth_handle->file_transfer != NULL, GNOME_VFS_ERROR_NOT_OPEN);
1.273 -
1.274 - if ( /*myth_handle->file_transfer->filesize <= 0 && */myth_handle->is_livetv ) {
1.275 - myth_handle->content_size = (GnomeVFSFileSize) - 1;
1.276 - //myth_handle->content_size = gmyth_recorder_get_file_position( myth_handle->livetv->recorder );
1.277 - } else
1.278 - myth_handle->content_size = myth_handle->file_transfer->filesize;
1.279 -
1.280 - myth_handle->buffer = g_byte_array_sized_new (MYTHTV_BUFFER_SIZE);
1.281 - myth_handle->buffer_remain = 0;
1.282 -
1.283 *method_handle = (GnomeVFSMethodHandle *) myth_handle;
1.284
1.285 return GNOME_VFS_OK;
1.286 @@ -210,31 +230,43 @@
1.287 GnomeVFSContext *context)
1.288 {
1.289 MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
1.290 - GnomeVFSFileSize bytes_to_read;
1.291 + GnomeVFSFileSize bytes_to_read = num_bytes;
1.292 + gint64 size_stream = *bytes_read;
1.293
1.294 - *bytes_read = 0;
1.295 + //*bytes_read = 0;
1.296
1.297 - g_debug ("XXXXXXXXXX Requested %llu bytes (remains %d bytes on buffer...)\n",
1.298 - (guint64)num_bytes, myth_handle->buffer->len );
1.299 + g_debug ("XXXXXXXXXX Requested %llu bytes (remains %d bytes on buffer...) file_size = %lld\n",
1.300 + (guint64)num_bytes, myth_handle->buffer->len, *bytes_read );
1.301
1.302 if ( !myth_handle->is_livetv && ( myth_handle->bytes_read >= myth_handle->content_size ) )
1.303 return GNOME_VFS_ERROR_EOF;
1.304
1.305 // fixme: change this to min math function
1.306 - if (!myth_handle->is_livetv && ( myth_handle->content_size > 0 ) &&
1.307 + if (( myth_handle->content_size > 0 ) )
1.308 + {
1.309 + if ( !myth_handle->is_livetv &&
1.310 ( num_bytes > ( myth_handle->content_size - myth_handle->bytes_read ) ) )
1.311 - bytes_to_read = myth_handle->content_size - myth_handle->bytes_read;
1.312 - else
1.313 - bytes_to_read = num_bytes;
1.314 + {
1.315 + bytes_to_read = myth_handle->content_size - myth_handle->bytes_read;
1.316 + } else {
1.317 + size_stream = gmyth_recorder_get_file_position(myth_handle->livetv->recorder);
1.318 + if ( size_stream > myth_handle->content_size ) {
1.319 + g_debug( "New file size %lld, old size = %lld.", size_stream, myth_handle->content_size );
1.320 + myth_handle->content_size = size_stream;
1.321 + num_bytes = ( myth_handle->content_size - myth_handle->bytes_read );
1.322 + } else if ( num_bytes > ( myth_handle->content_size - myth_handle->bytes_read ) )
1.323 + num_bytes = MYTHTV_MAX_VFS_BUFFER_SIZE;
1.324 + }
1.325 + }
1.326
1.327 /* Loop sending the Myth File Transfer request:
1.328 * Retry whilst authentication fails and we supply it. */
1.329 /* if (myth_handle->buffer_remain < MYTHTV_BUFFER_SIZE) { */
1.330 - if ( ( myth_handle->buffer_remain = myth_handle->buffer->len ) < MYTHTV_MAX_VFS_BUFFER_SIZE )
1.331 + if ( ( myth_handle->buffer_remain = myth_handle->buffer->len ) < bytes_to_read )
1.332 {
1.333 gint buffer_size;
1.334
1.335 - while ( MYTHTV_BUFFER_SIZE != myth_handle->buffer_remain ) {
1.336 + //while ( MYTHTV_BUFFER_SIZE != myth_handle->buffer_remain ) {
1.337
1.338 /* resize buffer length request to no more than MYTHTV_MAX_REQUEST_SIZE */
1.339 if ( ( MYTHTV_BUFFER_SIZE - myth_handle->buffer_remain ) <= MYTHTV_MAX_REQUEST_SIZE )
1.340 @@ -260,21 +292,21 @@
1.341 return GNOME_VFS_ERROR_EOF;
1.342 }*/
1.343
1.344 - myth_handle->buffer = g_byte_array_append (myth_handle->buffer,
1.345 - tmp_buffer->data, len);
1.346 + myth_handle->buffer = g_byte_array_append ( myth_handle->buffer,
1.347 + tmp_buffer->data, len );
1.348
1.349 myth_handle->buffer_remain += len;
1.350
1.351 if ( tmp_buffer != NULL )
1.352 {
1.353 - g_byte_array_free (tmp_buffer, TRUE);
1.354 + g_byte_array_free ( tmp_buffer, TRUE );
1.355 tmp_buffer = NULL;
1.356 }
1.357 - } /* while - iterates until fills the internal buffer */
1.358 + //} /* while - iterates until fills the internal buffer */
1.359
1.360 } /* if - got from the network, or not */
1.361
1.362 - bytes_to_read = (bytes_to_read > myth_handle->buffer_remain) ? myth_handle->buffer_remain : bytes_to_read;
1.363 + bytes_to_read = ( bytes_to_read > myth_handle->buffer_remain ) ? myth_handle->buffer_remain : bytes_to_read;
1.364 /* gets the first buffer_size bytes from the byte array buffer variable */
1.365
1.366 g_memmove (buffer, myth_handle->buffer->data, bytes_to_read);
1.367 @@ -286,7 +318,8 @@
1.368 myth_handle->buffer = g_byte_array_remove_range (myth_handle->buffer, 0, bytes_to_read);
1.369 g_debug ("Got from %llu bytes from internal buffer. (there are %d bytes in the buffer, from a total of %llu dispatched.)\n",
1.370 bytes_to_read, myth_handle->buffer_remain, myth_handle->bytes_read );
1.371 - *bytes_read = bytes_to_read;
1.372 +
1.373 + *bytes_read = bytes_to_read;
1.374
1.375 return GNOME_VFS_OK;
1.376 }
1.377 @@ -297,26 +330,34 @@
1.378 GnomeVFSContext *context)
1.379 {
1.380
1.381 - MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
1.382 -
1.383 - if (myth_handle->file_transfer != NULL) {
1.384 - g_object_unref (myth_handle->file_transfer);
1.385 - myth_handle->file_transfer = NULL;
1.386 - }
1.387 + MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
1.388 +
1.389 + //if ( NULL == myth_handle || myth_handle->configured ) {
1.390 +
1.391 + if (myth_handle->file_transfer != NULL) {
1.392 + g_object_unref (myth_handle->file_transfer);
1.393 + myth_handle->file_transfer = NULL;
1.394 + }
1.395 +
1.396 + if (myth_handle->is_livetv && myth_handle->livetv != NULL) {
1.397 + g_object_unref (myth_handle->livetv);
1.398 + myth_handle->livetv = NULL;
1.399 + }
1.400 +
1.401 + if (myth_handle->buffer) {
1.402 + g_byte_array_free (myth_handle->buffer, TRUE);
1.403 + myth_handle->buffer = NULL;
1.404 + }
1.405 +
1.406 + myth_handle->configured = FALSE;
1.407 +
1.408 + g_free (myth_handle);
1.409 +
1.410 + myth_handle = NULL;
1.411 +
1.412 + // }
1.413
1.414 - if (myth_handle->is_livetv && myth_handle->livetv != NULL) {
1.415 - g_object_unref (myth_handle->livetv);
1.416 - myth_handle->livetv = NULL;
1.417 - }
1.418 -
1.419 - if (myth_handle->buffer) {
1.420 - g_byte_array_free (myth_handle->buffer, TRUE);
1.421 - myth_handle->buffer = NULL;
1.422 - }
1.423 -
1.424 - g_free (myth_handle);
1.425 -
1.426 - return GNOME_VFS_OK;
1.427 + return GNOME_VFS_OK;
1.428 }
1.429
1.430 static GnomeVFSResult
1.431 @@ -413,7 +454,6 @@
1.432 }
1.433
1.434 // Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
1.435 - /*
1.436 res = gmyth_recorder_spawntv ( recorder,
1.437 gmyth_tvchain_get_id(tvchain) );
1.438 if (!res) {
1.439 @@ -421,16 +461,16 @@
1.440 res = FALSE;
1.441 goto error;
1.442 }
1.443 - */
1.444
1.445 - //gchar* channel_name = gmyth_uri_get_channel_name( gmyth_uri );
1.446 + //gchar* channel_name = gmyth_uri_get_channel_name( gmyth_uri );
1.447
1.448 /* DEBUG message */
1.449 GMythProgramInfo* prog_info = gmyth_recorder_get_current_program_info( recorder );
1.450
1.451 if ( prog_info != NULL )
1.452 {
1.453 - gmyth_program_info_print( prog_info );
1.454 + //gmyth_program_info_print( prog_info );
1.455 + g_debug( "Program Info: %s\n", gmyth_program_info_to_string( prog_info ) );
1.456
1.457 g_print( "path = %s", prog_info->pathname->str );
1.458