branches/gmyth-0.1b/src/gmyth_livetv.c
author rosfran
Fri Feb 09 20:42:28 2007 +0000 (2007-02-09)
branchtrunk
changeset 346 4ba962630375
permissions -rwxr-xr-x
[svn r348] Fixes.
     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 		return FALSE;
   385 	}
   386 	/* prints program info data text */ 
   387 	gmyth_debug( "New ProgramInfo...\n" );
   388 	gmyth_program_info_print( prog_info );
   389 	/* DEBUG message */
   390 	gmyth_debug( "Old ProgramInfo...\n" );
   391 	gmyth_program_info_print( livetv->proginfo );
   392 	
   393 	/* check if the program chain could be obtained from the MythTV protocol message */
   394 	if ( prog_info != NULL )
   395 	{
   396 		livetv->proginfo = prog_info;
   397 		/* testing change channel */
   398 		//gmyth_recorder_spawntv_no_tvchain( livetv->recorder );
   399 	} else {
   400 		
   401 		/* check for the program info in the TV program chain could be obtained 
   402 		   from the MythTV MySQL database */
   403 
   404 		/* Reload all TV chain from Mysql database. */
   405 		gmyth_tvchain_reload_all (livetv->tvchain);
   406 	
   407 		if ( livetv->tvchain == NULL ) {
   408 			res = FALSE;
   409 			goto error;
   410 		}
   411 		
   412 		/* Get program info from database using chanid and starttime */
   413 		livetv->proginfo = gmyth_tvchain_get_program_at (livetv->tvchain, tvchain_curr_index++ );
   414 		if ( livetv->proginfo == NULL ) {
   415 			g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
   416 			res = FALSE;
   417 			goto error;
   418 		} else {
   419 			res = TRUE;
   420 			gmyth_debug ("GMythLiveTV: All requests to backend to start TV were OK. [%s]\n", livetv->proginfo->pathname->str );
   421 		}
   422 		
   423 	}
   424 	
   425 	livetv->uri = (GMythURI*)gmyth_backend_info_get_uri( backend_info );
   426 	
   427 	g_static_mutex_unlock( &lock );
   428 
   429 	if ( !gmyth_livetv_monitor_handler_start( livetv ) )
   430 	{
   431 		res = FALSE;
   432 		gmyth_debug( "LiveTV MONITOR handler error on setup!" );
   433 		goto error;		
   434 	}
   435 	
   436 	livetv->setup_done = TRUE;
   437 	
   438 	return res;
   439 
   440 error:
   441 	g_print( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ );
   442 
   443 	if ( livetv->local_hostname != NULL ) {
   444 		g_string_free( livetv->local_hostname, FALSE );
   445 		res = FALSE;
   446 	}
   447 
   448 	if ( livetv->recorder != NULL ) {
   449 		g_object_unref (livetv->recorder);
   450 		livetv->recorder = NULL;
   451 	}
   452 
   453 	if ( livetv->tvchain != NULL ) {
   454 		g_object_unref (livetv->tvchain);
   455 		livetv->tvchain = NULL;
   456 	}
   457 
   458 	if ( livetv->proginfo != NULL ) {
   459 		g_object_unref (livetv->proginfo);
   460 		livetv->proginfo = NULL;
   461 	}
   462 
   463 	if ( livetv->monitor != NULL ) {
   464 		g_object_unref (livetv->monitor);
   465 		livetv->monitor = NULL;
   466 	}
   467 
   468 	return res;
   469 
   470 }
   471 
   472 static gboolean
   473 gmyth_livetv_setup_recorder ( GMythLiveTV *livetv, gint channel, GMythBackendInfo *backend_info )
   474 {
   475 	return gmyth_livetv_setup_recorder_channel_name ( livetv, ( channel != -1 ) ? 
   476 				g_strdup_printf( "%d", channel ) : NULL, backend_info );
   477 }
   478 
   479 gboolean
   480 gmyth_livetv_channel_setup ( GMythLiveTV *livetv, gint channel, GMythBackendInfo *backend_info )
   481 {
   482 	return gmyth_livetv_setup_recorder ( livetv, channel, backend_info );
   483 }
   484 
   485 gboolean
   486 gmyth_livetv_channel_name_setup ( GMythLiveTV *livetv, gchar* channel, GMythBackendInfo *backend_info )
   487 {
   488 	return gmyth_livetv_setup_recorder_channel_name ( livetv, channel, backend_info );
   489 }
   490 
   491 gboolean
   492 gmyth_livetv_setup ( GMythLiveTV *livetv, GMythBackendInfo *backend_info )
   493 {
   494 	return gmyth_livetv_setup_recorder ( livetv, -1, backend_info );
   495 }
   496 
   497 gboolean
   498 gmyth_livetv_next_program_chain ( GMythLiveTV *livetv )
   499 {
   500 	gboolean res = TRUE;
   501 	GMythProgramInfo *prog_info = NULL;
   502 	
   503 	if ( !livetv->setup_done )
   504 	{
   505 		gmyth_debug ( "Call the setup function first!" );
   506 		res= FALSE;
   507 		goto error;		
   508 	}
   509 	
   510 	//if ( !gmyth_livetv_monitor_handler_start( livetv ) )
   511 	//	goto error;
   512 	prog_info = gmyth_recorder_get_current_program_info( livetv->recorder );
   513 	
   514 	if ( NULL == prog_info )
   515 	{
   516 		gmyth_debug( "ProgramInfo is equals to NULL!!!" );
   517 		
   518 		return FALSE;
   519 	}
   520 	/* prints program info data text */ 
   521 	gmyth_program_info_print( prog_info );
   522 
   523 	if ( prog_info != NULL ) {		
   524 		res = TRUE;
   525 		livetv->proginfo = prog_info;
   526 		gmyth_debug ("GMythLiveTV: All requests to backend to start TV were OK, program info changed.");
   527 	} else {
   528 		g_warning ("[%s] LiveTV not successfully started on the next program chain.\n", __FUNCTION__ );
   529 		res = FALSE;
   530 		goto error;
   531 	}
   532 	
   533 	livetv->setup_done = TRUE;
   534 
   535 	return res;
   536 
   537 error:
   538 	g_print( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ );
   539 
   540 	if ( livetv->local_hostname != NULL ) {
   541 		g_string_free( livetv->local_hostname, FALSE );
   542 		res = FALSE;
   543 	}
   544 
   545 	if ( livetv->recorder != NULL ) {
   546 		g_object_unref (livetv->recorder);
   547 		livetv->recorder = NULL;
   548 	}
   549 
   550 	if ( livetv->tvchain != NULL ) {
   551 		g_object_unref (livetv->tvchain);
   552 		livetv->tvchain = NULL;
   553 	}
   554 
   555 	if ( livetv->proginfo != NULL ) {
   556 		g_object_unref (livetv->proginfo);
   557 		livetv->proginfo = NULL;
   558 	}
   559 
   560 	return res;
   561 
   562 }
   563 
   564 GMythFileTransfer *
   565 gmyth_livetv_create_file_transfer( GMythLiveTV *livetv )
   566 {
   567 	//GMythURI* uri = NULL;
   568 	
   569 	if ( NULL == livetv )
   570 		goto done;
   571 	
   572 	if ( !livetv->setup_done )
   573 	{
   574 		gmyth_debug( "Error: You must do the LiveTV setup, just before generating the FileTransfer from LiveTV source!" );
   575 		goto done;
   576 	}
   577 	
   578 	if ( livetv->proginfo != NULL )
   579   	gmyth_debug( "URI path = %s.\n", livetv->proginfo->pathname->str );
   580   else
   581   	gmyth_debug( "URI path = %s.\n", livetv->uri->uri->str ); 
   582   
   583   g_static_mutex_lock( &lock );
   584   
   585   if ( livetv->file_transfer != NULL )
   586   {
   587   	/*gmyth_file_transfer_close( livetv->file_transfer );*/
   588   	g_object_unref( livetv->file_transfer );
   589   	livetv->file_transfer = NULL;
   590   }  	
   591 
   592 	livetv->file_transfer = gmyth_file_transfer_new( livetv->backend_info );
   593 
   594   if ( NULL == livetv->file_transfer ) 
   595   {
   596   	gmyth_debug( "Error: couldn't create the FileTransfer from LiveTV source!" );
   597     goto done;
   598   }
   599   
   600   if ( livetv->uri != NULL )  
   601   { 
   602   	if ( livetv->uri->path != NULL )
   603   	{
   604   		g_string_free( livetv->uri->path, FALSE );
   605   		livetv->uri->path = NULL;
   606   	}
   607   	livetv->uri->path = g_string_new( g_strrstr( livetv->proginfo->pathname->str, "/" ) );
   608   } else {
   609   	livetv->uri = gmyth_uri_new_with_value( livetv->proginfo->pathname->str );
   610   }
   611   	
   612   if ( NULL == livetv->uri )
   613   {  	
   614   	gmyth_debug( "Couldn't parse the URI to start LiveTV! [ uri = %s ]", livetv->proginfo->pathname->str );
   615   	goto done;  	
   616   }
   617 
   618 	if ( !gmyth_file_transfer_open( livetv->file_transfer, livetv->uri != NULL ? gmyth_uri_get_path(livetv->uri) : 
   619 				livetv->proginfo->pathname->str ) )
   620 	{
   621 		gmyth_debug( "Error: couldn't open the FileTransfer from LiveTV source!" );
   622 		g_object_unref( livetv->file_transfer );
   623 		livetv->file_transfer = NULL;
   624 		goto done;
   625 	}
   626 	
   627 	g_static_mutex_unlock( &lock );
   628 
   629 done:
   630 	/*
   631 	if ( uri != NULL )
   632 	{
   633 		g_object_unref( uri );
   634 		uri = NULL;
   635 	}
   636 	*/	
   637 	
   638 	return livetv->file_transfer;
   639 	
   640 }
   641 
   642 /* FIXME: How to proceed differently between livetv and recorded content */
   643 void
   644 gmyth_livetv_stop_playing (GMythLiveTV *livetv) 
   645 {
   646 	gmyth_debug ("Stopping the LiveTV...\n");
   647 
   648 	if (livetv->is_livetv) {
   649 		if ( !gmyth_recorder_stop_livetv (livetv->recorder) ) {
   650 			g_warning ("[%s] Error while stoping remote encoder", __FUNCTION__);	
   651 		}
   652 	}
   653 }
   654 
   655 gboolean
   656 gmyth_livetv_is_playing (GMythLiveTV *livetv)
   657 {
   658 	return TRUE;
   659 }
   660 
   661 void
   662 gmyth_livetv_start_playing (GMythLiveTV *livetv)
   663 {
   664 
   665 	// TODO
   666 
   667 }
   668