leo_sobral@2: leo_sobral@2: #include leo_sobral@2: #include leo_sobral@2: #include leo_sobral@2: rosfran@40: #include "gmyth_livetv.h" rosfran@40: #include "gmyth_file_transfer.h" leo_sobral@2: rosfran@40: static void gmyth_livetv_class_init (GMythLiveTVClass *klass); rosfran@40: static void gmyth_livetv_init (GMythLiveTV *object); leo_sobral@2: rosfran@40: static void gmyth_livetv_dispose (GObject *object); rosfran@40: static void gmyth_livetv_finalize (GObject *object); leo_sobral@2: rosfran@37: static gint tvchain_curr_index = -1; rosfran@37: rosfran@40: G_DEFINE_TYPE(GMythLiveTV, gmyth_livetv, G_TYPE_OBJECT) leo_sobral@2: leo_sobral@2: static void rosfran@40: gmyth_livetv_class_init (GMythLiveTVClass *klass) leo_sobral@2: { leo_sobral@2: GObjectClass *gobject_class; leo_sobral@2: leo_sobral@2: gobject_class = (GObjectClass *) klass; leo_sobral@2: rosfran@40: gobject_class->dispose = gmyth_livetv_dispose; rosfran@40: gobject_class->finalize = gmyth_livetv_finalize; leo_sobral@2: } leo_sobral@2: leo_sobral@2: static void rosfran@40: gmyth_livetv_init (GMythLiveTV *livetv) leo_sobral@2: { leo_sobral@2: livetv->backend_hostname = NULL; leo_sobral@2: livetv->backend_port = 0; leo_sobral@2: livetv->local_hostname = NULL; leo_sobral@2: leo_sobral@2: livetv->remote_encoder = NULL; leo_sobral@2: livetv->tvchain = NULL; leo_sobral@2: livetv->proginfo = NULL; leo_sobral@2: } leo_sobral@2: leo_sobral@2: static void rosfran@40: gmyth_livetv_dispose (GObject *object) leo_sobral@2: { leo_sobral@2: rosfran@40: G_OBJECT_CLASS (gmyth_livetv_parent_class)->dispose (object); leo_sobral@2: } leo_sobral@2: leo_sobral@2: static void rosfran@40: gmyth_livetv_finalize (GObject *object) leo_sobral@2: { leo_sobral@2: g_signal_handlers_destroy (object); leo_sobral@2: rosfran@40: GMythLiveTV *livetv = GMYTH_LIVETV (object); leo_sobral@2: leo_sobral@2: g_debug ("[%s] Finalizing livetv", __FUNCTION__); leo_sobral@2: leo_sobral@2: if ( livetv->remote_encoder != NULL ) { leo_sobral@2: g_object_unref (livetv->remote_encoder); leo_sobral@2: livetv->remote_encoder = NULL; leo_sobral@2: } leo_sobral@2: leo_sobral@2: if ( livetv->tvchain != NULL ) { leo_sobral@2: g_object_unref (livetv->tvchain); leo_sobral@2: livetv->tvchain = NULL; leo_sobral@2: } leo_sobral@2: leo_sobral@2: if ( livetv->proginfo != NULL ) { leo_sobral@2: g_object_unref (livetv->proginfo); leo_sobral@2: livetv->proginfo = NULL; leo_sobral@2: } leo_sobral@2: rosfran@40: G_OBJECT_CLASS ( gmyth_livetv_parent_class )->finalize ( object ); leo_sobral@2: } leo_sobral@2: rosfran@40: GMythLiveTV* rosfran@40: gmyth_livetv_new () leo_sobral@2: { rosfran@40: GMythLiveTV *livetv = GMYTH_LIVETV ( g_object_new( GMYTH_LIVETV_TYPE, NULL ) ); leo_sobral@2: leo_sobral@2: return livetv; leo_sobral@2: } leo_sobral@2: leo_sobral@2: gboolean rosfran@40: gmyth_livetv_setup ( GMythLiveTV *livetv ) leo_sobral@2: { leo_sobral@2: GMythSettings *msettings = gmyth_context_get_settings (); leo_sobral@2: gboolean res = TRUE; leo_sobral@2: leo_sobral@2: livetv->is_livetv = TRUE; leo_sobral@2: leo_sobral@2: res = gmyth_context_check_connection(); leo_sobral@2: if (!res) { leo_sobral@2: g_warning ("[%s] LiveTV can not connect to backend", __FUNCTION__); leo_sobral@2: res = FALSE; leo_sobral@2: goto error; leo_sobral@2: } leo_sobral@2: leo_sobral@2: livetv->backend_hostname = gmyth_settings_get_backend_hostname(msettings); leo_sobral@2: livetv->backend_port = gmyth_settings_get_backend_port (msettings); leo_sobral@2: leo_sobral@2: livetv->local_hostname = g_string_new(""); leo_sobral@2: gmyth_context_get_local_hostname (livetv->local_hostname); leo_sobral@2: leo_sobral@2: if ( livetv->local_hostname == NULL ) { leo_sobral@2: res = FALSE; leo_sobral@2: goto error; leo_sobral@2: } leo_sobral@2: leo_sobral@2: // Gets the remote encoder num leo_sobral@2: livetv->remote_encoder = remote_request_next_free_recorder (-1); leo_sobral@2: leo_sobral@2: if ( livetv->remote_encoder == NULL ) { leo_sobral@2: g_warning ("[%s] None remote encoder available", __FUNCTION__); leo_sobral@2: res = FALSE; leo_sobral@2: goto error; leo_sobral@2: } leo_sobral@2: leo_sobral@2: // Creates livetv chain handler leo_sobral@2: livetv->tvchain = GMYTH_TVCHAIN ( g_object_new(GMYTH_TVCHAIN_TYPE, NULL) ); leo_sobral@2: gmyth_tvchain_initialize ( livetv->tvchain, livetv->local_hostname ); leo_sobral@2: leo_sobral@2: if ( livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL ) { leo_sobral@2: res = FALSE; leo_sobral@2: goto error; leo_sobral@2: } leo_sobral@2: leo_sobral@2: // Init remote encoder. Opens its control socket. leo_sobral@2: res = gmyth_remote_encoder_setup(livetv->remote_encoder); leo_sobral@2: if ( !res ) { leo_sobral@2: g_warning ("[%s] Fail while setting remote encoder\n", __FUNCTION__); leo_sobral@2: res = FALSE; leo_sobral@2: goto error; leo_sobral@2: } leo_sobral@2: // Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly) leo_sobral@2: res = gmyth_remote_encoder_spawntv ( livetv->remote_encoder, leo_sobral@2: gmyth_tvchain_get_id(livetv->tvchain) ); leo_sobral@2: if (!res) { leo_sobral@2: g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__); leo_sobral@2: res = FALSE; leo_sobral@2: goto error; leo_sobral@2: } leo_sobral@2: leo_sobral@2: // Reload all TV chain from Mysql database. leo_sobral@2: gmyth_tvchain_reload_all (livetv->tvchain); leo_sobral@2: leo_sobral@2: if ( livetv->tvchain == NULL ) { leo_sobral@2: res = FALSE; leo_sobral@2: goto error; leo_sobral@2: } leo_sobral@2: leo_sobral@2: // Get program info from database using chanid and starttime rosfran@37: livetv->proginfo = gmyth_tvchain_get_program_at (livetv->tvchain, tvchain_curr_index++ ); leo_sobral@2: if ( livetv->proginfo == NULL ) { leo_sobral@2: g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ ); leo_sobral@2: res = FALSE; leo_sobral@2: goto error; leo_sobral@2: } else { rosfran@40: g_debug ("[%s] GMythLiveTV: All requests to backend to start TV were OK.\n", __FUNCTION__ ); leo_sobral@2: } leo_sobral@2: leo_sobral@2: return res; leo_sobral@2: leo_sobral@2: error: leo_sobral@2: if ( livetv->backend_hostname != NULL ) { leo_sobral@2: g_string_free( livetv->backend_hostname, TRUE ); leo_sobral@2: res = FALSE; leo_sobral@2: } leo_sobral@2: leo_sobral@2: if ( livetv->local_hostname != NULL ) { leo_sobral@2: g_string_free( livetv->local_hostname, TRUE ); leo_sobral@2: res = FALSE; leo_sobral@2: } leo_sobral@2: leo_sobral@2: if ( livetv->remote_encoder != NULL ) { leo_sobral@2: g_object_unref (livetv->remote_encoder); leo_sobral@2: livetv->remote_encoder = NULL; leo_sobral@2: } leo_sobral@2: leo_sobral@2: if ( livetv->tvchain != NULL ) { leo_sobral@2: g_object_unref (livetv->tvchain); leo_sobral@2: livetv->tvchain = NULL; leo_sobral@2: } leo_sobral@2: leo_sobral@2: if ( livetv->proginfo != NULL ) { leo_sobral@2: g_object_unref (livetv->proginfo); leo_sobral@2: livetv->proginfo = NULL; leo_sobral@2: } leo_sobral@2: leo_sobral@2: return res; leo_sobral@2: leo_sobral@2: } leo_sobral@2: leo_sobral@2: // FIXME: How to proceed differently between livetv and recorded content leo_sobral@2: void rosfran@40: gmyth_livetv_stop_playing (GMythLiveTV *livetv) leo_sobral@2: { leo_sobral@2: g_debug ("[%s] Stopping the LiveTV...\n", __FUNCTION__); leo_sobral@2: leo_sobral@2: if (livetv->is_livetv) { leo_sobral@2: if (!gmyth_remote_encoder_stop_livetv (livetv->remote_encoder)) { leo_sobral@2: g_warning ("[%s] Error while stoping remote encoder", __FUNCTION__); leo_sobral@2: } leo_sobral@2: } leo_sobral@2: } leo_sobral@2: leo_sobral@2: gboolean rosfran@40: gmyth_livetv_is_playing (GMythLiveTV *livetv) leo_sobral@2: { leo_sobral@2: return TRUE; leo_sobral@2: } leo_sobral@2: leo_sobral@2: void rosfran@40: gmyth_livetv_start_playing (GMythLiveTV *livetv) leo_sobral@2: { leo_sobral@2: leo_sobral@2: // TODO leo_sobral@2: leo_sobral@2: } leo_sobral@2: