4 * @file gmyth/gmyth_recorder.c
6 * @brief <p> GMythRecorder defines functions for playing live tv.
8 * The remote encoder is used by gmyth_tvplayer to setup livetv.
10 * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
11 * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
12 * @author Rosfran Borges <rosfran.borges@indt.org.br>
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU Lesser General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include "gmyth_recorder.h"
38 #include "gmyth_stringlist.h"
39 #include "gmyth_util.h"
40 #include "gmyth_common.h"
41 #include "gmyth_debug.h"
43 #define GMYTHTV_RECORDER_HEADER "QUERY_RECORDER"
45 static void gmyth_recorder_class_init(GMythRecorderClass * klass);
46 static void gmyth_recorder_init(GMythRecorder * object);
48 static void gmyth_recorder_dispose(GObject * object);
49 static void gmyth_recorder_finalize(GObject * object);
51 G_DEFINE_TYPE(GMythRecorder, gmyth_recorder, G_TYPE_OBJECT)
52 static void gmyth_recorder_class_init(GMythRecorderClass * klass)
54 GObjectClass *gobject_class;
56 gobject_class = (GObjectClass *) klass;
58 gobject_class->dispose = gmyth_recorder_dispose;
59 gobject_class->finalize = gmyth_recorder_finalize;
63 gmyth_recorder_init(GMythRecorder * gmyth_remote_encoder)
68 gmyth_recorder_dispose(GObject * object)
70 GMythRecorder *recorder = GMYTH_RECORDER(object);
72 gmyth_recorder_close(recorder);
74 if (recorder->mutex != NULL) {
75 g_mutex_free(recorder->mutex);
76 recorder->mutex = NULL;
79 if (recorder->myth_socket != NULL) {
80 g_object_unref(recorder->myth_socket);
81 recorder->myth_socket = NULL;
84 if (recorder->progs_info_list != NULL)
85 gmyth_free_program_list(recorder->progs_info_list);
87 if (recorder->hostname != NULL)
88 g_string_free(recorder->hostname, TRUE);
90 G_OBJECT_CLASS(gmyth_recorder_parent_class)->dispose(object);
94 gmyth_recorder_finalize(GObject * object)
96 g_signal_handlers_destroy(object);
98 G_OBJECT_CLASS(gmyth_recorder_parent_class)->finalize(object);
102 gmyth_recorder_close(GMythRecorder * recorder)
104 if (recorder != NULL && recorder->recorder_num != -1) {
105 g_mutex_lock(recorder->mutex);
107 gmyth_recorder_stop_playing(recorder);
108 gmyth_recorder_stop_livetv(recorder);
109 gmyth_recorder_finish_recording(recorder);
110 gmyth_recorder_free_tuner(recorder);
112 g_mutex_unlock(recorder->mutex);
116 /** Creates a new instance of GMythRecorder.
118 * @return a new instance of GMythRecorder.
121 gmyth_recorder_new(int num, GString * hostname, gshort port)
123 GMythRecorder *encoder =
124 GMYTH_RECORDER(g_object_new(GMYTH_RECORDER_TYPE, FALSE));
126 encoder->recorder_num = num;
127 encoder->hostname = g_string_new(hostname->str);
128 encoder->port = port;
130 encoder->mutex = g_mutex_new();
132 encoder->progs_info_list = NULL;
137 /** Configures the remote encoder instance connecting it to Mythtv backend.
139 * @param recorder the GMythRecorder instance.
141 * @return TRUE if successfull, FALSE if any error happens.
144 gmyth_recorder_setup(GMythRecorder * recorder)
147 gmyth_debug("[%s] Creating socket and connecting to backend",
150 if (recorder->myth_socket == NULL) {
151 recorder->myth_socket = gmyth_socket_new();
153 if (!gmyth_socket_connect_to_backend(recorder->myth_socket,
154 recorder->hostname->str,
155 recorder->port, TRUE)) {
157 ("GMythRemoteEncoder: Connection to backend failed");
161 gmyth_debug("Remote encoder socket already created\n");
167 /** Sends the SPAWN_LIVETV command through Mythtv protocol. This command
168 * requests the backend to start capturing TV content.
170 * @param recorder The GMythRecorder instance.
171 * @param tvchain_id The tvchain unique id.
172 * @return true if success, false if any error happens.
175 gmyth_recorder_spawntv(GMythRecorder * recorder, GString * tvchain_id)
177 GMythStringList *str_list;
178 GString *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
181 gmyth_debug("[%s] Spawntv with tvchain_id = %s", __FUNCTION__,
184 str_list = gmyth_string_list_new();
186 g_mutex_lock(recorder->mutex);
188 g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
190 gmyth_string_list_append_string(str_list, tmp_str);
191 g_string_free(tmp_str, TRUE);
193 gmyth_string_list_append_char_array(str_list, "SPAWN_LIVETV");
195 gmyth_string_list_append_string(str_list, tvchain_id);
196 gmyth_string_list_append_int(str_list, 0); // PIP = FALSE (0)
198 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
200 tmp_str = gmyth_string_list_get_string(str_list, 0);
202 if (tmp_str == NULL) {
203 gmyth_debug("[%s] Spawntv request returned %s", __FUNCTION__,
209 if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
210 gmyth_debug("[%s] Spawntv request returned %s", __FUNCTION__,
217 g_mutex_unlock(recorder->mutex);
219 g_string_free(tmp_str, TRUE);
220 g_object_unref(str_list);
226 * Sends the SPAWN_LIVETV command through Mythtv protocol. This command
227 * requests the backend to start capturing TV content, but it doesn't need
230 * @param recorder The GMythRecorder instance.
231 * @return true if success, false if any error happens.
234 gmyth_recorder_spawntv_no_tvchain(GMythRecorder * recorder)
236 GMythStringList *str_list;
237 GString *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
240 gmyth_debug("[%s] Spawntv, no TV chain!", __FUNCTION__);
242 str_list = gmyth_string_list_new();
244 g_mutex_lock(recorder->mutex);
246 g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
248 gmyth_string_list_append_string(str_list, tmp_str);
249 g_string_free(tmp_str, TRUE);
251 gmyth_string_list_append_char_array(str_list, "SPAWN_LIVETV");
253 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
255 tmp_str = gmyth_string_list_get_string(str_list, 0);
257 if (tmp_str == NULL) {
258 gmyth_debug("[%s] Spawntv request returned %s", __FUNCTION__,
264 if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
265 gmyth_debug("[%s] Spawntv request returned %s", __FUNCTION__,
272 g_mutex_unlock(recorder->mutex);
274 g_string_free(tmp_str, TRUE);
275 g_object_unref(str_list);
280 /** Sends the command STOP_LIVETV to Mythtv backend.
282 * @param recorder the GMythRecorder instance.
283 * @return true if success, false if any error happens.
286 gmyth_recorder_stop_livetv(GMythRecorder * recorder)
288 GMythStringList *str_list;
289 GString *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
292 gmyth_debug("[%s]", __FUNCTION__);
294 str_list = gmyth_string_list_new();
296 g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
298 gmyth_string_list_append_string(str_list, tmp_str);
299 g_string_free(tmp_str, TRUE);
301 gmyth_string_list_append_char_array(str_list, "STOP_LIVETV");
303 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
305 tmp_str = gmyth_string_list_get_string(str_list, 0);
307 if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
308 gmyth_debug("[%s] Stop livetv request returned %s", __FUNCTION__,
315 g_string_free(tmp_str, TRUE);
316 g_object_unref(str_list);
321 /** Sends the FRONTEND_READY command through Mythtv protocol. This command
322 * advertises the backend to start capturing TV content.
324 * @param recorder The GMythRecorder instance.
325 * @return TRUE if success, FALSE if any error happens.
328 gmyth_recorder_send_frontend_ready_command(GMythRecorder * recorder)
330 GMythStringList *str_list;
331 GString *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
334 gmyth_debug("[%s] FRONTEND_READY with recorder id = %d", __FUNCTION__,
335 recorder->recorder_num);
337 str_list = gmyth_string_list_new();
339 g_mutex_lock(recorder->mutex);
341 g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
343 gmyth_string_list_append_string(str_list, tmp_str);
344 g_string_free(tmp_str, TRUE);
346 gmyth_string_list_append_char_array(str_list, "FRONTEND_READY");
348 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
350 tmp_str = gmyth_string_list_get_string(str_list, 0);
352 if (tmp_str == NULL) {
354 ("[%s] FRONTEND_READY command request couldn't returns, reason: %s",
355 __FUNCTION__, tmp_str->str);
360 if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
361 gmyth_debug("[%s] FRONTEND_READY request returned %s",
362 __FUNCTION__, tmp_str->str);
368 g_mutex_unlock(recorder->mutex);
369 g_string_free(tmp_str, TRUE);
370 g_object_unref(str_list);
375 /** Send a CHECK_CHANNEL command request to the backend, in order to find if a
376 * certain channel actually exists.
378 * @param recorder The GMythRecorder instance.
379 * @param channel The new channel to be checked (string format).
380 * @return true if success, false if any error happens.
383 gmyth_recorder_check_channel_name(GMythRecorder * recorder,
386 GMythStringList *str_list;
387 GString *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
390 gmyth_debug("[%s] CHECK_CHANNEL with channel = %s", __FUNCTION__,
393 str_list = gmyth_string_list_new();
395 g_mutex_lock(recorder->mutex);
397 g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
399 gmyth_string_list_append_string(str_list, tmp_str);
400 g_string_free(tmp_str, TRUE);
402 gmyth_string_list_append_char_array(str_list, "CHECK_CHANNEL");
404 gmyth_string_list_append_char_array(str_list, channel);
406 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
408 tmp_str = gmyth_string_list_get_string(str_list, 0);
410 if (tmp_str == NULL) {
411 gmyth_debug("[%s] CHECK_CHANNEL request returned %s", __FUNCTION__,
417 if (g_ascii_strncasecmp(tmp_str->str, "ok", 2) == 0
418 || g_ascii_strncasecmp(tmp_str->str, "0", 1) == 0) {
419 gmyth_debug("[%s] CHECK_CHANNEL request returned %s", __FUNCTION__,
426 g_mutex_unlock(recorder->mutex);
427 g_string_free(tmp_str, TRUE);
428 g_object_unref(str_list);
433 /** Send a CHECK_CHANNEL command request to the backend, in order to find if a
434 * certain channel actually exists.
436 * @param recorder The GMythRecorder instance.
437 * @param channel The new channel to be checked (decimal integer value).
438 * @return true if success, false if any error happens.
441 gmyth_recorder_check_channel(GMythRecorder * recorder, gint channel)
443 return gmyth_recorder_check_channel_name(recorder,
444 g_strdup_printf("%d",
448 /** Send a SET_CHANNEL command request to the backend, to start streaming on another
449 * TV content channel.
451 * @param recorder The GMythRecorder instance.
452 * @param channel The new channel to be loaded.
453 * @return true if success, false if any error happens.
456 gmyth_recorder_set_channel(GMythRecorder * recorder, gint channel)
458 GMythStringList *str_list;
459 GString *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
462 gmyth_debug("[%s] SET_CHANNEL with channel = %d", __FUNCTION__,
465 str_list = gmyth_string_list_new();
467 g_mutex_lock(recorder->mutex);
469 g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
471 gmyth_string_list_append_string(str_list, tmp_str);
472 g_string_free(tmp_str, TRUE);
474 gmyth_string_list_append_char_array(str_list, "SET_CHANNEL");
476 gmyth_string_list_append_int(str_list, channel);
478 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
480 tmp_str = gmyth_string_list_get_string(str_list, 0);
482 if (tmp_str == NULL) {
483 gmyth_debug("[%s] SET_CHANNEL request returned %s", __FUNCTION__,
489 if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
490 gmyth_debug("[%s] SET_CHANNEL request returned %s", __FUNCTION__,
497 g_mutex_unlock(recorder->mutex);
498 g_string_free(tmp_str, TRUE);
499 g_object_unref(str_list);
504 /** Send a SET_CHANNEL command request to the backend, to start streaming on another
505 * TV content channel.
507 * @param recorder The GMythRecorder instance.
508 * @param channel The new channel to be loaded.
509 * @return true if success, false if any error happens.
512 gmyth_recorder_set_channel_name(GMythRecorder * recorder,
513 const gchar * channel)
515 GMythStringList *str_list;
516 GString *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
519 gmyth_debug("[%s] SET_CHANNEL with channel name = %s", __FUNCTION__,
522 str_list = gmyth_string_list_new();
524 g_mutex_lock(recorder->mutex);
526 g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
528 gmyth_string_list_append_string(str_list, tmp_str);
529 g_string_free(tmp_str, TRUE);
531 gmyth_string_list_append_char_array(str_list, "SET_CHANNEL");
532 gmyth_string_list_append_char_array(str_list, channel);
534 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
536 tmp_str = gmyth_string_list_get_string(str_list, 0);
538 if (tmp_str == NULL) {
539 gmyth_debug("[%s] SET_CHANNEL name request returned NULL!",
545 if (tmp_str != NULL && g_ascii_strncasecmp(tmp_str->str, "ok", 2)
547 * || g_ascii_strtoull( tmp_str->str, NULL, 10 ) == 0
550 g_warning("[%s] SET_CHANNEL name request returned not ok",
557 g_mutex_unlock(recorder->mutex);
558 g_string_free(tmp_str, TRUE);
559 g_object_unref(str_list);
565 * Changes the channel of the actual Recorder.
567 * CHANNEL_DIRECTION_UP - Go up one channel in the listing
569 * CHANNEL_DIRECTION_DOWN - Go down one channel in the listing
571 * CHANNEL_DIRECTION_FAVORITE - Go to the next favorite channel
573 * CHANNEL_DIRECTION_SAME - Stay
575 * @param recorder The GMythRecorder instance.
576 * @param direction The new channel direction where to move to.
577 * @return true if success, false if any error happens.
580 gmyth_recorder_change_channel(GMythRecorder * recorder,
581 const GMythRecorderChannelChangeDirection
584 GMythStringList *str_list;
585 GString *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
588 gmyth_debug("[%s] CHANGE_CHANNEL to the channel direction = %u",
589 __FUNCTION__, direction);
591 str_list = gmyth_string_list_new();
593 g_mutex_lock(recorder->mutex);
595 g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
597 gmyth_string_list_append_string(str_list, tmp_str);
598 g_string_free(tmp_str, TRUE);
600 gmyth_string_list_append_char_array(str_list, "CHANGE_CHANNEL");
601 gmyth_string_list_append_int(str_list, direction);
603 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
605 tmp_str = gmyth_string_list_get_string(str_list, 0);
607 if (tmp_str == NULL) {
608 gmyth_debug("[%s] CHANGE_CHANNEL name request returned %s",
609 __FUNCTION__, tmp_str->str);
614 if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)
615 || g_ascii_strtoull(tmp_str->str, NULL, 10) == 0) {
616 gmyth_debug("[%s] CHANGE_CHANNEL name request returned %s",
617 __FUNCTION__, tmp_str->str);
623 g_mutex_unlock(recorder->mutex);
624 g_string_free(tmp_str, TRUE);
625 g_object_unref(str_list);
631 * Gets the channel's list from the MythTV backend server.
633 * @param recorder The GMythRecorder instance.
635 * @return a GList* instance with all the channel names.
638 gmyth_recorder_get_channel_list(GMythRecorder * recorder)
641 GList *channel_list = NULL;
642 gchar *channel = NULL;
645 for (i = 0; i < 1000; i++) {
646 channel = g_strdup_printf("%u", i);
648 if (gmyth_recorder_check_channel_name(recorder, channel)) {
649 channel_list = g_list_append(channel_list, g_strdup(channel));
652 } /* for - channel list */
660 /** Send a PAUSE command request to the backend, to pause streaming on another
661 * TV content channel.
663 * @param recorder The GMythRecorder instance.
664 * @return true if success, false if any error happens.
667 gmyth_recorder_pause_recording(GMythRecorder * recorder)
669 GMythStringList *str_list;
670 GString *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
673 gmyth_debug("[%s] PAUSE", __FUNCTION__);
675 str_list = gmyth_string_list_new();
677 g_mutex_lock(recorder->mutex);
679 g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
681 gmyth_string_list_append_string(str_list, tmp_str);
682 g_string_free(tmp_str, TRUE);
684 gmyth_string_list_append_char_array(str_list, "PAUSE");
686 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
688 tmp_str = gmyth_string_list_get_string(str_list, 0);
690 if (tmp_str == NULL) {
691 gmyth_debug("[%s] PAUSE name request returned %s", __FUNCTION__,
697 if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
698 gmyth_debug("[%s] PAUSE name request returned %s", __FUNCTION__,
705 g_mutex_unlock(recorder->mutex);
706 g_string_free(tmp_str, TRUE);
707 g_object_unref(str_list);
713 gmyth_recorder_find_if_program_exists(GMythRecorder * recorder,
714 GMythProgramInfo * prog)
718 g_return_val_if_fail(recorder != NULL
719 && recorder->progs_info_list != NULL, FALSE);
721 for (lst = recorder->progs_info_list; lst != NULL;
722 lst = g_list_next(lst)) {
723 gmyth_debug("Got program info from list = [%s]",
724 gmyth_program_info_to_string((GMythProgramInfo *)
726 if (gmyth_program_info_is_equals
727 (prog, (GMythProgramInfo *) lst->data))
735 * Requests the actual program info from the MythTV backend server.
737 * @param recorder The GMythRecorder instance.
738 * @return The actual program info.
741 gmyth_recorder_get_current_program_info(GMythRecorder * recorder)
743 GMythStringList *str_list = NULL;
744 GMythProgramInfo *program_info = NULL;
745 GString *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
747 str_list = gmyth_string_list_new();
749 g_mutex_lock(recorder->mutex);
751 g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
753 gmyth_string_list_append_string(str_list, tmp_str);
755 if (recorder->myth_socket->mythtv_version >= 26)
756 gmyth_string_list_append_char_array(str_list,
757 "GET_CURRENT_RECORDING");
759 gmyth_string_list_append_char_array(str_list, "GET_PROGRAM_INFO");
761 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
763 if (str_list == NULL) {
765 ("[%s] GET_PROGRAM_INFO request returned. Error getting program info, string list equals to NULL!",
770 program_info = gmyth_program_info_from_string_list(str_list);
772 if (NULL == program_info || NULL == program_info->pathname
773 || program_info->pathname->len <= 0) {
775 ("GET_PROGRAM_INFO request returned. Error getting program info, it is equals to NULL!!!");
778 g_object_unref(program_info);
785 if (!gmyth_recorder_find_if_program_exists(recorder, program_info))
786 recorder->progs_info_list =
787 g_list_append(recorder->progs_info_list,
788 g_object_ref(program_info));
790 g_mutex_unlock(recorder->mutex);
791 g_string_free(tmp_str, TRUE);
792 g_object_unref(str_list);
798 * Requests the actual program info from the MythTV backend server.
800 * @param rec_id The GMythRecorder record number.
801 * @return The GMythRecorder instance.
804 gmyth_recorder_get_recorder_from_num(gint rec_id)
806 GMythRecorder *recorder = NULL;
807 GMythStringList *str_list;
808 GString *tmp_str = g_string_new("GET_RECORDER_FROM_NUM");
809 gint command_size = 0;
811 gchar *recorder_host = NULL;
814 str_list = gmyth_string_list_new();
817 * g_string_append_printf ( tmp_str, " %d", recorder->recorder_num );
820 g_mutex_lock(recorder->mutex);
822 gmyth_string_list_append_string(str_list, tmp_str);
824 gmyth_string_list_append_int(str_list, rec_id);
827 gmyth_socket_sendreceive_stringlist(recorder->myth_socket,
830 if (str_list == NULL) {
832 ("[%s] GET_RECORDER_FROM_NUM request returned. Error getting recorder number %d, it is equals to NULL!!!",
833 __FUNCTION__, rec_id);
837 if (command_size > 0) {
838 recorder_host = gmyth_string_list_get_char_array(str_list, 0);
839 recorder_port = gmyth_string_list_get_int(str_list, 1);
841 if (g_strstr_len(recorder_host, strlen(recorder_host), "nohost")
844 ("No available recorder with the recorder ID number %d!",
848 recorder = gmyth_recorder_new(rec_id,
849 g_string_new(recorder_host),
850 (gshort) recorder_port);
852 if (NULL == recorder) {
854 ("[%s] GET_RECORDER_FROM_NUM request returned. Error getting recorder number %d, it is equals to NULL!!!",
855 __FUNCTION__, rec_id);
856 g_object_unref(recorder);
864 ("Cannot find a valuable recorder with the recorder ID number %d, backend server error!",
868 g_mutex_unlock(recorder->mutex);
870 g_object_unref(str_list);
872 g_string_free(tmp_str, TRUE);
874 g_free(recorder_host);
881 * Requests the actual program info from the MythTV backend server.
883 * @param recorder The GMythRecorder instance.
884 * @param direction The direction to move based on the current channel (forward, backward,
887 * @return The GMythProgramInfo next program info instance.
890 gmyth_recorder_get_next_program_info(GMythRecorder * recorder,
891 const GMythRecorderBrowseDirection
894 GMythProgramInfo *actual_proginfo = NULL;
895 GMythProgramInfo *program_info = NULL;
896 GMythStringList *str_list;
897 GString *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
900 struct tm *tm = NULL;
903 actual_proginfo = gmyth_recorder_get_current_program_info(recorder);
905 str_list = gmyth_string_list_new();
907 g_mutex_lock(recorder->mutex);
909 g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
913 date = g_strdup_printf("%.4d%.2d%.2d%.2d%.2d%.2d", tm->tm_year + 1900,
914 tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
915 tm->tm_min, tm->tm_sec);
917 gmyth_string_list_append_string(str_list, tmp_str);
918 gmyth_string_list_append_char_array(str_list, "GET_NEXT_PROGRAM_INFO");
919 gmyth_string_list_append_string(str_list, actual_proginfo->channame);
920 gmyth_string_list_append_string(str_list, actual_proginfo->chanid);
921 gmyth_string_list_append_int(str_list, direction);
922 gmyth_string_list_append_char_array(str_list, date);
924 if (gmyth_socket_sendreceive_stringlist
925 (recorder->myth_socket, str_list)
928 if (str_list == NULL) {
930 ("[%s] GET_NEXT_PROGRAM_INFO request returned. Error getting program info, it is equals to NULL!!!",
935 gmyth_program_info_from_string_list_next_prog(str_list);
937 if (NULL == program_info) {
939 ("[%s] GET_NEXT_PROGRAM_INFO request returned. Error getting next program info, it is equals to NULL!!!",
941 g_object_unref(program_info);
945 if ( /* ( program_info->chanid != NULL &&
946 * strlen( program_info->chanid->str ) > 0
948 (program_info->chansign != NULL
949 && strlen(program_info->chansign->str) > 0)) {
950 gmyth_debug("OK!!! Got the next program info... [%s].",
951 program_info->chansign->str);
954 ("GET_NEXT_PROGRAM_INFO request returned. Error getting next program info, it is equals to NULL!!!");
955 g_object_unref(program_info);
965 g_mutex_unlock(recorder->mutex);
967 if (actual_proginfo != NULL)
968 g_object_unref(actual_proginfo);
970 if (str_list != NULL)
971 g_object_unref(str_list);
974 g_string_free(tmp_str, TRUE);
985 * Requests the program info from the MythTV backend server, based on its
988 * @param recorder The GMythRecorder instance.
989 * @return The GMythProgramInfo next program info instance.
992 gmyth_recorder_get_program_info_from_channel_name(GMythRecorder * recorder,
993 const gchar * channel)
995 // GMythProgramInfo* actual_proginfo= NULL;
996 GMythProgramInfo *program_info = NULL;
997 GMythStringList *str_list;
998 GString *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
1001 * gchar *date = NULL; struct tm *tm = NULL; time_t t;
1004 * gmyth_recorder_get_current_program_info(recorder);
1007 str_list = gmyth_string_list_new();
1009 g_mutex_lock(recorder->mutex);
1011 g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
1014 * t = time(NULL); tm = localtime(&t); date =
1015 * g_strdup_printf("%.4d%.2d%.2d%.2d%.2d%.2d", tm->tm_year + 1900,
1016 * tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
1019 gmyth_string_list_append_string(str_list, tmp_str);
1020 gmyth_string_list_append_char_array(str_list, "GET_NEXT_PROGRAM_INFO");
1021 gmyth_string_list_append_char_array(str_list, channel);
1022 gmyth_string_list_append_char_array(str_list, "0");
1023 gmyth_string_list_append_int(str_list, BROWSE_DIRECTION_UP);
1024 gmyth_string_list_append_char_array(str_list, "0");
1028 if (str_list != NULL &&
1029 gmyth_socket_sendreceive_stringlist(recorder->myth_socket,
1032 if (str_list == NULL) {
1034 ("[%s] GET_NEXT_PROGRAM_INFO request returned. Error getting program info, it is equals to NULL!!!",
1039 gmyth_program_info_from_string_list_next_prog(str_list);
1041 if (NULL == program_info) {
1043 ("[%s] GET_NEXT_PROGRAM_INFO request returned. Error getting next program info, it is equals to NULL!!!",
1045 g_object_unref(program_info);
1049 if ( /* ( program_info->chanid != NULL &&
1050 * strlen( program_info->chanid->str ) > 0
1052 (program_info->chansign != NULL
1053 && strlen(program_info->chansign->str) > 0)) {
1054 gmyth_debug("OK!!! Got the next program info... [%s].",
1055 program_info->chansign->str);
1058 ("GET_NEXT_PROGRAM_INFO request returned. Error getting "
1059 "next program info, it is equals to NULL!!!");
1060 g_object_unref(program_info);
1061 program_info = NULL;
1069 while (str_list != NULL);
1073 g_mutex_unlock(recorder->mutex);
1075 if (str_list != NULL)
1076 g_object_unref(str_list);
1078 if (tmp_str != NULL)
1079 g_string_free(tmp_str, TRUE);
1081 return program_info;
1085 * Requests the actual remote file position on a LiveTV instance.
1087 * @param recorder The GMythRecorder instance.
1089 * @return The position, in bytes, of the offset to the read header.
1092 gmyth_recorder_get_file_position(GMythRecorder * recorder)
1095 GString *query = g_string_new(GMYTHTV_RECORDER_HEADER);
1097 GMythStringList *str_list = gmyth_string_list_new();
1099 g_mutex_lock(recorder->mutex);
1101 g_string_append_printf(query, " %d", recorder->recorder_num);
1103 gmyth_string_list_append_string(str_list, query);
1104 gmyth_string_list_append_char_array(str_list, "GET_FILE_POSITION");
1106 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
1108 if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
1109 GString *str = NULL;
1111 if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL
1112 && strstr(str->str, "bad") == NULL)
1113 pos = gmyth_string_list_get_int64(str_list, 0);
1114 g_string_free(str, TRUE);
1116 #ifndef GMYTHTV_ENABLE_DEBUG
1117 gmyth_debug("[%s] Got file position = %lld\n", __FUNCTION__, pos);
1120 g_mutex_unlock(recorder->mutex);
1122 if (str_list != NULL)
1123 g_object_unref(str_list);
1125 g_string_free(query, TRUE);
1131 * Asks MythTV backend server about if it started to record the remote file.
1133 * @param recorder The GMythRecorder instance.
1135 * @return <code>true</code>, if the actual remote file is bein recorded.
1138 gmyth_recorder_is_recording(GMythRecorder * recorder)
1140 gboolean ret = TRUE;
1142 g_return_val_if_fail(recorder != NULL, FALSE);
1144 GMythStringList *str_list = gmyth_string_list_new();
1145 GString *message = g_string_new("");
1147 g_mutex_lock(recorder->mutex);
1149 g_string_printf(message, "%s %d", GMYTHTV_RECORDER_HEADER,
1150 recorder->recorder_num);
1151 gmyth_string_list_append_string(str_list, message);
1152 gmyth_string_list_append_char_array(str_list, "IS_RECORDING");
1154 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
1156 if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
1157 GString *str = NULL;
1159 if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL
1160 && strcmp(str->str, "bad") != 0) {
1162 gmyth_string_list_get_int(str_list, 0);
1169 g_string_free(str, TRUE);
1172 gmyth_debug("%s, stream is %s being recorded!\n", ret ? "YES" : "NO",
1174 // g_static_mutex_unlock (&mutex);
1176 g_mutex_unlock(recorder->mutex);
1178 if (str_list != NULL)
1179 g_object_unref(str_list);
1181 g_string_free(message, TRUE);
1188 * Finish remote file recording process.
1190 * @param recorder The GMythRecorder instance.
1192 * @return <code>true</code>, if the recording had been actually closed.
1195 gmyth_recorder_finish_recording(GMythRecorder * recorder)
1197 gboolean ret = TRUE;
1199 g_return_val_if_fail(recorder != NULL, FALSE);
1201 GMythStringList *str_list = gmyth_string_list_new();
1202 GString *message = g_string_new("");
1204 g_string_printf(message, "%s %d", GMYTHTV_RECORDER_HEADER,
1205 recorder->recorder_num);
1206 gmyth_string_list_append_string(str_list, message);
1207 gmyth_string_list_append_char_array(str_list, "FINISH_RECORDING");
1209 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
1211 if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
1212 GString *str = NULL;
1214 if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL &&
1215 strcmp(str->str, "ok") != 0) {
1217 gmyth_string_list_get_int(str_list, 0);
1224 g_string_free(str, TRUE);
1227 gmyth_debug("%s, stream is %s finished!\n", ret ? "YES" : "NO",
1229 // g_static_mutex_unlock (&mutex);
1231 if (str_list != NULL)
1232 g_object_unref(str_list);
1234 g_string_free(message, TRUE);
1241 * Stops playing the remote file.
1243 * @param recorder The GMythRecorder instance.
1245 * @return <code>true</code>, if the recording had been actually stopped.
1248 gmyth_recorder_stop_playing(GMythRecorder * recorder)
1250 gboolean ret = TRUE;
1252 g_return_val_if_fail(recorder != NULL, FALSE);
1254 GMythStringList *str_list = gmyth_string_list_new();
1255 GString *message = g_string_new("");
1257 g_string_printf(message, "%s %d", GMYTHTV_RECORDER_HEADER,
1258 recorder->recorder_num);
1259 gmyth_string_list_append_string(str_list, message);
1260 gmyth_string_list_append_char_array(str_list, "STOP_PLAYING");
1262 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
1264 if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
1265 GString *str = NULL;
1267 if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL &&
1268 strcmp(str->str, "ok") != 0) {
1270 gmyth_string_list_get_int(str_list, 0);
1277 g_string_free(str, TRUE);
1280 gmyth_debug("%s, stream is %s stopped!\n", ret ? "YES" : "NO",
1283 if (str_list != NULL)
1284 g_object_unref(str_list);
1286 g_string_free(message, TRUE);
1292 * Free the tuner responsible for recording this channel.
1294 * @param recorder The GMythRecorder instance.
1296 * @return <code>true</code>, if the tuner had been freed.
1299 gmyth_recorder_free_tuner(GMythRecorder * recorder)
1301 gboolean ret = TRUE;
1303 g_return_val_if_fail(recorder != NULL, FALSE);
1305 GMythStringList *str_list = gmyth_string_list_new();
1306 GString *message = g_string_new("");
1308 g_string_printf(message, "%s %d", "FREE_TUNER",
1309 recorder->recorder_num);
1310 gmyth_string_list_append_string(str_list, message);
1312 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
1314 if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
1315 GString *str = NULL;
1317 if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL &&
1318 g_ascii_strncasecmp(str->str, "ok", 2) != 0) {
1320 gmyth_string_list_get_int(str_list, 0);
1327 g_string_free(str, TRUE);
1330 gmyth_debug("%s, tuner is %s freed!\n", ret ? "YES" : "NO",
1333 if (str_list != NULL)
1334 g_object_unref(str_list);
1336 g_string_free(message, TRUE);
1342 * Asks the MythTV backend server about the frame rate
1343 * of this LiveTV instance.
1345 * @param recorder The GMythRecorder instance.
1347 * @return The framerate (double value) of the current video.
1350 gmyth_recorder_get_framerate(GMythRecorder * recorder)
1353 GString *query = g_string_new(GMYTHTV_RECORDER_HEADER);
1355 GMythStringList *str_list = gmyth_string_list_new();
1357 g_mutex_lock(recorder->mutex);
1359 g_string_append_printf(query, " %d", recorder->recorder_num);
1361 gmyth_string_list_append_string(str_list, query);
1362 gmyth_string_list_append_char_array(str_list, "GET_FRAMERATE");
1364 gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
1366 if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
1367 GString *str = NULL;
1369 if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL
1370 && strstr(str->str, "bad") == NULL)
1371 fr = g_ascii_strtod(str->str, NULL);
1373 g_string_free(str, TRUE);
1375 #ifndef GMYTHTV_ENABLE_DEBUG
1376 gmyth_debug("[%s] Got file position = %f\n", __FUNCTION__, fr);
1379 g_mutex_unlock(recorder->mutex);
1381 if (str_list != NULL)
1382 g_object_unref(str_list);
1384 g_string_free(query, TRUE);