gmyth/src/gmyth_livetv.c
author rosfran
Thu Mar 01 20:03:52 2007 +0000 (2007-03-01)
branchtrunk
changeset 381 8ce480699085
parent 378 8ec23602c4ea
child 399 918644a59106
permissions -rwxr-xr-x
[svn r386] Put a mutex on the GMythFileTransfer send/receive transfer methods. Added timeout message to 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->socket = NULL;
    76 	livetv->recorder = NULL;
    77 	livetv->tvchain = NULL;
    78 	livetv->proginfo = NULL;
    79 	livetv->uri = NULL;
    80 	
    81 	livetv->mutex = NULL;
    82 
    83 }
    84 
    85 static void
    86 gmyth_livetv_dispose  (GObject *object)
    87 {	
    88 	GMythLiveTV *livetv = GMYTH_LIVETV (object);
    89 
    90 	if ( livetv->monitor != NULL ) {
    91 		g_object_unref (livetv->monitor);
    92 		livetv->monitor = NULL;
    93 	}
    94 	
    95 	if ( livetv->recorder != NULL ) {
    96 		//gmyth_livetv_stop_playing( 
    97 		g_object_unref (livetv->recorder);
    98 		livetv->recorder = NULL;
    99 	}
   100 
   101 	if ( livetv->socket != NULL ) {
   102 		g_object_unref (livetv->socket);
   103 		livetv->socket = NULL;
   104 	}
   105 	
   106 	if ( livetv->tvchain != NULL ) {
   107 		g_object_unref (livetv->tvchain);
   108 		livetv->tvchain = NULL;
   109 	}
   110 
   111 	if ( livetv->proginfo != NULL ) {
   112 		g_object_unref (livetv->proginfo);
   113 		livetv->proginfo = NULL;
   114 	}
   115 	
   116 	if ( livetv->file_transfer != NULL && G_IS_OBJECT(livetv->file_transfer) ) {
   117 		g_object_unref (livetv->file_transfer);
   118 		livetv->file_transfer = NULL;
   119 	}
   120 	
   121 	if ( livetv->backend_info != NULL ) {
   122 		g_object_unref (livetv->backend_info);
   123 		livetv->backend_info = NULL;
   124 	}
   125 	
   126 	if ( livetv->uri != NULL )
   127 	{
   128 		g_object_unref (livetv->uri);
   129 		livetv->uri = NULL;
   130 	}
   131 	
   132 	if ( livetv->mutex != NULL )
   133 	{
   134 		g_mutex_free (livetv->mutex);
   135 		livetv->mutex = NULL;
   136 	}
   137 	
   138 	G_OBJECT_CLASS (gmyth_livetv_parent_class)->dispose (object);
   139 }
   140 
   141 static void
   142 gmyth_livetv_finalize (GObject *object)
   143 {
   144 	g_signal_handlers_destroy (object);
   145 
   146 	G_OBJECT_CLASS ( gmyth_livetv_parent_class )->finalize ( object );
   147 }
   148 
   149 GMythLiveTV*
   150 gmyth_livetv_new ()
   151 {
   152 	GMythLiveTV *livetv = GMYTH_LIVETV ( g_object_new( GMYTH_LIVETV_TYPE, NULL ) );
   153 	
   154 	livetv->mutex = g_mutex_new();
   155 	
   156 	return livetv;
   157 }
   158 
   159 static void
   160 gmyth_livetv_monitor_signal_handler( GMythMonitorHandler *monitor, gint msg_code, 
   161 							gchar* message, gpointer user_data )
   162 {
   163 	GMythLiveTV *live_tv = GMYTH_LIVETV ( user_data );
   164 	//g_object_ref( live_tv );
   165 	
   166 	gmyth_debug( "LIVETV Signal handler ( msg = %s, code = %d, live_tv param = %s, user_data = %s )\n", message, msg_code, live_tv != NULL ? "" : 
   167 					"NULL", user_data != NULL ? "" : "NULL" );
   168 	
   169 	if ( NULL == live_tv )
   170 	{
   171 		gmyth_debug( "LiveTV_obj is equals to NULL!!!" );
   172 		return;
   173 	}		
   174 	
   175 	switch ( msg_code ) 
   176 	{
   177 		
   178 		case GMYTH_BACKEND_PROGRAM_INFO_CHANGED:
   179 		{
   180 			gmyth_debug( "LIVETV Program Changed request received [ msg = %s ]. Watching if the new "\
   181 				"TV Chain ID is the same as the old one...\n", message );
   182 			if ( g_ascii_strcasecmp ( message, (gmyth_tvchain_get_id( live_tv->tvchain ))->str ) != 0 ) {				
   183 				gmyth_debug( "OK!!! MOVED to the next program chain [actual == %s]!", 
   184 										(gmyth_tvchain_get_id( live_tv->tvchain ))->str );
   185 				/* advertises the FileTransfer about the program info changed */
   186 				if ( live_tv->file_transfer != NULL )
   187 				{
   188 					gmyth_debug( "Emitting signal to the FileTransfer... [ \"program-info-changed \" ]" );
   189 					/*
   190 					GMythProgramInfo* prog_info = gmyth_recorder_get_current_program_info( live_tv->recorder );
   191 					if ( prog_info != NULL )
   192 						live_tv->proginfo = prog_info;
   193 					*/
   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 		case GMYTH_BACKEND_DONE_RECORDING:
   204 		{
   205 			gmyth_debug( "LIVETV Program Changed request received [ msg = %s ]. Watching if the new "\
   206 				"TV Chain ID is the same as the old one...\n", message );
   207 			if ( g_ascii_strcasecmp ( message, (gmyth_tvchain_get_id( live_tv->tvchain ))->str ) != 0 ) {				
   208 				gmyth_debug( "OK!!! MOVED to the next program chain [actual == %s]!", 
   209 										(gmyth_tvchain_get_id( live_tv->tvchain ))->str );
   210 				/* advertises the FileTransfer about the program info changed */
   211 				if ( live_tv->file_transfer != NULL )
   212 				{
   213 					gmyth_debug( "Emitting signal to the FileTransfer... [ \"backend-done-recording\" ]" );
   214 					/*
   215 					GMythProgramInfo* prog_info = gmyth_recorder_get_current_program_info( live_tv->recorder );
   216 					if ( prog_info != NULL )
   217 						live_tv->proginfo = prog_info;
   218 						*/
   219 					
   220 					gmyth_file_transfer_emit_program_info_changed_signal( live_tv->file_transfer,
   221 		             msg_code, (gpointer)live_tv );
   222 		             
   223 		      //gmyth_livetv_monitor_handler_stop( live_tv );	      
   224 				} else
   225 					gmyth_debug( "LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");				
   226 			}
   227 		}
   228 		case GMYTH_BACKEND_STOP_LIVETV:
   229 		{
   230 			gmyth_debug( "LIVETV Stop LiveTV request received [ msg = %s ]. Going out the "\
   231 				"LiveTV...\n", message );
   232 			/* stops the LiveTV */
   233 			if ( live_tv != NULL )
   234 			{
   235 				gmyth_debug( "Going out the LiveTV... [ \"quit-livetv\" ]" );
   236 				
   237 				g_object_unref( live_tv );				
   238 			} else
   239 				gmyth_debug( "LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");				
   240 			
   241 			break;
   242 		}
   243 		default:
   244 			break;		
   245 	} /* switch (Monitor Handler messages) */
   246 	
   247 }
   248 
   249 gboolean
   250 gmyth_livetv_monitor_handler_start( GMythLiveTV *livetv )
   251 {
   252 	gboolean res = TRUE;
   253 	
   254 	if ( livetv->monitor != NULL )
   255 	{
   256 		g_object_unref( livetv->monitor );
   257 		livetv->monitor	= NULL;
   258 	}
   259 	
   260   livetv->monitor = gmyth_monitor_handler_new ( );
   261   
   262   res = gmyth_monitor_handler_open (livetv->monitor, livetv->backend_info->hostname, 
   263   				livetv->backend_info->port );
   264   
   265   if ( res == TRUE )
   266   {
   267   	gmyth_debug("Connect MythTV Monitor event socket! Trying to start the message handler...");
   268   	
   269   	res = gmyth_monitor_handler_start ( livetv->monitor );
   270   	
   271   	if (res)
   272   	{
   273   		gmyth_debug("MythTV Monitor event socket connected and listening!");
   274   		g_signal_connect ( G_OBJECT (livetv->monitor), "backend-events-handler",
   275                   (GCallback)gmyth_livetv_monitor_signal_handler,
   276                   livetv );
   277   	}
   278   	else
   279   	{
   280   		gmyth_debug("Problems when trying to start MythTV Monitor event socket!");
   281   		goto error;  		
   282   	}
   283   }
   284   
   285 error:
   286 	return res;
   287   
   288 }
   289 
   290 void
   291 gmyth_livetv_monitor_handler_stop( GMythLiveTV *livetv )
   292 {
   293 	
   294   if ( livetv->monitor != NULL )
   295   {
   296   	g_object_unref( livetv->monitor );
   297   	livetv->monitor = NULL;
   298   } 
   299   
   300 }
   301 
   302 /*
   303 static gchar*
   304 gmyth_livetv_create_remote_url( GMythLiveTV *livetv )
   305 {
   306 	gchar *uri = g_strdup("");
   307 	gmyth_backend_info_get_remote_h
   308 	
   309 	//gmyth_backend(livetv->backend_info)
   310 	
   311 	return uri;
   312 }
   313 */
   314 
   315 static gboolean
   316 gmyth_livetv_setup_recorder_channel_name ( GMythLiveTV *livetv, gchar* channel, 
   317 			GMythBackendInfo *backend_info )
   318 {
   319 	gboolean res = TRUE;
   320 	
   321 	livetv->backend_info = backend_info;
   322 		
   323 	if ( NULL == livetv->socket ) {
   324 		livetv->socket = gmyth_socket_new ();
   325 		
   326 		/* FIME: Implement this at gmyth_socket */
   327 		res = gmyth_socket_connect_to_backend (livetv->socket, livetv->backend_info->hostname,
   328 				livetv->backend_info->port, TRUE);
   329 		if (!res) {
   330 			g_warning ("[%s] LiveTV can not connect to backend", __FUNCTION__);	
   331 			res = FALSE;
   332 			goto error;
   333 		}
   334 	}
   335 	
   336 	g_mutex_lock( livetv->mutex );
   337 	
   338 	livetv->is_livetv = TRUE;
   339 	
   340 	livetv->local_hostname  = gmyth_socket_get_local_hostname ();
   341 
   342 	if ( livetv->local_hostname == NULL ) {
   343 		res = FALSE;
   344 		goto error;
   345 	}
   346 	
   347 	if  ( livetv->recorder != NULL )
   348 	{
   349 		g_object_unref( livetv->recorder );
   350 		livetv->recorder= NULL;
   351 	} 
   352 	
   353 	if ( gmyth_remote_util_get_free_recorder_count (livetv->socket) <= 0 ) {
   354 		gmyth_debug ("No free remote encoder available.");
   355 		
   356 		res = FALSE;
   357 		goto error;
   358 	}
   359 	
   360 	/* Gets the recorder num */
   361 	livetv->recorder = remote_request_next_free_recorder (livetv->socket, -1);
   362 	gmyth_socket_close_connection (livetv->socket);
   363 
   364 	if ( NULL == livetv->recorder ) {
   365 		g_warning ("[%s] None remote encoder available", __FUNCTION__);
   366 		res = FALSE;
   367 		goto error;
   368 	}
   369 	
   370 	/* Init remote encoder. Opens its control socket. */
   371 	res = gmyth_recorder_setup(livetv->recorder);
   372 	if ( !res ) {
   373 		g_warning ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
   374 		res = FALSE;
   375 		goto error;
   376 	}
   377 	
   378 	/* Creates livetv chain handler */
   379 	livetv->tvchain = gmyth_tvchain_new();
   380 	gmyth_tvchain_initialize ( livetv->tvchain, livetv->backend_info );
   381 
   382 	if ( livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL ) {
   383 		res = FALSE;
   384 		goto error;
   385 	}
   386 	
   387 	// Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
   388 	res = gmyth_recorder_spawntv ( livetv->recorder,
   389 			gmyth_tvchain_get_id(livetv->tvchain) );
   390 	if (!res) {
   391 		g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__);
   392 		res = FALSE;
   393 		goto error;
   394 	}
   395 	
   396   if ( res == TRUE ) {
   397     /* loop finished, set the max tries variable to zero again... */
   398     gint wait_to_transfer = 0;
   399 
   400     while (wait_to_transfer++ < GMYTHTV_TRANSFER_MAX_WAITS &&
   401         (gmyth_recorder_is_recording (livetv->recorder) == FALSE))
   402       g_usleep (800);
   403 
   404 		if ( channel != NULL ) 
   405 		{
   406 			/* Pauses remote encoder. */
   407 			res = gmyth_recorder_pause_recording(livetv->recorder);
   408 			if ( !res ) {
   409 				g_warning ("[%s] Fail while pausing remote encoder\n", __FUNCTION__);
   410 				res = FALSE;
   411 				goto error;
   412 			}
   413 	
   414 	  	if ( gmyth_recorder_check_channel_name( livetv->recorder, channel ) )
   415 	  	{
   416 		  	if ( gmyth_recorder_set_channel_name( livetv->recorder, channel ) )
   417 		  	{
   418 		  		gmyth_debug( "Channel changed!!! [%s].\n", channel );
   419 		  	}
   420 	  	}
   421 	
   422 		} /* if - changes the channel number */
   423 		
   424     sleep (2);                  /* FIXME: this is evil (tpm) */
   425   }
   426   
   427   /* DEBUG message */  
   428 	GMythProgramInfo* prog_info = gmyth_recorder_get_current_program_info( livetv->recorder );
   429 	
   430 	if ( NULL == prog_info )
   431 	{
   432 		gmyth_debug( "ProgramInfo is equals to NULL!!!" );
   433 		
   434     gint i;
   435     gchar *channame = NULL;
   436 
   437     gmyth_debug( "Problem getting current proginfo!\n" );
   438 
   439     /*
   440      * mythbackend must not be tuned in to a channel, so keep
   441      * changing channels until we find a valid one, or until
   442      * we decide to give up.
   443      */
   444     for (i=1; i<1000; i++) {
   445 			if ( channame != NULL )
   446 				g_free(channame);
   447       channame = g_strdup_printf( "%d", i );
   448       if (gmyth_recorder_set_channel_name(livetv->recorder, channame) < 0) {
   449       	continue;
   450       }
   451       prog_info = gmyth_recorder_get_next_program_info(livetv->recorder, BROWSE_DIRECTION_UP);
   452       if (prog_info != NULL)
   453       	break;
   454     }
   455 
   456 	} /* if - Program Info */
   457 	
   458 	/* prints program info data text */ 
   459 	gmyth_debug( "New ProgramInfo...\n" );
   460 	gmyth_program_info_print( prog_info );
   461 	/* DEBUG message */
   462 	/*
   463 	gmyth_debug( "Old ProgramInfo...\n" );
   464 	gmyth_program_info_print( livetv->proginfo );
   465 	*/	
   466 	/*
   467 	GMythProgramInfo* prog_inf = gmyth_recorder_get_next_program_info( livetv->recorder, BROWSE_DIRECTION_UP );
   468 	
   469 	gmyth_debug( "Next ProgramInfo...\n" );
   470 	gmyth_program_info_print( prog_inf );
   471 	*/
   472 	
   473 	/* check if the program chain could be obtained from the MythTV protocol message */
   474 	if ( prog_info != NULL )
   475 	{
   476 		g_debug( "Program Info: %s\n", gmyth_program_info_to_string( prog_info ) );
   477 		livetv->proginfo = prog_info;
   478 		/* testing change channel */
   479 		//gmyth_recorder_spawntv_no_tvchain( livetv->recorder );
   480 	} else {
   481 		
   482 		/* check for the program info in the TV program chain could be obtained 
   483 		   from the MythTV MySQL database */
   484 
   485 		/* Reload all TV chain from Mysql database. */
   486 		gmyth_tvchain_reload_all (livetv->tvchain);
   487 	
   488 		if ( livetv->tvchain == NULL ) {
   489 			res = FALSE;
   490 			goto error;
   491 		}
   492 		
   493 		/* Get program info from database using chanid and starttime */
   494 		livetv->proginfo = gmyth_tvchain_get_program_at (livetv->tvchain, tvchain_curr_index++ );
   495 		if ( livetv->proginfo == NULL ) {
   496 			g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
   497 			res = FALSE;
   498 			goto error;
   499 		} else {
   500 			res = TRUE;
   501 			gmyth_debug ("GMythLiveTV: All requests to backend to start TV were OK. [%s]\n", livetv->proginfo->pathname->str );
   502 		}
   503 		
   504 	}
   505 	
   506 	livetv->uri = (GMythURI*)gmyth_backend_info_get_uri( backend_info );
   507 	
   508 	g_mutex_unlock( livetv->mutex );
   509 
   510 	if ( !gmyth_livetv_monitor_handler_start( livetv ) )
   511 	{
   512 		res = FALSE;
   513 		gmyth_debug( "LiveTV MONITOR handler error on setup!" );
   514 		goto error;		
   515 	}
   516 	
   517 	livetv->setup_done = TRUE;
   518 	
   519 	return res;
   520 
   521 error:
   522 	g_print( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ );
   523 
   524 	if ( livetv->local_hostname != NULL ) {
   525 		g_string_free( livetv->local_hostname, TRUE );
   526 		livetv->local_hostname = NULL;
   527 		res = FALSE;
   528 	}
   529 
   530 	if ( livetv->recorder != NULL ) {
   531 		g_object_unref (livetv->recorder);
   532 		livetv->recorder = NULL;
   533 	}
   534 
   535 	if ( livetv->tvchain != NULL ) {
   536 		g_object_unref (livetv->tvchain);
   537 		livetv->tvchain = NULL;
   538 	}
   539 
   540 	if ( livetv->proginfo != NULL ) {
   541 		g_object_unref (livetv->proginfo);
   542 		livetv->proginfo = NULL;
   543 	}
   544 
   545 	if ( livetv->monitor != NULL ) {
   546 		g_object_unref (livetv->monitor);
   547 		livetv->monitor = NULL;
   548 	}
   549 
   550 	return res;
   551 
   552 }
   553 
   554 static gboolean
   555 gmyth_livetv_setup_recorder ( GMythLiveTV *livetv, gint channel, GMythBackendInfo *backend_info )
   556 {
   557 	return gmyth_livetv_setup_recorder_channel_name ( livetv, ( channel != -1 ) ? 
   558 				g_strdup_printf( "%d", channel ) : NULL, backend_info );
   559 }
   560 
   561 gboolean
   562 gmyth_livetv_channel_setup ( GMythLiveTV *livetv, gint channel, GMythBackendInfo *backend_info )
   563 {
   564 	return gmyth_livetv_setup_recorder ( livetv, channel, backend_info );
   565 }
   566 
   567 gboolean
   568 gmyth_livetv_channel_name_setup ( GMythLiveTV *livetv, gchar* channel, GMythBackendInfo *backend_info )
   569 {
   570 	return gmyth_livetv_setup_recorder_channel_name ( livetv, channel, backend_info );
   571 }
   572 
   573 gboolean
   574 gmyth_livetv_setup ( GMythLiveTV *livetv, GMythBackendInfo *backend_info )
   575 {
   576 	return gmyth_livetv_setup_recorder ( livetv, -1, backend_info );
   577 }
   578 
   579 gboolean
   580 gmyth_livetv_next_program_chain ( GMythLiveTV *livetv )
   581 {
   582 	gboolean res = TRUE;
   583 	GMythProgramInfo *prog_info = NULL;
   584 	
   585 	if ( !livetv->setup_done )
   586 	{
   587 		gmyth_debug ( "Call the setup function first!" );
   588 		res= FALSE;
   589 		goto error;		
   590 	}
   591 	
   592 	gmyth_debug( "Current ProgramInfo...\n" );
   593 	prog_info = gmyth_recorder_get_current_program_info( livetv->recorder );
   594 	
   595 	if ( prog_info != NULL )
   596 	{
   597 		livetv->proginfo = prog_info;
   598 	} else {
   599 		gmyth_debug( "ProgramInfo is equals to NULL!!! Getting the next program info..." );
   600 		prog_info = gmyth_recorder_get_next_program_info( livetv->recorder, BROWSE_DIRECTION_RIGHT );
   601 		livetv->proginfo = prog_info;		
   602 	}
   603 	/* prints program info data text */ 
   604 	gmyth_program_info_print( prog_info );
   605 
   606 	if ( prog_info != NULL ) {		
   607 		res = TRUE;
   608 		livetv->proginfo = prog_info;
   609 		gmyth_debug ("GMythLiveTV: All requests to backend to start TV were OK, program info changed.");
   610 	} else {
   611 		g_warning ("[%s] LiveTV not successfully started on the next program chain.\n", __FUNCTION__ );
   612 		res = FALSE;
   613 		goto error;
   614 	}
   615 	
   616 	livetv->setup_done = TRUE;
   617 
   618 	return res;
   619 
   620 error:
   621 	g_print( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ );
   622 
   623 	if ( livetv->local_hostname != NULL ) {
   624 		g_string_free( livetv->local_hostname, FALSE );
   625 		res = FALSE;
   626 	}
   627 
   628 	if ( livetv->recorder != NULL ) {
   629 		g_object_unref (livetv->recorder);
   630 		livetv->recorder = NULL;
   631 	}
   632 
   633 	if ( livetv->tvchain != NULL ) {
   634 		g_object_unref (livetv->tvchain);
   635 		livetv->tvchain = NULL;
   636 	}
   637 
   638 	if ( livetv->proginfo != NULL ) {
   639 		g_object_unref (livetv->proginfo);
   640 		livetv->proginfo = NULL;
   641 	}
   642 
   643 	return res;
   644 
   645 }
   646 
   647 GMythFileTransfer *
   648 gmyth_livetv_create_file_transfer( GMythLiveTV *livetv )
   649 {
   650 	//GMythURI* uri = NULL;
   651 	
   652 	if ( NULL == livetv )
   653 		goto done;
   654 	
   655 	if ( !livetv->setup_done )
   656 	{
   657 		gmyth_debug( "Error: You must do the LiveTV setup, just before generating the FileTransfer from LiveTV source!" );
   658 		goto done;
   659 	}
   660 	
   661 	if ( livetv->proginfo != NULL )
   662   	gmyth_debug( "URI path (from program info) = %s.\n", livetv->proginfo->pathname->str );
   663   else
   664   	gmyth_debug( "URI path (from URI) = %s.\n", livetv->uri->uri->str ); 
   665   
   666   g_mutex_lock( livetv->mutex );
   667   
   668   if ( livetv->file_transfer != NULL )
   669   {
   670   	/*gmyth_file_transfer_close( livetv->file_transfer );*/
   671   	g_object_unref( livetv->file_transfer );
   672   	livetv->file_transfer = NULL;
   673   }  	
   674 
   675   if ( livetv->uri != NULL )  
   676   {
   677   	/* 
   678   	if ( livetv->uri->path != NULL )
   679   	{
   680   		g_string_free( livetv->uri->path, FALSE );
   681   		livetv->uri->path = NULL;
   682   	}
   683   	*/
   684   	gmyth_debug( "URI is NULL, creating from the ProgramInfo pathname... (%s)", livetv->proginfo->pathname->str );
   685   	livetv->uri->path = g_string_erase(livetv->uri->path, 0, -1);
   686   	livetv->uri->path = g_string_new( g_strrstr( livetv->proginfo->pathname->str, "/" ) );
   687   } else {
   688   	gmyth_debug( "URI is NULL, creating from the ProgramInfo pathname... (%s)", livetv->proginfo->pathname->str );
   689   	livetv->uri = gmyth_uri_new_with_value( livetv->proginfo->pathname->str );
   690   }
   691   	
   692   if ( NULL == livetv->uri )
   693   {  	
   694   	gmyth_debug( "Couldn't parse the URI to start LiveTV! [ uri = %s ]", livetv->proginfo->pathname->str );
   695   	goto done;  	
   696   }
   697   
   698 	livetv->file_transfer = gmyth_file_transfer_new( livetv->backend_info );
   699 
   700   if ( NULL == livetv->file_transfer ) 
   701   {
   702   	gmyth_debug( "Error: couldn't create the FileTransfer from LiveTV source!" );
   703     goto done;
   704   }
   705   
   706   gmyth_file_transfer_settimeout( livetv->file_transfer, TRUE );
   707 	
   708 	g_mutex_unlock( livetv->mutex );
   709 
   710 done:
   711 	/*
   712 	if ( uri != NULL )
   713 	{
   714 		g_object_unref( uri );
   715 		uri = NULL;
   716 	}
   717 	*/	
   718 	
   719 	return livetv->file_transfer;
   720 	
   721 }
   722 
   723 /* FIXME: How to proceed differently between livetv and recorded content */
   724 void
   725 gmyth_livetv_stop_playing (GMythLiveTV *livetv) 
   726 {
   727 	gmyth_debug ("Stopping the LiveTV...\n");
   728 
   729 	if (livetv->is_livetv) {
   730 		if ( !gmyth_recorder_stop_livetv (livetv->recorder) ) {
   731 			g_debug ("[%s] Error while stoping remote encoder", __FUNCTION__);	
   732 		}
   733 		
   734 		if ( !gmyth_recorder_finish_recording(livetv->recorder) ) {
   735 			g_debug ("[%s] Error while finishing recording on remote encoder", __FUNCTION__);	
   736 		}
   737 	}
   738 }
   739 
   740 gboolean
   741 gmyth_livetv_is_playing (GMythLiveTV *livetv)
   742 {
   743 	return TRUE;
   744 }
   745 
   746 void
   747 gmyth_livetv_start_playing (GMythLiveTV *livetv)
   748 {
   749 
   750 	// TODO
   751 
   752 }
   753