gmyth/src/gmyth_livetv.c
author rosfran
Thu Feb 01 22:10:18 2007 +0000 (2007-02-01)
branchtrunk
changeset 321 1c020e9ef06d
parent 310 0638b71f9293
child 322 eb6b0b1409b5
permissions -rwxr-xr-x
[svn r323] Some updates in the LiveTV.
     1 /**
     2  * GMyth Library
     3  *
     4  * @file gmyth/gmyth_livetv.c
     5  * 
     6  * @brief <p> GMythLiveTV starts a remote TV session with the MythTV backend.
     7  *
     8  * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
     9  * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
    10  *
    11  *//*
    12  * 
    13  * This program is free software; you can redistribute it and/or modify
    14  * it under the terms of the GNU Lesser General Public License as published by
    15  * the Free Software Foundation; either version 2 of the License, or
    16  * (at your option) any later version.
    17  *
    18  * This program is distributed in the hope that it will be useful,
    19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    21  * GNU General Public License for more details.
    22  *
    23  * You should have received a copy of the GNU Lesser General Public License
    24  * along with this program; if not, write to the Free Software
    25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    26  */
    27   
    28 #ifdef HAVE_CONFIG_H
    29 #include "config.h"
    30 #endif
    31 
    32 #include "gmyth_livetv.h" 
    33 #include "gmyth_remote_util.h"
    34 #include "gmyth_tvchain.h"
    35 #include "gmyth_socket.h"
    36 #include "gmyth_backendinfo.h"
    37 #include "gmyth_debug.h"
    38 
    39 #include "gmyth_file_transfer.h"
    40 #include "gmyth_monitor_handler.h"
    41 
    42 static void gmyth_livetv_class_init          (GMythLiveTVClass *klass);
    43 static void gmyth_livetv_init                (GMythLiveTV *object);
    44 
    45 static void gmyth_livetv_dispose  (GObject *object);
    46 static void gmyth_livetv_finalize (GObject *object);
    47 
    48 static gint tvchain_curr_index = -1; 
    49 
    50 static GStaticMutex lock = G_STATIC_MUTEX_INIT;
    51 
    52 #define GMYTHTV_TRANSFER_MAX_WAITS	    100
    53 
    54 G_DEFINE_TYPE(GMythLiveTV, gmyth_livetv, G_TYPE_OBJECT)
    55 
    56 static void
    57 gmyth_livetv_class_init (GMythLiveTVClass *klass)
    58 {
    59 	GObjectClass *gobject_class;
    60 
    61 	gobject_class = (GObjectClass *) klass;
    62 
    63 	gobject_class->dispose  = gmyth_livetv_dispose;
    64 	gobject_class->finalize = gmyth_livetv_finalize;	
    65 }
    66 
    67 static void
    68 gmyth_livetv_init (GMythLiveTV *livetv)
    69 {
    70 	livetv->backend_info = NULL;
    71 	livetv->local_hostname = NULL;
    72 	livetv->file_transfer = NULL;
    73 	livetv->setup_done = FALSE;
    74 
    75 	livetv->recorder = NULL;
    76 	livetv->tvchain = NULL;
    77 	livetv->proginfo = NULL;
    78 	livetv->uri = NULL;
    79 
    80 }
    81 
    82 static void
    83 gmyth_livetv_dispose  (GObject *object)
    84 {
    85 	G_OBJECT_CLASS (gmyth_livetv_parent_class)->dispose (object);
    86 }
    87 
    88 static void
    89 gmyth_livetv_finalize (GObject *object)
    90 {
    91 	g_signal_handlers_destroy (object);
    92 
    93 	GMythLiveTV *livetv = GMYTH_LIVETV (object);
    94 
    95 	gmyth_debug ("Finalizing livetv");
    96 
    97 	if ( livetv->monitor != NULL ) {
    98 		g_object_unref (livetv->monitor);
    99 		livetv->monitor = NULL;
   100 	}
   101 
   102 	if ( livetv->recorder != NULL ) {
   103 		g_object_unref (livetv->recorder);
   104 		livetv->recorder = NULL;
   105 	}
   106 
   107 	if ( livetv->tvchain != NULL ) {
   108 		g_object_unref (livetv->tvchain);
   109 		livetv->tvchain = NULL;
   110 	}
   111 
   112 	if ( livetv->proginfo != NULL ) {
   113 		g_object_unref (livetv->proginfo);
   114 		livetv->proginfo = NULL;
   115 	}
   116 	
   117 	if ( livetv->file_transfer != NULL ) {
   118 		g_object_unref (livetv->file_transfer);
   119 		livetv->file_transfer = NULL;
   120 	}
   121 	
   122 	if ( livetv->backend_info != NULL ) {
   123 		g_object_unref (livetv->backend_info);
   124 		livetv->backend_info = NULL;
   125 	}
   126 	
   127 	if ( livetv->uri != NULL )
   128 	{
   129 		g_object_unref (livetv->uri);
   130 		livetv->uri = NULL;
   131 	}
   132 
   133 	G_OBJECT_CLASS ( gmyth_livetv_parent_class )->finalize ( object );
   134 }
   135 
   136 GMythLiveTV*
   137 gmyth_livetv_new ()
   138 {
   139 	GMythLiveTV *livetv = GMYTH_LIVETV ( g_object_new( GMYTH_LIVETV_TYPE, NULL ) );
   140 
   141 	return livetv;
   142 }
   143 
   144 static void
   145 gmyth_livetv_monitor_signal_handler( GMythMonitorHandler *monitor, gint msg_code, 
   146 							gchar* message, gpointer user_data )
   147 {
   148 	GMythLiveTV *live_tv = GMYTH_LIVETV ( user_data );
   149 	//g_object_ref( live_tv );
   150 	
   151 	gmyth_debug( "LIVETV Signal handler ( msg = %s, code = %d, live_tv param = %s, user_data = %s )\n", message, msg_code, live_tv != NULL ? "" : 
   152 					"NULL", user_data != NULL ? "" : "NULL" );
   153 	
   154 	if ( NULL == live_tv )
   155 	{
   156 		gmyth_debug( "LiveTV_obj is equals to NULL!!!" );
   157 		return;
   158 	}		
   159 	
   160 	switch ( msg_code ) 
   161 	{
   162 		
   163 		case GMYTH_BACKEND_PROGRAM_INFO_CHANGED:
   164 		{
   165 			gmyth_debug( "LIVETV Program Changed request received [ msg = %s ]. Watching if the new "\
   166 				"TV Chain ID is the same as the old one...\n", message );
   167 			if ( g_ascii_strcasecmp ( message, (gmyth_tvchain_get_id( live_tv->tvchain ))->str ) != 0 ) {				
   168 				gmyth_debug( "OK!!! MOVED to the next program chain [actual == %s]!", 
   169 										(gmyth_tvchain_get_id( live_tv->tvchain ))->str );
   170 				/* advertises the FileTransfer about the program info changed */
   171 				if ( live_tv->file_transfer != NULL )
   172 				{
   173 					gmyth_debug( "Emitting signal to the FileTransfer... [ \"program-info-changed \" ]" );
   174 					
   175 					gmyth_file_transfer_emit_program_info_changed_signal( live_tv->file_transfer,
   176 		             msg_code, (gpointer)live_tv );
   177 		             
   178 		      //gmyth_livetv_monitor_handler_stop( live_tv );	      
   179 				} else
   180 					gmyth_debug( "LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");				
   181 			}
   182 		}
   183 		case GMYTH_BACKEND_DONE_RECORDING:
   184 		{
   185 			gmyth_debug( "LIVETV Program Changed request received [ msg = %s ]. Watching if the new "\
   186 				"TV Chain ID is the same as the old one...\n", message );
   187 			if ( g_ascii_strcasecmp ( message, (gmyth_tvchain_get_id( live_tv->tvchain ))->str ) != 0 ) {				
   188 				gmyth_debug( "OK!!! MOVED to the next program chain [actual == %s]!", 
   189 										(gmyth_tvchain_get_id( live_tv->tvchain ))->str );
   190 				/* advertises the FileTransfer about the program info changed */
   191 				if ( live_tv->file_transfer != NULL )
   192 				{
   193 					gmyth_debug( "Emitting signal to the FileTransfer... [ \"program-info-changed \" ]" );
   194 					
   195 					gmyth_file_transfer_emit_program_info_changed_signal( live_tv->file_transfer,
   196 		             msg_code, (gpointer)live_tv );
   197 		             
   198 		      //gmyth_livetv_monitor_handler_stop( live_tv );	      
   199 				} else
   200 					gmyth_debug( "LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");				
   201 			}
   202 			
   203 			break;
   204 		}
   205 		default:
   206 			break;		
   207 	} /* switch (Monitor Handler messages) */
   208 	
   209 }
   210 
   211 gboolean
   212 gmyth_livetv_monitor_handler_start( GMythLiveTV *livetv )
   213 {
   214 	gboolean res = TRUE;
   215 	
   216 	if ( livetv->monitor != NULL )
   217 	{
   218 		g_object_unref( livetv->monitor );
   219 		livetv->monitor	= NULL;
   220 	}
   221 	
   222   livetv->monitor = gmyth_monitor_handler_new ( );
   223   
   224   res = gmyth_monitor_handler_open (livetv->monitor, livetv->backend_info->hostname, 
   225   				livetv->backend_info->port );
   226   
   227   if ( res == TRUE )
   228   {
   229   	gmyth_debug("Connect MythTV Monitor event socket! Trying to start the message handler...");
   230   	
   231   	res = gmyth_monitor_handler_start ( livetv->monitor );
   232   	
   233   	if (res)
   234   	{
   235   		gmyth_debug("MythTV Monitor event socket connected and listening!");
   236   		g_signal_connect ( G_OBJECT (livetv->monitor), "backend-events-handler",
   237                   (GCallback)gmyth_livetv_monitor_signal_handler,
   238                   livetv );
   239   	}
   240   	else
   241   	{
   242   		gmyth_debug("Problems when trying to start MythTV Monitor event socket!");
   243   		goto error;  		
   244   	}
   245   }
   246   
   247 error:
   248 	return res;
   249   
   250 }
   251 
   252 void
   253 gmyth_livetv_monitor_handler_stop( GMythLiveTV *livetv )
   254 {
   255 	
   256   if ( livetv->monitor != NULL )
   257   {
   258   	g_object_unref( livetv->monitor );
   259   	livetv->monitor = NULL;
   260   } 
   261   
   262 }  
   263 
   264 
   265 /*
   266 static gchar*
   267 gmyth_livetv_create_remote_url( GMythLiveTV *livetv )
   268 {
   269 	gchar *uri = g_strdup("");
   270 	gmyth_backend_info_get_remote_h
   271 	
   272 	//gmyth_backend(livetv->backend_info)
   273 	
   274 	return uri;
   275 }
   276 */
   277 
   278 static gboolean
   279 gmyth_livetv_setup_recorder_channel_name ( GMythLiveTV *livetv, gchar* channel, GMythBackendInfo *backend_info )
   280 {
   281 	gboolean res = TRUE;
   282 
   283 	GMythSocket *socket = gmyth_socket_new ();
   284 	
   285 	livetv->backend_info = backend_info;
   286 	
   287 	g_static_mutex_lock( &lock );
   288 
   289 	// FIME: Implement this at gmyth_socket
   290 	res = gmyth_socket_connect_to_backend (socket, livetv->backend_info->hostname,
   291 			livetv->backend_info->port, TRUE);
   292 	if (!res) {
   293 		g_warning ("[%s] LiveTV can not connect to backend", __FUNCTION__);	
   294 		res = FALSE;
   295 		goto error;
   296 	}
   297 	
   298 	livetv->is_livetv = TRUE;
   299 	
   300 	livetv->local_hostname  = gmyth_socket_get_local_hostname ();
   301 
   302 	if ( livetv->local_hostname == NULL ) {
   303 		res = FALSE;
   304 		goto error;
   305 	}
   306 
   307 	// Gets the recorder num
   308 	livetv->recorder = remote_request_next_free_recorder (socket, -1);
   309 	gmyth_socket_close_connection (socket);
   310 
   311 	if ( livetv->recorder == NULL ) {
   312 		g_warning ("[%s] None remote encoder available", __FUNCTION__);
   313 		res = FALSE;
   314 		goto error;
   315 	}
   316 	
   317 	// Init remote encoder. Opens its control socket.
   318 	res = gmyth_recorder_setup(livetv->recorder);
   319 	if ( !res ) {
   320 		g_warning ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
   321 		res = FALSE;
   322 		goto error;
   323 	}
   324 	
   325 	// Creates livetv chain handler
   326 	livetv->tvchain = GMYTH_TVCHAIN ( g_object_new(GMYTH_TVCHAIN_TYPE, NULL) );
   327 	gmyth_tvchain_initialize ( livetv->tvchain, livetv->backend_info );
   328 
   329 	if ( livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL ) {
   330 		res = FALSE;
   331 		goto error;
   332 	}
   333 	
   334 	// Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
   335 	res = gmyth_recorder_spawntv ( livetv->recorder,
   336 			gmyth_tvchain_get_id(livetv->tvchain) );
   337 	if (!res) {
   338 		g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__);
   339 		res = FALSE;
   340 		goto error;
   341 	}
   342 	
   343   if ( res == TRUE ) {
   344     /* loop finished, set the max tries variable to zero again... */
   345     gint wait_to_transfer = 0;
   346 
   347     while (wait_to_transfer++ < GMYTHTV_TRANSFER_MAX_WAITS &&
   348         (gmyth_recorder_is_recording (livetv->recorder) == FALSE))
   349       g_usleep (500);
   350 
   351     /* IS_RECORDING again, just like the MythTV backend does... */
   352     gmyth_recorder_is_recording (livetv->recorder);
   353     
   354 		if ( channel != NULL ) 
   355 		{
   356 			/* Pauses remote encoder. */
   357 			res = gmyth_recorder_pause_recording(livetv->recorder);
   358 			if ( !res ) {
   359 				g_warning ("[%s] Fail while pausing remote encoder\n", __FUNCTION__);
   360 				res = FALSE;
   361 				goto error;
   362 			}
   363 	
   364 	  	if ( gmyth_recorder_check_channel_name( livetv->recorder, channel ) )
   365 	  	{
   366 		  	if ( gmyth_recorder_set_channel_name( livetv->recorder, channel ) )
   367 		  	{
   368 		  		g_print( "[%s] Channel changed!!! [%s].\n", __FUNCTION__, channel );
   369 		  	}
   370 	  	}
   371 	
   372 		}
   373 		
   374     sleep (9);                  /* FIXME: this is evil (tpm) */
   375   }
   376   
   377   /* DEBUG message */  
   378 	GMythProgramInfo* prog_info = gmyth_recorder_get_current_program_info( livetv->recorder );
   379 	
   380 	if ( NULL == prog_info )
   381 	{
   382 		gmyth_debug( "ProgramInfo is equals to NULL!!!" );
   383 		
   384     gint i;
   385     gchar *channame = NULL;
   386 
   387     fprintf(stderr, "problem getting current proginfo!\n");
   388 
   389     /*
   390      * mythbackend must not be tuned in to a channel, so keep
   391      * changing channels until we find a valid one, or until
   392      * we decide to give up.
   393      */
   394     for (i=1; i<1000; i++) {
   395 			if ( channame != NULL )
   396 				g_free(channame);
   397       channame = g_strdup_printf( "%d", i );
   398       if (gmyth_recorder_set_channel_name(livetv->recorder, channame) < 0) {
   399       	continue;
   400       }
   401       prog_info = gmyth_recorder_get_next_program_info(livetv->recorder, BROWSE_DIRECTION_UP);
   402       if (prog_info != NULL)
   403       	break;
   404     }
   405 		
   406 	}
   407 	/* prints program info data text */ 
   408 	gmyth_debug( "New ProgramInfo...\n" );
   409 	gmyth_program_info_print( prog_info );
   410 	/* DEBUG message */
   411 	gmyth_debug( "Old ProgramInfo...\n" );
   412 	gmyth_program_info_print( livetv->proginfo );
   413 	
   414 	GMythProgramInfo* prog_inf = gmyth_recorder_get_next_program_info( livetv->recorder, BROWSE_DIRECTION_UP );
   415 	
   416 	gmyth_debug( "Next ProgramInfo...\n" );
   417 	gmyth_program_info_print( prog_inf );
   418 	
   419 	/* check if the program chain could be obtained from the MythTV protocol message */
   420 	if ( prog_info != NULL )
   421 	{
   422 		livetv->proginfo = prog_info;
   423 		/* testing change channel */
   424 		//gmyth_recorder_spawntv_no_tvchain( livetv->recorder );
   425 	} else {
   426 		
   427 		/* check for the program info in the TV program chain could be obtained 
   428 		   from the MythTV MySQL database */
   429 
   430 		/* Reload all TV chain from Mysql database. */
   431 		gmyth_tvchain_reload_all (livetv->tvchain);
   432 	
   433 		if ( livetv->tvchain == NULL ) {
   434 			res = FALSE;
   435 			goto error;
   436 		}
   437 		
   438 		/* Get program info from database using chanid and starttime */
   439 		livetv->proginfo = gmyth_tvchain_get_program_at (livetv->tvchain, tvchain_curr_index++ );
   440 		if ( livetv->proginfo == NULL ) {
   441 			g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
   442 			res = FALSE;
   443 			goto error;
   444 		} else {
   445 			res = TRUE;
   446 			gmyth_debug ("GMythLiveTV: All requests to backend to start TV were OK. [%s]\n", livetv->proginfo->pathname->str );
   447 		}
   448 		
   449 	}
   450 	
   451 	livetv->uri = (GMythURI*)gmyth_backend_info_get_uri( backend_info );
   452 	
   453 	g_static_mutex_unlock( &lock );
   454 
   455 	if ( !gmyth_livetv_monitor_handler_start( livetv ) )
   456 	{
   457 		res = FALSE;
   458 		gmyth_debug( "LiveTV MONITOR handler error on setup!" );
   459 		goto error;		
   460 	}
   461 	
   462 	livetv->setup_done = TRUE;
   463 	
   464 	return res;
   465 
   466 error:
   467 	g_print( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ );
   468 
   469 	if ( livetv->local_hostname != NULL ) {
   470 		g_string_free( livetv->local_hostname, FALSE );
   471 		res = FALSE;
   472 	}
   473 
   474 	if ( livetv->recorder != NULL ) {
   475 		g_object_unref (livetv->recorder);
   476 		livetv->recorder = NULL;
   477 	}
   478 
   479 	if ( livetv->tvchain != NULL ) {
   480 		g_object_unref (livetv->tvchain);
   481 		livetv->tvchain = NULL;
   482 	}
   483 
   484 	if ( livetv->proginfo != NULL ) {
   485 		g_object_unref (livetv->proginfo);
   486 		livetv->proginfo = NULL;
   487 	}
   488 
   489 	if ( livetv->monitor != NULL ) {
   490 		g_object_unref (livetv->monitor);
   491 		livetv->monitor = NULL;
   492 	}
   493 
   494 	return res;
   495 
   496 }
   497 
   498 static gboolean
   499 gmyth_livetv_setup_recorder ( GMythLiveTV *livetv, gint channel, GMythBackendInfo *backend_info )
   500 {
   501 	return gmyth_livetv_setup_recorder_channel_name ( livetv, ( channel != -1 ) ? 
   502 				g_strdup_printf( "%d", channel ) : NULL, backend_info );
   503 }
   504 
   505 gboolean
   506 gmyth_livetv_channel_setup ( GMythLiveTV *livetv, gint channel, GMythBackendInfo *backend_info )
   507 {
   508 	return gmyth_livetv_setup_recorder ( livetv, channel, backend_info );
   509 }
   510 
   511 gboolean
   512 gmyth_livetv_channel_name_setup ( GMythLiveTV *livetv, gchar* channel, GMythBackendInfo *backend_info )
   513 {
   514 	return gmyth_livetv_setup_recorder_channel_name ( livetv, channel, backend_info );
   515 }
   516 
   517 gboolean
   518 gmyth_livetv_setup ( GMythLiveTV *livetv, GMythBackendInfo *backend_info )
   519 {
   520 	return gmyth_livetv_setup_recorder ( livetv, -1, backend_info );
   521 }
   522 
   523 gboolean
   524 gmyth_livetv_next_program_chain ( GMythLiveTV *livetv )
   525 {
   526 	gboolean res = TRUE;
   527 	GMythProgramInfo *prog_info = NULL;
   528 	
   529 	if ( !livetv->setup_done )
   530 	{
   531 		gmyth_debug ( "Call the setup function first!" );
   532 		res= FALSE;
   533 		goto error;		
   534 	}
   535 	
   536 	prog_info = gmyth_recorder_get_next_program_info( livetv->recorder, BROWSE_DIRECTION_RIGHT );
   537 	
   538 	gmyth_debug( "Next ProgramInfo...\n" );
   539 	
   540 	if ( NULL == prog_info )
   541 	{
   542 		gmyth_debug( "ProgramInfo is equals to NULL!!!" );
   543 		
   544 		return FALSE;
   545 	}
   546 	/* prints program info data text */ 
   547 	gmyth_program_info_print( prog_info );
   548 
   549 	if ( prog_info != NULL ) {		
   550 		res = TRUE;
   551 		livetv->proginfo = prog_info;
   552 		gmyth_debug ("GMythLiveTV: All requests to backend to start TV were OK, program info changed.");
   553 	} else {
   554 		g_warning ("[%s] LiveTV not successfully started on the next program chain.\n", __FUNCTION__ );
   555 		res = FALSE;
   556 		goto error;
   557 	}
   558 	
   559 	livetv->setup_done = TRUE;
   560 
   561 	return res;
   562 
   563 error:
   564 	g_print( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ );
   565 
   566 	if ( livetv->local_hostname != NULL ) {
   567 		g_string_free( livetv->local_hostname, FALSE );
   568 		res = FALSE;
   569 	}
   570 
   571 	if ( livetv->recorder != NULL ) {
   572 		g_object_unref (livetv->recorder);
   573 		livetv->recorder = NULL;
   574 	}
   575 
   576 	if ( livetv->tvchain != NULL ) {
   577 		g_object_unref (livetv->tvchain);
   578 		livetv->tvchain = NULL;
   579 	}
   580 
   581 	if ( livetv->proginfo != NULL ) {
   582 		g_object_unref (livetv->proginfo);
   583 		livetv->proginfo = NULL;
   584 	}
   585 
   586 	return res;
   587 
   588 }
   589 
   590 GMythFileTransfer *
   591 gmyth_livetv_create_file_transfer( GMythLiveTV *livetv )
   592 {
   593 	//GMythURI* uri = NULL;
   594 	
   595 	if ( NULL == livetv )
   596 		goto done;
   597 	
   598 	if ( !livetv->setup_done )
   599 	{
   600 		gmyth_debug( "Error: You must do the LiveTV setup, just before generating the FileTransfer from LiveTV source!" );
   601 		goto done;
   602 	}
   603 	
   604 	if ( livetv->proginfo != NULL )
   605   	gmyth_debug( "URI path (from program info) = %s.\n", livetv->proginfo->pathname->str );
   606   else
   607   	gmyth_debug( "URI path (from URI) = %s.\n", livetv->uri->uri->str ); 
   608   
   609   g_static_mutex_lock( &lock );
   610   
   611   if ( livetv->file_transfer != NULL )
   612   {
   613   	/*gmyth_file_transfer_close( livetv->file_transfer );*/
   614   	g_object_unref( livetv->file_transfer );
   615   	livetv->file_transfer = NULL;
   616   }  	
   617 
   618   if ( livetv->uri != NULL )  
   619   {
   620   	/* 
   621   	if ( livetv->uri->path != NULL )
   622   	{
   623   		g_string_free( livetv->uri->path, FALSE );
   624   		livetv->uri->path = NULL;
   625   	}
   626   	*/
   627   	gmyth_debug( "URI is NULL, creating from the ProgramInfo pathname... (%s)", livetv->proginfo->pathname->str );
   628   	livetv->uri->path = g_string_erase(livetv->uri->path, 0, -1);
   629   	livetv->uri->path = g_string_new( g_strrstr( livetv->proginfo->pathname->str, "/" ) );
   630   } else {
   631   	gmyth_debug( "URI is NULL, creating from the ProgramInfo pathname... (%s)", livetv->proginfo->pathname->str );
   632   	livetv->uri = gmyth_uri_new_with_value( livetv->proginfo->pathname->str );
   633   }
   634   	
   635   if ( NULL == livetv->uri )
   636   {  	
   637   	gmyth_debug( "Couldn't parse the URI to start LiveTV! [ uri = %s ]", livetv->proginfo->pathname->str );
   638   	goto done;  	
   639   }
   640   
   641 	livetv->file_transfer = gmyth_file_transfer_new( livetv->backend_info );
   642 
   643   if ( NULL == livetv->file_transfer ) 
   644   {
   645   	gmyth_debug( "Error: couldn't create the FileTransfer from LiveTV source!" );
   646     goto done;
   647   }
   648 
   649 	if ( !gmyth_file_transfer_open( livetv->file_transfer, livetv->uri != NULL ? gmyth_uri_get_path(livetv->uri) : 
   650 				livetv->proginfo->pathname->str ) )
   651 	{
   652 		gmyth_debug( "Error: couldn't open the FileTransfer from LiveTV source!" );
   653 		g_object_unref( livetv->file_transfer );
   654 		livetv->file_transfer = NULL;
   655 		goto done;
   656 	}
   657 	
   658 	g_static_mutex_unlock( &lock );
   659 
   660 done:
   661 	/*
   662 	if ( uri != NULL )
   663 	{
   664 		g_object_unref( uri );
   665 		uri = NULL;
   666 	}
   667 	*/	
   668 	
   669 	return livetv->file_transfer;
   670 	
   671 }
   672 
   673 /* FIXME: How to proceed differently between livetv and recorded content */
   674 void
   675 gmyth_livetv_stop_playing (GMythLiveTV *livetv) 
   676 {
   677 	gmyth_debug ("Stopping the LiveTV...\n");
   678 
   679 	if (livetv->is_livetv) {
   680 		if ( !gmyth_recorder_stop_livetv (livetv->recorder) ) {
   681 			g_warning ("[%s] Error while stoping remote encoder", __FUNCTION__);	
   682 		}
   683 	}
   684 }
   685 
   686 gboolean
   687 gmyth_livetv_is_playing (GMythLiveTV *livetv)
   688 {
   689 	return TRUE;
   690 }
   691 
   692 void
   693 gmyth_livetv_start_playing (GMythLiveTV *livetv)
   694 {
   695 
   696 	// TODO
   697 
   698 }
   699