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