leo_sobral@2
|
1 |
|
leo_sobral@2
|
2 |
#include <gmyth/gmyth_context.h>
|
leo_sobral@2
|
3 |
#include <gmyth/gmyth_remote_util.h>
|
leo_sobral@2
|
4 |
#include <gmyth/gmyth_tvchain.h>
|
leo_sobral@2
|
5 |
|
rosfran@40
|
6 |
#include "gmyth_livetv.h"
|
rosfran@40
|
7 |
#include "gmyth_file_transfer.h"
|
leo_sobral@2
|
8 |
|
rosfran@40
|
9 |
static void gmyth_livetv_class_init (GMythLiveTVClass *klass);
|
rosfran@40
|
10 |
static void gmyth_livetv_init (GMythLiveTV *object);
|
leo_sobral@2
|
11 |
|
rosfran@40
|
12 |
static void gmyth_livetv_dispose (GObject *object);
|
rosfran@40
|
13 |
static void gmyth_livetv_finalize (GObject *object);
|
leo_sobral@2
|
14 |
|
rosfran@37
|
15 |
static gint tvchain_curr_index = -1;
|
rosfran@37
|
16 |
|
rosfran@40
|
17 |
G_DEFINE_TYPE(GMythLiveTV, gmyth_livetv, G_TYPE_OBJECT)
|
leo_sobral@2
|
18 |
|
leo_sobral@2
|
19 |
static void
|
rosfran@40
|
20 |
gmyth_livetv_class_init (GMythLiveTVClass *klass)
|
leo_sobral@2
|
21 |
{
|
leo_sobral@2
|
22 |
GObjectClass *gobject_class;
|
leo_sobral@2
|
23 |
|
leo_sobral@2
|
24 |
gobject_class = (GObjectClass *) klass;
|
leo_sobral@2
|
25 |
|
rosfran@40
|
26 |
gobject_class->dispose = gmyth_livetv_dispose;
|
rosfran@40
|
27 |
gobject_class->finalize = gmyth_livetv_finalize;
|
leo_sobral@2
|
28 |
}
|
leo_sobral@2
|
29 |
|
leo_sobral@2
|
30 |
static void
|
rosfran@40
|
31 |
gmyth_livetv_init (GMythLiveTV *livetv)
|
leo_sobral@2
|
32 |
{
|
leo_sobral@2
|
33 |
livetv->backend_hostname = NULL;
|
leo_sobral@2
|
34 |
livetv->backend_port = 0;
|
leo_sobral@2
|
35 |
livetv->local_hostname = NULL;
|
leo_sobral@2
|
36 |
|
leo_sobral@2
|
37 |
livetv->remote_encoder = NULL;
|
leo_sobral@2
|
38 |
livetv->tvchain = NULL;
|
leo_sobral@2
|
39 |
livetv->proginfo = NULL;
|
leo_sobral@2
|
40 |
}
|
leo_sobral@2
|
41 |
|
leo_sobral@2
|
42 |
static void
|
rosfran@40
|
43 |
gmyth_livetv_dispose (GObject *object)
|
leo_sobral@2
|
44 |
{
|
leo_sobral@2
|
45 |
|
rosfran@40
|
46 |
G_OBJECT_CLASS (gmyth_livetv_parent_class)->dispose (object);
|
leo_sobral@2
|
47 |
}
|
leo_sobral@2
|
48 |
|
leo_sobral@2
|
49 |
static void
|
rosfran@40
|
50 |
gmyth_livetv_finalize (GObject *object)
|
leo_sobral@2
|
51 |
{
|
leo_sobral@2
|
52 |
g_signal_handlers_destroy (object);
|
leo_sobral@2
|
53 |
|
rosfran@40
|
54 |
GMythLiveTV *livetv = GMYTH_LIVETV (object);
|
leo_sobral@2
|
55 |
|
leo_sobral@2
|
56 |
g_debug ("[%s] Finalizing livetv", __FUNCTION__);
|
leo_sobral@2
|
57 |
|
leo_sobral@2
|
58 |
if ( livetv->remote_encoder != NULL ) {
|
leo_sobral@2
|
59 |
g_object_unref (livetv->remote_encoder);
|
leo_sobral@2
|
60 |
livetv->remote_encoder = NULL;
|
leo_sobral@2
|
61 |
}
|
leo_sobral@2
|
62 |
|
leo_sobral@2
|
63 |
if ( livetv->tvchain != NULL ) {
|
leo_sobral@2
|
64 |
g_object_unref (livetv->tvchain);
|
leo_sobral@2
|
65 |
livetv->tvchain = NULL;
|
leo_sobral@2
|
66 |
}
|
leo_sobral@2
|
67 |
|
leo_sobral@2
|
68 |
if ( livetv->proginfo != NULL ) {
|
leo_sobral@2
|
69 |
g_object_unref (livetv->proginfo);
|
leo_sobral@2
|
70 |
livetv->proginfo = NULL;
|
leo_sobral@2
|
71 |
}
|
leo_sobral@2
|
72 |
|
rosfran@40
|
73 |
G_OBJECT_CLASS ( gmyth_livetv_parent_class )->finalize ( object );
|
leo_sobral@2
|
74 |
}
|
leo_sobral@2
|
75 |
|
rosfran@40
|
76 |
GMythLiveTV*
|
rosfran@40
|
77 |
gmyth_livetv_new ()
|
leo_sobral@2
|
78 |
{
|
rosfran@40
|
79 |
GMythLiveTV *livetv = GMYTH_LIVETV ( g_object_new( GMYTH_LIVETV_TYPE, NULL ) );
|
leo_sobral@2
|
80 |
|
leo_sobral@2
|
81 |
return livetv;
|
leo_sobral@2
|
82 |
}
|
leo_sobral@2
|
83 |
|
leo_sobral@2
|
84 |
gboolean
|
rosfran@40
|
85 |
gmyth_livetv_setup ( GMythLiveTV *livetv )
|
leo_sobral@2
|
86 |
{
|
leo_sobral@2
|
87 |
GMythSettings *msettings = gmyth_context_get_settings ();
|
leo_sobral@2
|
88 |
gboolean res = TRUE;
|
leo_sobral@2
|
89 |
|
leo_sobral@2
|
90 |
livetv->is_livetv = TRUE;
|
leo_sobral@2
|
91 |
|
leo_sobral@2
|
92 |
res = gmyth_context_check_connection();
|
leo_sobral@2
|
93 |
if (!res) {
|
leo_sobral@2
|
94 |
g_warning ("[%s] LiveTV can not connect to backend", __FUNCTION__);
|
leo_sobral@2
|
95 |
res = FALSE;
|
leo_sobral@2
|
96 |
goto error;
|
leo_sobral@2
|
97 |
}
|
leo_sobral@2
|
98 |
|
leo_sobral@2
|
99 |
livetv->backend_hostname = gmyth_settings_get_backend_hostname(msettings);
|
leo_sobral@2
|
100 |
livetv->backend_port = gmyth_settings_get_backend_port (msettings);
|
leo_sobral@2
|
101 |
|
leo_sobral@2
|
102 |
livetv->local_hostname = g_string_new("");
|
leo_sobral@2
|
103 |
gmyth_context_get_local_hostname (livetv->local_hostname);
|
leo_sobral@2
|
104 |
|
leo_sobral@2
|
105 |
if ( livetv->local_hostname == NULL ) {
|
leo_sobral@2
|
106 |
res = FALSE;
|
leo_sobral@2
|
107 |
goto error;
|
leo_sobral@2
|
108 |
}
|
leo_sobral@2
|
109 |
|
leo_sobral@2
|
110 |
// Gets the remote encoder num
|
leo_sobral@2
|
111 |
livetv->remote_encoder = remote_request_next_free_recorder (-1);
|
leo_sobral@2
|
112 |
|
leo_sobral@2
|
113 |
if ( livetv->remote_encoder == NULL ) {
|
leo_sobral@2
|
114 |
g_warning ("[%s] None remote encoder available", __FUNCTION__);
|
leo_sobral@2
|
115 |
res = FALSE;
|
leo_sobral@2
|
116 |
goto error;
|
leo_sobral@2
|
117 |
}
|
leo_sobral@2
|
118 |
|
leo_sobral@2
|
119 |
// Creates livetv chain handler
|
leo_sobral@2
|
120 |
livetv->tvchain = GMYTH_TVCHAIN ( g_object_new(GMYTH_TVCHAIN_TYPE, NULL) );
|
leo_sobral@2
|
121 |
gmyth_tvchain_initialize ( livetv->tvchain, livetv->local_hostname );
|
leo_sobral@2
|
122 |
|
leo_sobral@2
|
123 |
if ( livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL ) {
|
leo_sobral@2
|
124 |
res = FALSE;
|
leo_sobral@2
|
125 |
goto error;
|
leo_sobral@2
|
126 |
}
|
leo_sobral@2
|
127 |
|
leo_sobral@2
|
128 |
// Init remote encoder. Opens its control socket.
|
leo_sobral@2
|
129 |
res = gmyth_remote_encoder_setup(livetv->remote_encoder);
|
leo_sobral@2
|
130 |
if ( !res ) {
|
leo_sobral@2
|
131 |
g_warning ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
|
leo_sobral@2
|
132 |
res = FALSE;
|
leo_sobral@2
|
133 |
goto error;
|
leo_sobral@2
|
134 |
}
|
leo_sobral@2
|
135 |
// Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
|
leo_sobral@2
|
136 |
res = gmyth_remote_encoder_spawntv ( livetv->remote_encoder,
|
leo_sobral@2
|
137 |
gmyth_tvchain_get_id(livetv->tvchain) );
|
leo_sobral@2
|
138 |
if (!res) {
|
leo_sobral@2
|
139 |
g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__);
|
leo_sobral@2
|
140 |
res = FALSE;
|
leo_sobral@2
|
141 |
goto error;
|
leo_sobral@2
|
142 |
}
|
leo_sobral@2
|
143 |
|
leo_sobral@2
|
144 |
// Reload all TV chain from Mysql database.
|
leo_sobral@2
|
145 |
gmyth_tvchain_reload_all (livetv->tvchain);
|
leo_sobral@2
|
146 |
|
leo_sobral@2
|
147 |
if ( livetv->tvchain == NULL ) {
|
leo_sobral@2
|
148 |
res = FALSE;
|
leo_sobral@2
|
149 |
goto error;
|
leo_sobral@2
|
150 |
}
|
leo_sobral@2
|
151 |
|
leo_sobral@2
|
152 |
// Get program info from database using chanid and starttime
|
rosfran@37
|
153 |
livetv->proginfo = gmyth_tvchain_get_program_at (livetv->tvchain, tvchain_curr_index++ );
|
leo_sobral@2
|
154 |
if ( livetv->proginfo == NULL ) {
|
leo_sobral@2
|
155 |
g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
|
leo_sobral@2
|
156 |
res = FALSE;
|
leo_sobral@2
|
157 |
goto error;
|
leo_sobral@2
|
158 |
} else {
|
rosfran@40
|
159 |
g_debug ("[%s] GMythLiveTV: All requests to backend to start TV were OK.\n", __FUNCTION__ );
|
leo_sobral@2
|
160 |
}
|
leo_sobral@2
|
161 |
|
leo_sobral@2
|
162 |
return res;
|
leo_sobral@2
|
163 |
|
leo_sobral@2
|
164 |
error:
|
leo_sobral@2
|
165 |
if ( livetv->backend_hostname != NULL ) {
|
leo_sobral@2
|
166 |
g_string_free( livetv->backend_hostname, TRUE );
|
leo_sobral@2
|
167 |
res = FALSE;
|
leo_sobral@2
|
168 |
}
|
leo_sobral@2
|
169 |
|
leo_sobral@2
|
170 |
if ( livetv->local_hostname != NULL ) {
|
leo_sobral@2
|
171 |
g_string_free( livetv->local_hostname, TRUE );
|
leo_sobral@2
|
172 |
res = FALSE;
|
leo_sobral@2
|
173 |
}
|
leo_sobral@2
|
174 |
|
leo_sobral@2
|
175 |
if ( livetv->remote_encoder != NULL ) {
|
leo_sobral@2
|
176 |
g_object_unref (livetv->remote_encoder);
|
leo_sobral@2
|
177 |
livetv->remote_encoder = NULL;
|
leo_sobral@2
|
178 |
}
|
leo_sobral@2
|
179 |
|
leo_sobral@2
|
180 |
if ( livetv->tvchain != NULL ) {
|
leo_sobral@2
|
181 |
g_object_unref (livetv->tvchain);
|
leo_sobral@2
|
182 |
livetv->tvchain = NULL;
|
leo_sobral@2
|
183 |
}
|
leo_sobral@2
|
184 |
|
leo_sobral@2
|
185 |
if ( livetv->proginfo != NULL ) {
|
leo_sobral@2
|
186 |
g_object_unref (livetv->proginfo);
|
leo_sobral@2
|
187 |
livetv->proginfo = NULL;
|
leo_sobral@2
|
188 |
}
|
leo_sobral@2
|
189 |
|
leo_sobral@2
|
190 |
return res;
|
leo_sobral@2
|
191 |
|
leo_sobral@2
|
192 |
}
|
leo_sobral@2
|
193 |
|
leo_sobral@2
|
194 |
// FIXME: How to proceed differently between livetv and recorded content
|
leo_sobral@2
|
195 |
void
|
rosfran@40
|
196 |
gmyth_livetv_stop_playing (GMythLiveTV *livetv)
|
leo_sobral@2
|
197 |
{
|
leo_sobral@2
|
198 |
g_debug ("[%s] Stopping the LiveTV...\n", __FUNCTION__);
|
leo_sobral@2
|
199 |
|
leo_sobral@2
|
200 |
if (livetv->is_livetv) {
|
leo_sobral@2
|
201 |
if (!gmyth_remote_encoder_stop_livetv (livetv->remote_encoder)) {
|
leo_sobral@2
|
202 |
g_warning ("[%s] Error while stoping remote encoder", __FUNCTION__);
|
leo_sobral@2
|
203 |
}
|
leo_sobral@2
|
204 |
}
|
leo_sobral@2
|
205 |
}
|
leo_sobral@2
|
206 |
|
leo_sobral@2
|
207 |
gboolean
|
rosfran@40
|
208 |
gmyth_livetv_is_playing (GMythLiveTV *livetv)
|
leo_sobral@2
|
209 |
{
|
leo_sobral@2
|
210 |
return TRUE;
|
leo_sobral@2
|
211 |
}
|
leo_sobral@2
|
212 |
|
leo_sobral@2
|
213 |
void
|
rosfran@40
|
214 |
gmyth_livetv_start_playing (GMythLiveTV *livetv)
|
leo_sobral@2
|
215 |
{
|
leo_sobral@2
|
216 |
|
leo_sobral@2
|
217 |
// TODO
|
leo_sobral@2
|
218 |
|
leo_sobral@2
|
219 |
}
|
leo_sobral@2
|
220 |
|