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