gmyth/src/gmyth_livetv.c
author renatofilho
Tue Apr 03 14:56:51 2007 +0100 (2007-04-03)
branchtrunk
changeset 481 6d00c497a403
parent 472 e5618b012121
child 486 56b98fd15019
permissions -rwxr-xr-x
[svn r486] fixed bug on filetransfer
     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 #include "gmyth_common.h"
    43 
    44 static void gmyth_livetv_class_init          (GMythLiveTVClass *klass);
    45 static void gmyth_livetv_init                (GMythLiveTV *object);
    46 
    47 static void gmyth_livetv_dispose  (GObject *object);
    48 static void gmyth_livetv_finalize (GObject *object);
    49 
    50 static gint tvchain_curr_index = -1; 
    51 
    52 /*static GStaticMutex lock = G_STATIC_MUTEX_INIT;*/
    53 
    54 #define GMYTHTV_TRANSFER_MAX_WAITS	    100
    55 
    56 G_DEFINE_TYPE(GMythLiveTV, gmyth_livetv, G_TYPE_OBJECT)
    57 
    58 static void
    59 gmyth_livetv_class_init (GMythLiveTVClass *klass)
    60 {
    61 	GObjectClass *gobject_class;
    62 
    63 	gobject_class = (GObjectClass *) klass;
    64 
    65 	gobject_class->dispose  = gmyth_livetv_dispose;
    66 	gobject_class->finalize = gmyth_livetv_finalize;	
    67 }
    68 
    69 static void
    70 gmyth_livetv_init (GMythLiveTV *livetv)
    71 {
    72     livetv->monitor = NULL;
    73 	livetv->backend_info = NULL;
    74 	livetv->local_hostname = NULL;
    75 	livetv->file_transfer = NULL;
    76 	livetv->setup_done = FALSE;
    77 	
    78 	livetv->socket = NULL;
    79 	livetv->recorder = NULL;
    80 	livetv->tvchain = NULL;
    81 	livetv->proginfo = NULL;
    82 	livetv->uri = NULL;
    83 	
    84 	livetv->mutex = g_mutex_new();
    85 }
    86 
    87 static void
    88 gmyth_livetv_dispose  (GObject *object)
    89 {	
    90 	GMythLiveTV *livetv = GMYTH_LIVETV (object);
    91 
    92     if (livetv->disposed) {
    93         /* If dispose did already run, return. */
    94         return;
    95     }
    96     
    97     /* Make sure dispose does not run twice. */
    98     livetv->disposed = TRUE;
    99 
   100 	if ( livetv->monitor != NULL ) {
   101 		g_object_unref (livetv->monitor);
   102 		livetv->monitor = NULL;
   103 	}
   104 	
   105 	if ( livetv->recorder != NULL ) {
   106 		g_object_unref (livetv->recorder);
   107 		livetv->recorder = NULL;
   108 	}
   109 
   110 	if ( livetv->socket != NULL ) {
   111 		g_object_unref (livetv->socket);
   112 		livetv->socket = NULL;
   113 	}
   114 	
   115 	if ( livetv->tvchain != NULL ) {
   116 		g_object_unref (livetv->tvchain);
   117 		livetv->tvchain = NULL;
   118 	}
   119 
   120 	if ( livetv->proginfo != NULL ) {
   121 		g_object_unref (livetv->proginfo);
   122 		livetv->proginfo = NULL;
   123 	}
   124 	
   125 	if ( livetv->file_transfer != NULL ) {
   126 		g_object_unref (livetv->file_transfer);
   127 		livetv->file_transfer = NULL;
   128 	}
   129 	
   130 	if ( livetv->backend_info != NULL ) {
   131 		g_object_unref (livetv->backend_info);
   132 		livetv->backend_info = NULL;
   133 	}
   134 	
   135 	if ( livetv->uri != NULL ) {
   136 		g_object_unref (livetv->uri);
   137 		livetv->uri = NULL;
   138 	}
   139 	
   140 	if ( livetv->mutex != NULL ) {
   141 		g_mutex_free (livetv->mutex);
   142 		livetv->mutex = NULL;
   143 	}
   144     
   145     if ( livetv->local_hostname != NULL ) {
   146         g_string_free (livetv->local_hostname, TRUE);
   147         livetv->local_hostname = NULL;
   148     }
   149 
   150 	G_OBJECT_CLASS (gmyth_livetv_parent_class)->dispose (object);
   151 }
   152 
   153 static void
   154 gmyth_livetv_finalize (GObject *object)
   155 {
   156 	g_signal_handlers_destroy (object);
   157 
   158 	G_OBJECT_CLASS ( gmyth_livetv_parent_class )->finalize ( object );
   159 }
   160 
   161 /**
   162  * Creates a new GMythLiveTV instance
   163  * 
   164  * @return a newly allocated GMythLiveTV instance
   165  */
   166 GMythLiveTV*
   167 gmyth_livetv_new (GMythBackendInfo *backend_info)
   168 {
   169 	GMythLiveTV *livetv = GMYTH_LIVETV ( g_object_new( GMYTH_LIVETV_TYPE, NULL ) );
   170     
   171 	livetv->backend_info = backend_info;
   172     g_object_ref (livetv->backend_info);
   173 
   174 	return livetv;
   175 }
   176 
   177 /**
   178  * The GObject signal handler function, from which all status messages 
   179  * from the Monitor Handler will be advertized, all time it receives
   180  * LiveTV status messages from the MythTV backend
   181  * 
   182  * @param monitor a GMythMonitorHandler instance
   183  * @param msg_code the MythTV's server numeric status code
   184  * @param message the message's string description
   185  * @param user_data pointer to the GMythLiveTV instance
   186  */
   187 static void
   188 gmyth_livetv_monitor_signal_handler( GMythMonitorHandler *monitor, gint msg_code, 
   189 							gchar* message, gpointer user_data )
   190 {
   191 	GMythLiveTV *live_tv = GMYTH_LIVETV ( user_data );
   192 	
   193 	gmyth_debug( "LIVETV Signal handler ( msg = %s, code = %d, live_tv param = %s, user_data = %s )\n", message, msg_code, live_tv != NULL ? "" : 
   194 					"NULL", user_data != NULL ? "" : "NULL" );
   195 	
   196 	if ( NULL == live_tv )
   197 	{
   198 		gmyth_debug( "LiveTV_obj is equals to NULL!!!" );
   199 		return;
   200 	}		
   201 	
   202 	switch ( msg_code ) 
   203 	{
   204 		
   205 		case GMYTH_BACKEND_PROGRAM_INFO_CHANGED:
   206 		{
   207 			gmyth_debug( "LIVETV Program Changed request received [ msg = %s ]. Watching if the new "\
   208 				"TV Chain ID is the same as the old one...\n", message );
   209 			if ( g_ascii_strcasecmp ( message, (gmyth_tvchain_get_id( live_tv->tvchain ))->str ) != 0 ) {				
   210 				gmyth_debug( "OK!!! MOVED to the next program chain [actual == %s]!", 
   211 										(gmyth_tvchain_get_id( live_tv->tvchain ))->str );
   212 				/* advertises the FileTransfer about the program info changed */
   213 				if ( live_tv->file_transfer != NULL )
   214 				{
   215 					gmyth_debug( "Emitting signal to the FileTransfer... [ \"program-info-changed \" ]" );
   216 					
   217 					gmyth_file_transfer_emit_program_info_changed_signal( live_tv->file_transfer,
   218 		             msg_code, (gpointer)(live_tv->recorder) );
   219 		             
   220 					/* gmyth_livetv_monitor_handler_stop( live_tv ); */
   221 				} else
   222 					gmyth_debug( "LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");				
   223 			}
   224 			break;
   225 		}
   226 		case GMYTH_BACKEND_DONE_RECORDING:
   227 		{
   228 			gmyth_debug( "LIVETV Program Changed request received [ msg = %s ]. Watching if the new "\
   229 				"TV Chain ID is the same as the old one...\n", message );
   230 			if ( g_ascii_strcasecmp ( message, (gmyth_tvchain_get_id( live_tv->tvchain ))->str ) != 0 ) {				
   231 				gmyth_debug( "OK!!! MOVED to the next program chain [actual == %s]!", 
   232 										(gmyth_tvchain_get_id( live_tv->tvchain ))->str );
   233 				/* advertises the FileTransfer about the program info changed */
   234 				if ( live_tv->file_transfer != NULL )
   235 				{
   236 					gmyth_debug( "Emitting signal to the FileTransfer... [ \"backend-done-recording\" ]" );
   237 					
   238 					gmyth_file_transfer_emit_program_info_changed_signal( live_tv->file_transfer,
   239 		             msg_code, (gpointer)(live_tv->recorder) );
   240 		             
   241 				} else
   242 					gmyth_debug( "LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");				
   243 			}
   244 			break;
   245 		}
   246 		case GMYTH_BACKEND_STOP_LIVETV:
   247 		{
   248 			gmyth_debug( "LIVETV Stop LiveTV request received [ msg = %s ]. Going out the "\
   249 				"LiveTV...\n", message );
   250 			/* stops the LiveTV */
   251 			if ( live_tv != NULL )
   252 			{
   253 				gmyth_debug( "Going out the LiveTV... [ \"quit-livetv\" ]" );
   254 				
   255 				g_object_unref( live_tv );
   256 			} else
   257 				gmyth_debug( "LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");				
   258 			
   259 			break;
   260 		}
   261 		default:
   262 			break;		
   263 	} /* switch (Monitor Handler messages) */
   264 	
   265 }
   266 
   267 /**
   268  * Starts the Monitor Handler to this GMythLiveTV session, in order
   269  * to receive the status messages from the MythTV's backend server 
   270  * 
   271  * @param live_tv the GMythLiveTV instance
   272  * 
   273  * @return <code>true</code> if the Monitor Handler start-up process
   274  * 	   had been concluded succcesfully 
   275  */
   276 gboolean
   277 gmyth_livetv_monitor_handler_start( GMythLiveTV *livetv )
   278 {
   279 	gboolean res = TRUE;
   280 	
   281 	if ( livetv->monitor != NULL )
   282 	{
   283 		g_object_unref( livetv->monitor );
   284 		livetv->monitor	= NULL;
   285 	}
   286 	
   287   livetv->monitor = gmyth_monitor_handler_new ( );
   288   
   289   res = gmyth_monitor_handler_open (livetv->monitor, livetv->backend_info->hostname, 
   290   				livetv->backend_info->port );
   291   
   292   if ( res == TRUE )
   293   {
   294   	gmyth_debug("Connect MythTV Monitor event socket! Trying to start the message handler...");
   295   	
   296   	res = gmyth_monitor_handler_start ( livetv->monitor );
   297   	
   298   	if (res)
   299   	{
   300   		gmyth_debug("MythTV Monitor event socket connected and listening!");
   301   		g_signal_connect ( G_OBJECT (livetv->monitor), "backend-events-handler",
   302                   (GCallback)gmyth_livetv_monitor_signal_handler,
   303                   livetv );
   304   	}
   305   	else
   306   	{
   307   		gmyth_debug("Problems when trying to start MythTV Monitor event socket!");
   308   		goto error;  		
   309   	}
   310   }
   311   
   312 error:
   313 	return res;
   314   
   315 }
   316 
   317 /**
   318  * Stops the Monitor Handler to this GMythLiveTV session, in order
   319  * to stop receiving the status messages from the MythTV's backend server 
   320  * 
   321  * @param live_tv the GMythLiveTV instance
   322  * 
   323  * @return <code>true</code> if the Monitor Handler shutdown process
   324  * 	   had been concluded succcesfully 
   325  */
   326 void
   327 gmyth_livetv_monitor_handler_stop( GMythLiveTV *livetv )
   328 {
   329 	
   330   if ( livetv->monitor != NULL )
   331   {
   332   	g_object_unref( livetv->monitor );
   333   	livetv->monitor = NULL;
   334   } 
   335   
   336 }
   337 
   338 #if 0
   339 static gchar*
   340 gmyth_livetv_create_remote_url( GMythLiveTV *livetv )
   341 {
   342 	gchar *uri = g_strdup("");
   343 	gmyth_backend_info_get_remote_h
   344 	
   345 	//gmyth_backend(livetv->backend_info)
   346 	
   347 	return uri;
   348 }
   349 #endif
   350 
   351 /**
   352  * Configures the GMythLiveTV session, sends SPAWN_LIVETV message, 
   353  * sets the channel name, and gets the first program info about the
   354  * actual recording 
   355  * 
   356  * @param live_tv the GMythLiveTV instance
   357  * @param channel the channel name (the chan_name field, from the tvchain table)
   358  * @param backend_info the GMythBackendInfo describing the remote server
   359  * 
   360  * @return <code>true</code> if the LiveTV's recorder instance configuration 
   361  * 				had been concluded succcesfully 
   362  */
   363 static gboolean
   364 gmyth_livetv_setup_recorder_channel_name (GMythLiveTV *livetv, gchar* channel)
   365 {
   366 	gboolean res = TRUE;
   367     
   368     g_return_val_if_fail (livetv != NULL, FALSE);
   369     
   370 	if ( NULL == livetv->socket ) {
   371 		livetv->socket = gmyth_socket_new ();
   372 		
   373 		/* FIME: Implement this at gmyth_socket */
   374 		res = gmyth_socket_connect_to_backend (livetv->socket, livetv->backend_info->hostname,
   375 				livetv->backend_info->port, TRUE);
   376 		if (!res) {
   377 			gmyth_debug ("[%s] LiveTV can not connect to backend", __FUNCTION__);	
   378 			res = FALSE;
   379 			goto error;
   380 		}
   381 	}
   382 	
   383 	g_mutex_lock( livetv->mutex );
   384 	
   385 	livetv->is_livetv = TRUE;
   386 	
   387 	livetv->local_hostname  = gmyth_socket_get_local_hostname ();
   388 
   389 	if ( livetv->local_hostname == NULL ) {
   390 		res = FALSE;
   391 		goto error;
   392 	}
   393 	
   394 	if  ( livetv->recorder != NULL )
   395 	{
   396 		g_object_unref( livetv->recorder );
   397 		livetv->recorder= NULL;
   398 	} 
   399 	
   400 	if ( gmyth_remote_util_get_free_recorder_count (livetv->socket) <= 0 ) {
   401 		
   402 #ifdef GMYTH_USE_DEBUG
   403 		gmyth_debug ("No free remote encoder available.");
   404 #endif
   405 		res = FALSE;
   406 		goto error;
   407 	}
   408 
   409 	/* Gets the recorder num */
   410 	livetv->recorder = remote_request_next_free_recorder (livetv->socket, -1);
   411 	gmyth_socket_close_connection (livetv->socket);
   412 
   413 	if ( NULL == livetv->recorder ) {
   414 		gmyth_debug ("[%s] None remote encoder available", __FUNCTION__);
   415 		res = FALSE;
   416 		goto error;
   417 	}
   418 	
   419 	/* Init remote encoder. Opens its control socket. */
   420 	res = gmyth_recorder_setup(livetv->recorder);
   421 	if ( !res ) {
   422 		gmyth_debug ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
   423 		res = FALSE;
   424 		goto error;
   425 	}
   426 	
   427 	/* Creates livetv chain handler */
   428 	livetv->tvchain = gmyth_tvchain_new();
   429 	gmyth_tvchain_initialize ( livetv->tvchain, livetv->backend_info );
   430 
   431 	if ( livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL ) {
   432 		res = FALSE;
   433 		goto error;
   434 	}
   435 	
   436 	// Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
   437 	res = gmyth_recorder_spawntv ( livetv->recorder,
   438 			gmyth_tvchain_get_id(livetv->tvchain) );
   439 	if (!res) {
   440 		gmyth_debug ("[%s] Fail while spawn tv\n", __FUNCTION__);
   441 		res = FALSE;
   442 		goto error;
   443 	}
   444 	
   445   if ( res == TRUE ) {
   446     /* loop finished, set the max tries variable to zero again... */
   447     gint wait_to_transfer = 0;
   448 
   449     while (wait_to_transfer++ < GMYTHTV_TRANSFER_MAX_WAITS &&
   450         (gmyth_recorder_is_recording (livetv->recorder) == FALSE))
   451       g_usleep (300);
   452 
   453 		if ( channel != NULL ) 
   454 		{
   455 			/* Pauses remote encoder. */
   456 			res = gmyth_recorder_pause_recording(livetv->recorder);
   457 			if ( !res ) {
   458 				gmyth_debug ("[%s] Fail while pausing remote encoder\n", __FUNCTION__);
   459 				res = FALSE;
   460 				goto error;
   461 			}
   462 	
   463     	  	if ( gmyth_recorder_check_channel_name( livetv->recorder, channel ) )
   464     	  	{
   465     		  	if ( gmyth_recorder_set_channel_name( livetv->recorder, channel ) )
   466     		  	{
   467     		  		gmyth_debug( "Channel changed!!! [%s].\n", channel );
   468     		  	}
   469     	  	}
   470 	
   471 		} /* if - changes the channel number */
   472     sleep (4);                  /* FIXME: this is evil (tpm) */
   473   }
   474   
   475   /* DEBUG message */  
   476 	GMythProgramInfo* prog_info = gmyth_recorder_get_current_program_info( livetv->recorder );
   477 	
   478 	if ( NULL == prog_info )
   479 	{
   480 		gmyth_debug( "ProgramInfo is equals to NULL!!!" );
   481 		
   482     gint i;
   483     gchar *channame = NULL;
   484 
   485     gmyth_debug( "Problem getting current proginfo!\n" );
   486 
   487     /*
   488      * mythbackend must not be tuned in to a channel, so keep
   489      * changing channels until we find a valid one, or until
   490      * we decide to give up.
   491      */
   492     for (i=1; i<1000; i++) {
   493 			if ( channame != NULL )
   494 				g_free(channame);
   495       channame = g_strdup_printf( "%d", i );
   496       if (gmyth_recorder_set_channel_name(livetv->recorder, channame) < 0) {
   497       	continue;
   498       }
   499       prog_info = gmyth_recorder_get_next_program_info(livetv->recorder, BROWSE_DIRECTION_UP);
   500       if (prog_info != NULL)
   501       	break;
   502     }
   503 
   504 	} /* if - Program Info */
   505 	
   506 	/* prints program info data text */ 
   507 #ifdef GMYTH_USE_DEBUG	
   508 	gmyth_debug( "New ProgramInfo...\n" );
   509 	gmyth_program_info_print( prog_info );
   510 #endif	
   511 
   512 	/* check if the program chain could be obtained from the MythTV protocol message */
   513 	if ( prog_info != NULL )
   514 	{
   515 #ifdef GMYTH_USE_DEBUG
   516 		gmyth_debug( "Program Info: %s\n", gmyth_program_info_to_string( prog_info ) );
   517 #endif
   518 		livetv->proginfo = prog_info;
   519 		/* testing change channel */
   520 		//gmyth_recorder_spawntv_no_tvchain( livetv->recorder );
   521 	} else {
   522 		
   523 		/* check for the program info in the TV program chain could be obtained 
   524 		   from the MythTV MySQL database */
   525 
   526 		/* Reload all TV chain from Mysql database. */
   527 		gmyth_tvchain_reload_all (livetv->tvchain);
   528 	
   529 		if ( livetv->tvchain == NULL ) {
   530 			res = FALSE;
   531 			goto error;
   532 		}
   533 		
   534 		/* Get program info from database using chanid and starttime */
   535 		livetv->proginfo = gmyth_tvchain_get_program_at (livetv->tvchain, tvchain_curr_index++ );
   536 		if ( livetv->proginfo == NULL ) {
   537 			gmyth_debug ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
   538 			res = FALSE;
   539 			goto error;
   540 		} else {
   541 			res = TRUE;
   542 			gmyth_debug ("GMythLiveTV: All requests to backend to start TV were OK. [%s]\n", livetv->proginfo->pathname->str );
   543 		}
   544 		
   545 	}
   546 	
   547 	livetv->uri = (GMythURI*)gmyth_backend_info_get_uri( livetv->backend_info );
   548 	
   549 	g_mutex_unlock( livetv->mutex );
   550 
   551 	if ( !gmyth_livetv_monitor_handler_start( livetv ) )
   552 	{
   553 		res = FALSE;
   554 		gmyth_debug( "LiveTV MONITOR handler error on setup!" );
   555 		goto error;		
   556 	}
   557 	
   558 	livetv->setup_done = TRUE;
   559 	
   560 	return res;
   561 
   562 error:
   563 	gmyth_debug( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ );
   564 
   565     res = FALSE;
   566 
   567     g_string_free( livetv->local_hostname, TRUE );
   568 
   569 	if ( livetv->recorder != NULL ) {
   570 		g_object_unref (livetv->recorder);
   571 		livetv->recorder = NULL;
   572 	}
   573 
   574 	if ( livetv->tvchain != NULL ) {
   575 		g_object_unref (livetv->tvchain);
   576 		livetv->tvchain = NULL;
   577 	}
   578 
   579 	if ( livetv->proginfo != NULL ) {
   580 		g_object_unref (livetv->proginfo);
   581 		livetv->proginfo = NULL;
   582 	}
   583 
   584 	if ( livetv->monitor != NULL ) {
   585 		g_object_unref (livetv->monitor);
   586 		livetv->monitor = NULL;
   587 	}
   588 
   589 	return res;
   590 
   591 }
   592 
   593 /**
   594  * Setup the GMythLiveTV session, sends SPAWN_LIVETV message, 
   595  * sets the channel name, and gets the first program info about the
   596  * actual recording 
   597  * 
   598  * @param live_tv the GMythLiveTV instance
   599  * @param channel the channel name, in numerical format
   600  * @param backend_info the GMythBackendInfo describing the remote server
   601  * 
   602  * @return <code>true</code> if the LiveTV's recorder instance configuration 
   603  * 				had been concluded succcesfully 
   604  */
   605 static gboolean
   606 gmyth_livetv_setup_recorder ( GMythLiveTV *livetv, gint channel)
   607 {
   608 	return gmyth_livetv_setup_recorder_channel_name ( livetv, ( channel != -1 ) ? 
   609 				g_strdup_printf( "%d", channel ) : NULL );
   610 }
   611 
   612 /**
   613  * Setup the GMythLiveTV session, sends SPAWN_LIVETV message, 
   614  * sets the channel name (numerical format), and gets the first program info about the
   615  * actual recording 
   616  * 
   617  * @param live_tv the GMythLiveTV instance
   618  * @param channel the channel name, in numerical format
   619  * @param backend_info the GMythBackendInfo describing the remote server
   620  * 
   621  * @return <code>true</code> if the LiveTV's recorder instance configuration 
   622  * 				had been concluded succcesfully 
   623  */
   624 gboolean
   625 gmyth_livetv_channel_setup ( GMythLiveTV *livetv, gint channel )
   626 {
   627 	return gmyth_livetv_setup_recorder ( livetv, channel );
   628 }
   629 
   630 /**
   631  * Setup the GMythLiveTV session, sends SPAWN_LIVETV message, 
   632  * sets the channel name (string format), and gets the first program info about the
   633  * actual recording 
   634  * 
   635  * @param live_tv the GMythLiveTV instance
   636  * @param channel the channel name, in numerical format
   637  * @param backend_info the GMythBackendInfo describing the remote server
   638  * 
   639  * @return <code>true</code> if the LiveTV's recorder instance configuration 
   640  * 				had been concluded succcesfully 
   641  */
   642 gboolean
   643 gmyth_livetv_channel_name_setup ( GMythLiveTV *livetv, gchar* channel )
   644 {
   645 	return gmyth_livetv_setup_recorder_channel_name ( livetv, channel );
   646 }
   647 
   648 /**
   649  * Setup the GMythLiveTV session, sends SPAWN_LIVETV message, 
   650  * and gets the first program info about the actual recording
   651  * (doesn't changes the channel). 
   652  * 
   653  * @param live_tv the GMythLiveTV instance
   654  * @param backend_info the GMythBackendInfo describing the remote server
   655  * 
   656  * @return <code>true</code> if the LiveTV's recorder instance configuration 
   657  * 				had been concluded succcesfully 
   658  */
   659 gboolean
   660 gmyth_livetv_setup ( GMythLiveTV *livetv )
   661 {
   662 	return gmyth_livetv_setup_recorder ( livetv, -1 );
   663 }
   664 
   665 /**
   666  * Gets the next program info from this GMythLiveTV session.
   667  * 
   668  * @param live_tv the GMythLiveTV instance
   669  * 
   670  * @return <code>true</code> if the next program info could be got 
   671  */
   672 gboolean
   673 gmyth_livetv_next_program_chain ( GMythLiveTV *livetv )
   674 {
   675 	gboolean res = TRUE;
   676 	GMythProgramInfo *prog_info = NULL;
   677 	
   678 	if ( !livetv->setup_done )
   679 	{
   680 		gmyth_debug ( "Call the setup function first!" );
   681 		goto error;		
   682 	}
   683 	
   684 	gmyth_debug( "Current ProgramInfo...\n" );
   685 	prog_info = gmyth_recorder_get_current_program_info( livetv->recorder );
   686 	
   687 	if ( prog_info != NULL )
   688 	{
   689 		livetv->proginfo = prog_info;
   690 	} else {
   691 		gmyth_debug( "ProgramInfo equals to NULL!!! Getting the next program info..." );
   692 		prog_info = gmyth_recorder_get_next_program_info( livetv->recorder, BROWSE_DIRECTION_RIGHT );
   693 		livetv->proginfo = prog_info;		
   694 	}
   695 	/* prints program info data text */ 
   696 #ifdef GMYTH_USE_DEBUG
   697 	gmyth_program_info_print( prog_info );
   698 #endif
   699 
   700 	if ( prog_info != NULL ) {		
   701 		res = TRUE;
   702 		livetv->proginfo = prog_info;
   703 		gmyth_debug ("GMythLiveTV: All requests to backend to start TV were OK, program info changed.");
   704 	} else {
   705 		gmyth_debug ("[%s] LiveTV not successfully started on the next program chain.\n", __FUNCTION__ );
   706 		goto error;
   707 	}
   708 	
   709 	livetv->setup_done = TRUE;
   710 
   711 	return res;
   712 
   713 error:
   714 	gmyth_debug( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ );
   715 
   716     res = FALSE;
   717     
   718     g_string_free( livetv->local_hostname, TRUE );
   719 
   720 	if ( livetv->recorder != NULL ) {
   721 		g_object_unref (livetv->recorder);
   722 		livetv->recorder = NULL;
   723 	}
   724 
   725 	if ( livetv->tvchain != NULL ) {
   726 		g_object_unref (livetv->tvchain);
   727 		livetv->tvchain = NULL;
   728 	}
   729 
   730 	if ( livetv->proginfo != NULL ) {
   731 		g_object_unref (livetv->proginfo);
   732 		livetv->proginfo = NULL;
   733 	}
   734 
   735 	return res;
   736 }
   737 
   738 /**
   739  * Creates a File Transfer session, using all configuration information
   740  * got from the actual program info.
   741  * 
   742  * @param live_tv the GMythLiveTV instance
   743  * 
   744  * @return the actual GMythFileTransfer instance, generated using the
   745  * 		data got from the actual program info.
   746  */
   747 GMythFileTransfer *
   748 gmyth_livetv_create_file_transfer( GMythLiveTV *livetv )
   749 {
   750 	//GMythURI* uri = NULL;
   751 	
   752 	if ( NULL == livetv )
   753 		goto done;
   754 	
   755 	if ( !livetv->setup_done )
   756 	{
   757 		gmyth_debug( "Error: You must do the LiveTV setup, just before generating the FileTransfer from LiveTV source!" );
   758 		goto done;
   759 	}
   760 	
   761 #ifdef GMYTH_USE_DEBUG
   762 	if ( livetv->proginfo != NULL )
   763   	gmyth_debug( "URI path (from program info) = %s.\n", livetv->proginfo->pathname->str );
   764   else
   765   	gmyth_debug( "URI path (from URI) = %s.\n", livetv->uri->uri->str );
   766 #endif
   767   
   768   g_mutex_lock( livetv->mutex );
   769   
   770   if ( livetv->file_transfer != NULL )
   771   {
   772   	/*gmyth_file_transfer_close( livetv->file_transfer );*/
   773   	g_object_unref( livetv->file_transfer );
   774   	livetv->file_transfer = NULL;
   775   }  	
   776 
   777   if ( livetv->uri != NULL )  
   778   {
   779   	/* 
   780   	if ( livetv->uri->path != NULL )
   781   	{
   782   		g_string_free( livetv->uri->path, FALSE );
   783   		livetv->uri->path = NULL;
   784   	}
   785   	*/
   786 #ifdef GMYTH_USE_DEBUG
   787   	gmyth_debug( "URI is not NULL, creating from the ProgramInfo pathname... (%s)", livetv->proginfo->pathname->str );
   788 #endif
   789   	livetv->uri->path = g_string_erase(livetv->uri->path, 0, -1);
   790   	livetv->uri->path = g_string_new( g_strrstr( livetv->proginfo->pathname->str, "/" ) );
   791   } else {
   792 #ifdef GMYTH_USE_DEBUG
   793   	gmyth_debug( "URI is NULL, creating from the ProgramInfo pathname... (%s)", livetv->proginfo->pathname->str );
   794 #endif
   795   	livetv->uri = gmyth_uri_new_with_value( livetv->proginfo->pathname->str );
   796   }
   797   	
   798   if ( NULL == livetv->uri )
   799   {  	
   800   	gmyth_debug( "Couldn't parse the URI to start LiveTV! [ uri = %s ]", livetv->proginfo->pathname->str );
   801   	goto done;  	
   802   }
   803  
   804 	livetv->file_transfer = gmyth_file_transfer_new( livetv->backend_info );
   805 
   806   if ( NULL == livetv->file_transfer ) 
   807   {
   808   	gmyth_debug( "Error: couldn't create the FileTransfer from LiveTV source!" );
   809     goto done;
   810   }
   811   
   812     g_object_ref( livetv->file_transfer );
   813 
   814   /* gmyth_file_transfer_settimeout( livetv->file_transfer, TRUE ); */
   815 	
   816   g_mutex_unlock( livetv->mutex );
   817 
   818 done:
   819 	/*
   820 	if ( uri != NULL )
   821 	{
   822 		g_object_unref( uri );
   823 		uri = NULL;
   824 	}
   825 	*/	
   826 	
   827 	return livetv->file_transfer;
   828 	
   829 }
   830 
   831 /**
   832  * Stops this LiveTV session.
   833  * 
   834  * @param live_tv the GMythLiveTV instance
   835  */
   836 void
   837 gmyth_livetv_stop_playing (GMythLiveTV *livetv) 
   838 {
   839 	gmyth_debug ("Stopping the LiveTV...\n");
   840 
   841 	if (livetv->is_livetv) {
   842 		if ( !gmyth_recorder_stop_livetv (livetv->recorder) ) {
   843 			gmyth_debug ("[%s] Error while stoping remote encoder", __FUNCTION__);	
   844 		}
   845 		
   846 		if ( !gmyth_recorder_finish_recording(livetv->recorder) ) {
   847 			gmyth_debug ("[%s] Error while finishing recording on remote encoder", __FUNCTION__);	
   848 		}
   849 	}
   850 }
   851 
   852 gboolean
   853 gmyth_livetv_is_playing (GMythLiveTV *livetv)
   854 {
   855 	return TRUE;
   856 }
   857 
   858 void
   859 gmyth_livetv_start_playing (GMythLiveTV *livetv)
   860 {
   861 
   862 	// TODO
   863 
   864 }
   865