1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/branches/gmyth-0.1b/src/gmyth_livetv.c Tue Feb 13 23:17:35 2007 +0000
1.3 @@ -0,0 +1,668 @@
1.4 +/**
1.5 + * GMyth Library
1.6 + *
1.7 + * @file gmyth/gmyth_livetv.c
1.8 + *
1.9 + * @brief <p> GMythLiveTV starts a remote TV session with the MythTV backend.
1.10 + *
1.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
1.12 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
1.13 + *
1.14 + *//*
1.15 + *
1.16 + * This program is free software; you can redistribute it and/or modify
1.17 + * it under the terms of the GNU Lesser General Public License as published by
1.18 + * the Free Software Foundation; either version 2 of the License, or
1.19 + * (at your option) any later version.
1.20 + *
1.21 + * This program is distributed in the hope that it will be useful,
1.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.24 + * GNU General Public License for more details.
1.25 + *
1.26 + * You should have received a copy of the GNU Lesser General Public License
1.27 + * along with this program; if not, write to the Free Software
1.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1.29 + */
1.30 +
1.31 +#ifdef HAVE_CONFIG_H
1.32 +#include "config.h"
1.33 +#endif
1.34 +
1.35 +#include "gmyth_livetv.h"
1.36 +#include "gmyth_remote_util.h"
1.37 +#include "gmyth_tvchain.h"
1.38 +#include "gmyth_socket.h"
1.39 +#include "gmyth_backendinfo.h"
1.40 +#include "gmyth_debug.h"
1.41 +
1.42 +#include "gmyth_file_transfer.h"
1.43 +#include "gmyth_monitor_handler.h"
1.44 +
1.45 +static void gmyth_livetv_class_init (GMythLiveTVClass *klass);
1.46 +static void gmyth_livetv_init (GMythLiveTV *object);
1.47 +
1.48 +static void gmyth_livetv_dispose (GObject *object);
1.49 +static void gmyth_livetv_finalize (GObject *object);
1.50 +
1.51 +static gint tvchain_curr_index = -1;
1.52 +
1.53 +static GStaticMutex lock = G_STATIC_MUTEX_INIT;
1.54 +
1.55 +#define GMYTHTV_TRANSFER_MAX_WAITS 100
1.56 +
1.57 +G_DEFINE_TYPE(GMythLiveTV, gmyth_livetv, G_TYPE_OBJECT)
1.58 +
1.59 +static void
1.60 +gmyth_livetv_class_init (GMythLiveTVClass *klass)
1.61 +{
1.62 + GObjectClass *gobject_class;
1.63 +
1.64 + gobject_class = (GObjectClass *) klass;
1.65 +
1.66 + gobject_class->dispose = gmyth_livetv_dispose;
1.67 + gobject_class->finalize = gmyth_livetv_finalize;
1.68 +}
1.69 +
1.70 +static void
1.71 +gmyth_livetv_init (GMythLiveTV *livetv)
1.72 +{
1.73 + livetv->backend_info = NULL;
1.74 + livetv->local_hostname = NULL;
1.75 + livetv->file_transfer = NULL;
1.76 + livetv->setup_done = FALSE;
1.77 +
1.78 + livetv->recorder = NULL;
1.79 + livetv->tvchain = NULL;
1.80 + livetv->proginfo = NULL;
1.81 + livetv->uri = NULL;
1.82 +
1.83 +}
1.84 +
1.85 +static void
1.86 +gmyth_livetv_dispose (GObject *object)
1.87 +{
1.88 + G_OBJECT_CLASS (gmyth_livetv_parent_class)->dispose (object);
1.89 +}
1.90 +
1.91 +static void
1.92 +gmyth_livetv_finalize (GObject *object)
1.93 +{
1.94 + g_signal_handlers_destroy (object);
1.95 +
1.96 + GMythLiveTV *livetv = GMYTH_LIVETV (object);
1.97 +
1.98 + gmyth_debug ("Finalizing livetv");
1.99 +
1.100 + if ( livetv->monitor != NULL ) {
1.101 + g_object_unref (livetv->monitor);
1.102 + livetv->monitor = NULL;
1.103 + }
1.104 +
1.105 + if ( livetv->recorder != NULL ) {
1.106 + g_object_unref (livetv->recorder);
1.107 + livetv->recorder = NULL;
1.108 + }
1.109 +
1.110 + if ( livetv->tvchain != NULL ) {
1.111 + g_object_unref (livetv->tvchain);
1.112 + livetv->tvchain = NULL;
1.113 + }
1.114 +
1.115 + if ( livetv->proginfo != NULL ) {
1.116 + g_object_unref (livetv->proginfo);
1.117 + livetv->proginfo = NULL;
1.118 + }
1.119 +
1.120 + if ( livetv->file_transfer != NULL ) {
1.121 + g_object_unref (livetv->file_transfer);
1.122 + livetv->file_transfer = NULL;
1.123 + }
1.124 +
1.125 + if ( livetv->backend_info != NULL ) {
1.126 + g_object_unref (livetv->backend_info);
1.127 + livetv->backend_info = NULL;
1.128 + }
1.129 +
1.130 + if ( livetv->uri != NULL )
1.131 + {
1.132 + g_object_unref (livetv->uri);
1.133 + livetv->uri = NULL;
1.134 + }
1.135 +
1.136 + G_OBJECT_CLASS ( gmyth_livetv_parent_class )->finalize ( object );
1.137 +}
1.138 +
1.139 +GMythLiveTV*
1.140 +gmyth_livetv_new ()
1.141 +{
1.142 + GMythLiveTV *livetv = GMYTH_LIVETV ( g_object_new( GMYTH_LIVETV_TYPE, NULL ) );
1.143 +
1.144 + return livetv;
1.145 +}
1.146 +
1.147 +static void
1.148 +gmyth_livetv_monitor_signal_handler( GMythMonitorHandler *monitor, gint msg_code,
1.149 + gchar* message, gpointer user_data )
1.150 +{
1.151 + GMythLiveTV *live_tv = GMYTH_LIVETV ( user_data );
1.152 + //g_object_ref( live_tv );
1.153 +
1.154 + gmyth_debug( "LIVETV Signal handler ( msg = %s, code = %d, live_tv param = %s, user_data = %s )\n", message, msg_code, live_tv != NULL ? "" :
1.155 + "NULL", user_data != NULL ? "" : "NULL" );
1.156 +
1.157 + if ( NULL == live_tv )
1.158 + {
1.159 + gmyth_debug( "LiveTV_obj is equals to NULL!!!" );
1.160 + return;
1.161 + }
1.162 +
1.163 + switch ( msg_code )
1.164 + {
1.165 +
1.166 + case GMYTH_BACKEND_PROGRAM_INFO_CHANGED:
1.167 + {
1.168 + gmyth_debug( "LIVETV Program Changed request received [ msg = %s ]. Watching if the new "\
1.169 + "TV Chain ID is the same as the old one...\n", message );
1.170 + if ( g_ascii_strcasecmp ( message, (gmyth_tvchain_get_id( live_tv->tvchain ))->str ) != 0 ) {
1.171 + gmyth_debug( "OK!!! MOVED to the next program chain [actual == %s]!",
1.172 + (gmyth_tvchain_get_id( live_tv->tvchain ))->str );
1.173 + /* advertises the FileTransfer about the program info changed */
1.174 + if ( live_tv->file_transfer != NULL )
1.175 + {
1.176 + gmyth_debug( "Emitting signal to the FileTransfer... [ \"program-info-changed \" ]" );
1.177 +
1.178 + gmyth_file_transfer_emit_program_info_changed_signal( live_tv->file_transfer,
1.179 + msg_code, (gpointer)live_tv );
1.180 +
1.181 + //gmyth_livetv_monitor_handler_stop( live_tv );
1.182 + } else
1.183 + gmyth_debug( "LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");
1.184 + }
1.185 + }
1.186 + case GMYTH_BACKEND_DONE_RECORDING:
1.187 + {
1.188 + gmyth_debug( "LIVETV Program Changed request received [ msg = %s ]. Watching if the new "\
1.189 + "TV Chain ID is the same as the old one...\n", message );
1.190 + if ( g_ascii_strcasecmp ( message, (gmyth_tvchain_get_id( live_tv->tvchain ))->str ) != 0 ) {
1.191 + gmyth_debug( "OK!!! MOVED to the next program chain [actual == %s]!",
1.192 + (gmyth_tvchain_get_id( live_tv->tvchain ))->str );
1.193 + /* advertises the FileTransfer about the program info changed */
1.194 + if ( live_tv->file_transfer != NULL )
1.195 + {
1.196 + gmyth_debug( "Emitting signal to the FileTransfer... [ \"program-info-changed \" ]" );
1.197 +
1.198 + gmyth_file_transfer_emit_program_info_changed_signal( live_tv->file_transfer,
1.199 + msg_code, (gpointer)live_tv );
1.200 +
1.201 + //gmyth_livetv_monitor_handler_stop( live_tv );
1.202 + } else
1.203 + gmyth_debug( "LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");
1.204 + }
1.205 +
1.206 + break;
1.207 + }
1.208 + default:
1.209 + break;
1.210 + } /* switch (Monitor Handler messages) */
1.211 +
1.212 +}
1.213 +
1.214 +gboolean
1.215 +gmyth_livetv_monitor_handler_start( GMythLiveTV *livetv )
1.216 +{
1.217 + gboolean res = TRUE;
1.218 +
1.219 + if ( livetv->monitor != NULL )
1.220 + {
1.221 + g_object_unref( livetv->monitor );
1.222 + livetv->monitor = NULL;
1.223 + }
1.224 +
1.225 + livetv->monitor = gmyth_monitor_handler_new ( );
1.226 +
1.227 + res = gmyth_monitor_handler_open (livetv->monitor, livetv->backend_info->hostname,
1.228 + livetv->backend_info->port );
1.229 +
1.230 + if ( res == TRUE )
1.231 + {
1.232 + gmyth_debug("Connect MythTV Monitor event socket! Trying to start the message handler...");
1.233 +
1.234 + res = gmyth_monitor_handler_start ( livetv->monitor );
1.235 +
1.236 + if (res)
1.237 + {
1.238 + gmyth_debug("MythTV Monitor event socket connected and listening!");
1.239 + g_signal_connect ( G_OBJECT (livetv->monitor), "backend-events-handler",
1.240 + (GCallback)gmyth_livetv_monitor_signal_handler,
1.241 + livetv );
1.242 + }
1.243 + else
1.244 + {
1.245 + gmyth_debug("Problems when trying to start MythTV Monitor event socket!");
1.246 + goto error;
1.247 + }
1.248 + }
1.249 +
1.250 +error:
1.251 + return res;
1.252 +
1.253 +}
1.254 +
1.255 +void
1.256 +gmyth_livetv_monitor_handler_stop( GMythLiveTV *livetv )
1.257 +{
1.258 +
1.259 + if ( livetv->monitor != NULL )
1.260 + {
1.261 + g_object_unref( livetv->monitor );
1.262 + livetv->monitor = NULL;
1.263 + }
1.264 +
1.265 +}
1.266 +
1.267 +
1.268 +/*
1.269 +static gchar*
1.270 +gmyth_livetv_create_remote_url( GMythLiveTV *livetv )
1.271 +{
1.272 + gchar *uri = g_strdup("");
1.273 + gmyth_backend_info_get_remote_h
1.274 +
1.275 + //gmyth_backend(livetv->backend_info)
1.276 +
1.277 + return uri;
1.278 +}
1.279 +*/
1.280 +
1.281 +static gboolean
1.282 +gmyth_livetv_setup_recorder_channel_name ( GMythLiveTV *livetv, gchar* channel, GMythBackendInfo *backend_info )
1.283 +{
1.284 + gboolean res = TRUE;
1.285 +
1.286 + GMythSocket *socket = gmyth_socket_new ();
1.287 +
1.288 + livetv->backend_info = backend_info;
1.289 +
1.290 + g_static_mutex_lock( &lock );
1.291 +
1.292 + // FIME: Implement this at gmyth_socket
1.293 + res = gmyth_socket_connect_to_backend (socket, livetv->backend_info->hostname,
1.294 + livetv->backend_info->port, TRUE);
1.295 + if (!res) {
1.296 + g_warning ("[%s] LiveTV can not connect to backend", __FUNCTION__);
1.297 + res = FALSE;
1.298 + goto error;
1.299 + }
1.300 +
1.301 + livetv->is_livetv = TRUE;
1.302 +
1.303 + livetv->local_hostname = gmyth_socket_get_local_hostname ();
1.304 +
1.305 + if ( livetv->local_hostname == NULL ) {
1.306 + res = FALSE;
1.307 + goto error;
1.308 + }
1.309 +
1.310 + // Gets the recorder num
1.311 + livetv->recorder = remote_request_next_free_recorder (socket, -1);
1.312 + gmyth_socket_close_connection (socket);
1.313 +
1.314 + if ( livetv->recorder == NULL ) {
1.315 + g_warning ("[%s] None remote encoder available", __FUNCTION__);
1.316 + res = FALSE;
1.317 + goto error;
1.318 + }
1.319 +
1.320 + // Init remote encoder. Opens its control socket.
1.321 + res = gmyth_recorder_setup(livetv->recorder);
1.322 + if ( !res ) {
1.323 + g_warning ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
1.324 + res = FALSE;
1.325 + goto error;
1.326 + }
1.327 +
1.328 + // Creates livetv chain handler
1.329 + livetv->tvchain = GMYTH_TVCHAIN ( g_object_new(GMYTH_TVCHAIN_TYPE, NULL) );
1.330 + gmyth_tvchain_initialize ( livetv->tvchain, livetv->backend_info );
1.331 +
1.332 + if ( livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL ) {
1.333 + res = FALSE;
1.334 + goto error;
1.335 + }
1.336 +
1.337 + // Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
1.338 + res = gmyth_recorder_spawntv ( livetv->recorder,
1.339 + gmyth_tvchain_get_id(livetv->tvchain) );
1.340 + if (!res) {
1.341 + g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__);
1.342 + res = FALSE;
1.343 + goto error;
1.344 + }
1.345 +
1.346 + if ( res == TRUE ) {
1.347 + /* loop finished, set the max tries variable to zero again... */
1.348 + gint wait_to_transfer = 0;
1.349 +
1.350 + while (wait_to_transfer++ < GMYTHTV_TRANSFER_MAX_WAITS &&
1.351 + (gmyth_recorder_is_recording (livetv->recorder) == FALSE))
1.352 + g_usleep (500);
1.353 +
1.354 + /* IS_RECORDING again, just like the MythTV backend does... */
1.355 + gmyth_recorder_is_recording (livetv->recorder);
1.356 +
1.357 + if ( channel != NULL )
1.358 + {
1.359 + /* Pauses remote encoder. */
1.360 + res = gmyth_recorder_pause_recording(livetv->recorder);
1.361 + if ( !res ) {
1.362 + g_warning ("[%s] Fail while pausing remote encoder\n", __FUNCTION__);
1.363 + res = FALSE;
1.364 + goto error;
1.365 + }
1.366 +
1.367 + if ( gmyth_recorder_check_channel_name( livetv->recorder, channel ) )
1.368 + {
1.369 + if ( gmyth_recorder_set_channel_name( livetv->recorder, channel ) )
1.370 + {
1.371 + g_print( "[%s] Channel changed!!! [%s].\n", __FUNCTION__, channel );
1.372 + }
1.373 + }
1.374 +
1.375 + }
1.376 +
1.377 + sleep (9); /* FIXME: this is evil (tpm) */
1.378 + }
1.379 +
1.380 + /* DEBUG message */
1.381 + GMythProgramInfo* prog_info = gmyth_recorder_get_current_program_info( livetv->recorder );
1.382 +
1.383 + if ( NULL == prog_info )
1.384 + {
1.385 + gmyth_debug( "ProgramInfo is equals to NULL!!!" );
1.386 +
1.387 + return FALSE;
1.388 + }
1.389 + /* prints program info data text */
1.390 + gmyth_debug( "New ProgramInfo...\n" );
1.391 + gmyth_program_info_print( prog_info );
1.392 + /* DEBUG message */
1.393 + gmyth_debug( "Old ProgramInfo...\n" );
1.394 + gmyth_program_info_print( livetv->proginfo );
1.395 +
1.396 + /* check if the program chain could be obtained from the MythTV protocol message */
1.397 + if ( prog_info != NULL )
1.398 + {
1.399 + livetv->proginfo = prog_info;
1.400 + /* testing change channel */
1.401 + //gmyth_recorder_spawntv_no_tvchain( livetv->recorder );
1.402 + } else {
1.403 +
1.404 + /* check for the program info in the TV program chain could be obtained
1.405 + from the MythTV MySQL database */
1.406 +
1.407 + /* Reload all TV chain from Mysql database. */
1.408 + gmyth_tvchain_reload_all (livetv->tvchain);
1.409 +
1.410 + if ( livetv->tvchain == NULL ) {
1.411 + res = FALSE;
1.412 + goto error;
1.413 + }
1.414 +
1.415 + /* Get program info from database using chanid and starttime */
1.416 + livetv->proginfo = gmyth_tvchain_get_program_at (livetv->tvchain, tvchain_curr_index++ );
1.417 + if ( livetv->proginfo == NULL ) {
1.418 + g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
1.419 + res = FALSE;
1.420 + goto error;
1.421 + } else {
1.422 + res = TRUE;
1.423 + gmyth_debug ("GMythLiveTV: All requests to backend to start TV were OK. [%s]\n", livetv->proginfo->pathname->str );
1.424 + }
1.425 +
1.426 + }
1.427 +
1.428 + livetv->uri = (GMythURI*)gmyth_backend_info_get_uri( backend_info );
1.429 +
1.430 + g_static_mutex_unlock( &lock );
1.431 +
1.432 + if ( !gmyth_livetv_monitor_handler_start( livetv ) )
1.433 + {
1.434 + res = FALSE;
1.435 + gmyth_debug( "LiveTV MONITOR handler error on setup!" );
1.436 + goto error;
1.437 + }
1.438 +
1.439 + livetv->setup_done = TRUE;
1.440 +
1.441 + return res;
1.442 +
1.443 +error:
1.444 + g_print( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ );
1.445 +
1.446 + if ( livetv->local_hostname != NULL ) {
1.447 + g_string_free( livetv->local_hostname, FALSE );
1.448 + res = FALSE;
1.449 + }
1.450 +
1.451 + if ( livetv->recorder != NULL ) {
1.452 + g_object_unref (livetv->recorder);
1.453 + livetv->recorder = NULL;
1.454 + }
1.455 +
1.456 + if ( livetv->tvchain != NULL ) {
1.457 + g_object_unref (livetv->tvchain);
1.458 + livetv->tvchain = NULL;
1.459 + }
1.460 +
1.461 + if ( livetv->proginfo != NULL ) {
1.462 + g_object_unref (livetv->proginfo);
1.463 + livetv->proginfo = NULL;
1.464 + }
1.465 +
1.466 + if ( livetv->monitor != NULL ) {
1.467 + g_object_unref (livetv->monitor);
1.468 + livetv->monitor = NULL;
1.469 + }
1.470 +
1.471 + return res;
1.472 +
1.473 +}
1.474 +
1.475 +static gboolean
1.476 +gmyth_livetv_setup_recorder ( GMythLiveTV *livetv, gint channel, GMythBackendInfo *backend_info )
1.477 +{
1.478 + return gmyth_livetv_setup_recorder_channel_name ( livetv, ( channel != -1 ) ?
1.479 + g_strdup_printf( "%d", channel ) : NULL, backend_info );
1.480 +}
1.481 +
1.482 +gboolean
1.483 +gmyth_livetv_channel_setup ( GMythLiveTV *livetv, gint channel, GMythBackendInfo *backend_info )
1.484 +{
1.485 + return gmyth_livetv_setup_recorder ( livetv, channel, backend_info );
1.486 +}
1.487 +
1.488 +gboolean
1.489 +gmyth_livetv_channel_name_setup ( GMythLiveTV *livetv, gchar* channel, GMythBackendInfo *backend_info )
1.490 +{
1.491 + return gmyth_livetv_setup_recorder_channel_name ( livetv, channel, backend_info );
1.492 +}
1.493 +
1.494 +gboolean
1.495 +gmyth_livetv_setup ( GMythLiveTV *livetv, GMythBackendInfo *backend_info )
1.496 +{
1.497 + return gmyth_livetv_setup_recorder ( livetv, -1, backend_info );
1.498 +}
1.499 +
1.500 +gboolean
1.501 +gmyth_livetv_next_program_chain ( GMythLiveTV *livetv )
1.502 +{
1.503 + gboolean res = TRUE;
1.504 + GMythProgramInfo *prog_info = NULL;
1.505 +
1.506 + if ( !livetv->setup_done )
1.507 + {
1.508 + gmyth_debug ( "Call the setup function first!" );
1.509 + res= FALSE;
1.510 + goto error;
1.511 + }
1.512 +
1.513 + //if ( !gmyth_livetv_monitor_handler_start( livetv ) )
1.514 + // goto error;
1.515 + prog_info = gmyth_recorder_get_current_program_info( livetv->recorder );
1.516 +
1.517 + if ( NULL == prog_info )
1.518 + {
1.519 + gmyth_debug( "ProgramInfo is equals to NULL!!!" );
1.520 +
1.521 + return FALSE;
1.522 + }
1.523 + /* prints program info data text */
1.524 + gmyth_program_info_print( prog_info );
1.525 +
1.526 + if ( prog_info != NULL ) {
1.527 + res = TRUE;
1.528 + livetv->proginfo = prog_info;
1.529 + gmyth_debug ("GMythLiveTV: All requests to backend to start TV were OK, program info changed.");
1.530 + } else {
1.531 + g_warning ("[%s] LiveTV not successfully started on the next program chain.\n", __FUNCTION__ );
1.532 + res = FALSE;
1.533 + goto error;
1.534 + }
1.535 +
1.536 + livetv->setup_done = TRUE;
1.537 +
1.538 + return res;
1.539 +
1.540 +error:
1.541 + g_print( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ );
1.542 +
1.543 + if ( livetv->local_hostname != NULL ) {
1.544 + g_string_free( livetv->local_hostname, FALSE );
1.545 + res = FALSE;
1.546 + }
1.547 +
1.548 + if ( livetv->recorder != NULL ) {
1.549 + g_object_unref (livetv->recorder);
1.550 + livetv->recorder = NULL;
1.551 + }
1.552 +
1.553 + if ( livetv->tvchain != NULL ) {
1.554 + g_object_unref (livetv->tvchain);
1.555 + livetv->tvchain = NULL;
1.556 + }
1.557 +
1.558 + if ( livetv->proginfo != NULL ) {
1.559 + g_object_unref (livetv->proginfo);
1.560 + livetv->proginfo = NULL;
1.561 + }
1.562 +
1.563 + return res;
1.564 +
1.565 +}
1.566 +
1.567 +GMythFileTransfer *
1.568 +gmyth_livetv_create_file_transfer( GMythLiveTV *livetv )
1.569 +{
1.570 + //GMythURI* uri = NULL;
1.571 +
1.572 + if ( NULL == livetv )
1.573 + goto done;
1.574 +
1.575 + if ( !livetv->setup_done )
1.576 + {
1.577 + gmyth_debug( "Error: You must do the LiveTV setup, just before generating the FileTransfer from LiveTV source!" );
1.578 + goto done;
1.579 + }
1.580 +
1.581 + if ( livetv->proginfo != NULL )
1.582 + gmyth_debug( "URI path = %s.\n", livetv->proginfo->pathname->str );
1.583 + else
1.584 + gmyth_debug( "URI path = %s.\n", livetv->uri->uri->str );
1.585 +
1.586 + g_static_mutex_lock( &lock );
1.587 +
1.588 + if ( livetv->file_transfer != NULL )
1.589 + {
1.590 + /*gmyth_file_transfer_close( livetv->file_transfer );*/
1.591 + g_object_unref( livetv->file_transfer );
1.592 + livetv->file_transfer = NULL;
1.593 + }
1.594 +
1.595 + livetv->file_transfer = gmyth_file_transfer_new( livetv->backend_info );
1.596 +
1.597 + if ( NULL == livetv->file_transfer )
1.598 + {
1.599 + gmyth_debug( "Error: couldn't create the FileTransfer from LiveTV source!" );
1.600 + goto done;
1.601 + }
1.602 +
1.603 + if ( livetv->uri != NULL )
1.604 + {
1.605 + if ( livetv->uri->path != NULL )
1.606 + {
1.607 + g_string_free( livetv->uri->path, FALSE );
1.608 + livetv->uri->path = NULL;
1.609 + }
1.610 + livetv->uri->path = g_string_new( g_strrstr( livetv->proginfo->pathname->str, "/" ) );
1.611 + } else {
1.612 + livetv->uri = gmyth_uri_new_with_value( livetv->proginfo->pathname->str );
1.613 + }
1.614 +
1.615 + if ( NULL == livetv->uri )
1.616 + {
1.617 + gmyth_debug( "Couldn't parse the URI to start LiveTV! [ uri = %s ]", livetv->proginfo->pathname->str );
1.618 + goto done;
1.619 + }
1.620 +
1.621 + if ( !gmyth_file_transfer_open( livetv->file_transfer, livetv->uri != NULL ? gmyth_uri_get_path(livetv->uri) :
1.622 + livetv->proginfo->pathname->str ) )
1.623 + {
1.624 + gmyth_debug( "Error: couldn't open the FileTransfer from LiveTV source!" );
1.625 + g_object_unref( livetv->file_transfer );
1.626 + livetv->file_transfer = NULL;
1.627 + goto done;
1.628 + }
1.629 +
1.630 + g_static_mutex_unlock( &lock );
1.631 +
1.632 +done:
1.633 + /*
1.634 + if ( uri != NULL )
1.635 + {
1.636 + g_object_unref( uri );
1.637 + uri = NULL;
1.638 + }
1.639 + */
1.640 +
1.641 + return livetv->file_transfer;
1.642 +
1.643 +}
1.644 +
1.645 +/* FIXME: How to proceed differently between livetv and recorded content */
1.646 +void
1.647 +gmyth_livetv_stop_playing (GMythLiveTV *livetv)
1.648 +{
1.649 + gmyth_debug ("Stopping the LiveTV...\n");
1.650 +
1.651 + if (livetv->is_livetv) {
1.652 + if ( !gmyth_recorder_stop_livetv (livetv->recorder) ) {
1.653 + g_warning ("[%s] Error while stoping remote encoder", __FUNCTION__);
1.654 + }
1.655 + }
1.656 +}
1.657 +
1.658 +gboolean
1.659 +gmyth_livetv_is_playing (GMythLiveTV *livetv)
1.660 +{
1.661 + return TRUE;
1.662 +}
1.663 +
1.664 +void
1.665 +gmyth_livetv_start_playing (GMythLiveTV *livetv)
1.666 +{
1.667 +
1.668 + // TODO
1.669 +
1.670 +}
1.671 +