branches/gmyth-0.1b/src/gmyth_recorder.c
author rosfran
Wed Feb 14 21:28:49 2007 +0000 (2007-02-14)
branchtrunk
changeset 360 6d5596b9eb95
permissions -rw-r--r--
[svn r362] Some fixes in the GIOWatcher clean-ups, and changed the API version number.
     1 /**
     2  * GMyth Library
     3  *
     4  * @file gmyth/gmyth_remote_encoder.c
     5  * 
     6  * @brief <p> GMythRecorder class defines functions for playing live tv.
     7  *
     8  * The remote encoder is used by gmyth_tvplayer to setup livetv. 
     9  *
    10  * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
    11  * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
    12  *
    13  *//*
    14  * 
    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.
    19  *
    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.
    24  *
    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
    28  */
    29  
    30 #ifdef HAVE_CONFIG_H
    31 #include "config.h"
    32 #endif
    33 
    34 #include "gmyth_recorder.h"
    35 
    36 #include <assert.h>
    37 
    38 #include "gmyth_stringlist.h"
    39 #include "gmyth_util.h"
    40 #include "gmyth_debug.h"
    41 
    42 #define	 GMYTHTV_RECORDER_HEADER			"QUERY_RECORDER"
    43 
    44 static void gmyth_recorder_class_init          (GMythRecorderClass *klass);
    45 static void gmyth_recorder_init                (GMythRecorder *object);
    46 
    47 static void gmyth_recorder_dispose  (GObject *object);
    48 static void gmyth_recorder_finalize (GObject *object);
    49 
    50 G_DEFINE_TYPE(GMythRecorder, gmyth_recorder, G_TYPE_OBJECT)
    51     
    52 static void
    53 gmyth_recorder_class_init (GMythRecorderClass *klass)
    54 {
    55     GObjectClass *gobject_class;
    56 
    57     gobject_class = (GObjectClass *) klass;
    58 	
    59     gobject_class->dispose  = gmyth_recorder_dispose;
    60     gobject_class->finalize = gmyth_recorder_finalize;	
    61 }
    62 
    63 static void
    64 gmyth_recorder_init (GMythRecorder *gmyth_remote_encoder)
    65 {
    66 }
    67 
    68 static void
    69 gmyth_recorder_dispose  (GObject *object)
    70 {
    71     // GMythRecorder *gmyth_remote_encoder = GMYTH_RECORDER(object);
    72     
    73 	G_OBJECT_CLASS (gmyth_recorder_parent_class)->dispose (object);
    74 }
    75 
    76 
    77 static void
    78 gmyth_recorder_finalize (GObject *object)
    79 {
    80 	g_signal_handlers_destroy (object);
    81 
    82   GMythRecorder *recorder = GMYTH_RECORDER(object);
    83 
    84 	gmyth_debug ("[%s] Closing control socket", __FUNCTION__);
    85 	gmyth_socket_close_connection(recorder->myth_socket);
    86 	g_object_unref (recorder->myth_socket);
    87     
    88   G_OBJECT_CLASS (gmyth_recorder_parent_class)->finalize (object);
    89 }
    90 
    91 /** Creates a new instance of GMythRecorder.
    92  * 
    93  * @return a new instance of GMythRecorder.
    94  */
    95 GMythRecorder*
    96 gmyth_recorder_new (int num, GString *hostname, gshort port)
    97 {
    98 	GMythRecorder *encoder = GMYTH_RECORDER ( g_object_new (
    99 			GMYTH_RECORDER_TYPE, FALSE ));
   100 			
   101 	encoder->recorder_num = num;
   102 	encoder->hostname = g_string_new (hostname->str);
   103 	encoder->port = port;
   104 	
   105 	return encoder;
   106 }
   107 
   108 /** Configures the remote encoder instance connecting it to Mythtv backend.
   109  * 
   110  * @param recorder the GMythRecorder instance.
   111  * @return TRUE if successfull, FALSE if any error happens.
   112  */
   113 gboolean
   114 gmyth_recorder_setup (GMythRecorder *recorder)
   115 {
   116 	assert (recorder);
   117 	gmyth_debug ("[%s] Creating socket and connecting to backend", __FUNCTION__);
   118 
   119 	if (recorder->myth_socket == NULL) {
   120 		
   121 		recorder->myth_socket = gmyth_socket_new ();
   122 		
   123 		if (!gmyth_socket_connect_to_backend ( recorder->myth_socket, recorder->hostname->str, 
   124 					recorder->port, TRUE ) ) {
   125 			g_warning ("GMythRemoteEncoder: Connection to backend failed");	
   126 			return FALSE;
   127 		}
   128 		
   129 	} else {
   130 		g_warning("Remote encoder socket already created\n");
   131 	}
   132 
   133 	return TRUE;
   134 }
   135 
   136 /** Sends the SPAWN_LIVETV command through Mythtv protocol. This command
   137  * requests the backend to start capturing TV content.
   138  * 
   139  * @param recorder The GMythRecorder instance.
   140  * @param tvchain_id The tvchain unique id.
   141  * @return true if success, false if any error happens.
   142  */
   143 gboolean
   144 gmyth_recorder_spawntv (GMythRecorder *recorder, GString *tvchain_id)
   145 {
   146 	GMythStringList *str_list;
   147 	GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
   148 	
   149 	gmyth_debug ("[%s] Spawntv with tvchain_id = %s", __FUNCTION__, tvchain_id->str);
   150 	
   151 	str_list = gmyth_string_list_new ();
   152 	
   153 	g_string_append_printf ( tmp_str, " %d", recorder->recorder_num ); 
   154 	
   155 	gmyth_string_list_append_string (str_list, tmp_str);
   156 	gmyth_string_list_append_string (str_list, g_string_new ("SPAWN_LIVETV"));
   157 	gmyth_string_list_append_string (str_list, tvchain_id);
   158 	gmyth_string_list_append_int (str_list, 0); // PIP = FALSE (0)
   159 
   160 	gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
   161 	
   162     g_string_free (tmp_str, TRUE);
   163     
   164     tmp_str = gmyth_string_list_get_string (str_list, 0);
   165     if (tmp_str == NULL) {
   166     	g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
   167     	return FALSE;
   168 	}
   169 	
   170     if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
   171     	g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
   172 	    g_object_unref (str_list);
   173     	return FALSE;
   174     }
   175 
   176     g_object_unref (str_list);
   177     return TRUE;
   178 
   179 }
   180 
   181 /** 
   182  * Sends the SPAWN_LIVETV command through Mythtv protocol. This command
   183  * requests the backend to start capturing TV content, but it doesn't need
   184  * the TV chain ID.
   185  * 
   186  * @param recorder The GMythRecorder instance.
   187  * @return true if success, false if any error happens.
   188  */
   189 gboolean
   190 gmyth_recorder_spawntv_no_tvchain (GMythRecorder *recorder)
   191 {
   192 	GMythStringList *str_list;
   193 	GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
   194 	
   195 	gmyth_debug ("[%s] Spawntv, no TV chain!", __FUNCTION__);
   196 	
   197 	str_list = gmyth_string_list_new ();
   198 	
   199 	g_string_append_printf ( tmp_str, " %d", recorder->recorder_num ); 
   200 	
   201 	gmyth_string_list_append_string (str_list, tmp_str);
   202 	gmyth_string_list_append_string (str_list, g_string_new ("SPAWN_LIVETV"));
   203 
   204 	gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
   205 	
   206     g_string_free (tmp_str, TRUE);
   207     
   208     tmp_str = gmyth_string_list_get_string (str_list, 0);
   209     if (tmp_str == NULL) {
   210     	g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
   211     	return FALSE;
   212 	}
   213 	
   214     if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
   215     	g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
   216 	    g_object_unref (str_list);
   217     	return FALSE;
   218     }
   219 
   220     g_object_unref (str_list);
   221     return TRUE;
   222 
   223 }
   224 
   225 /** Sends the command STOP_LIVETV to Mythtv backend.
   226  * 
   227  * @param recorder the GMythRecorder instance.
   228  * @return true if success, false if any error happens.
   229  */
   230 gboolean
   231 gmyth_recorder_stop_livetv (GMythRecorder *recorder)
   232 {
   233 	GMythStringList *str_list;
   234 	GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
   235 
   236 	gmyth_debug ("[%s]", __FUNCTION__);
   237 
   238 	str_list = gmyth_string_list_new ();
   239 
   240 	g_string_append_printf ( tmp_str, " %d", recorder->recorder_num ); 
   241 	gmyth_string_list_append_char_array( str_list, "STOP_LIVETV" );
   242 
   243 	gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
   244 
   245 	g_string_free (tmp_str, TRUE);
   246 
   247 	tmp_str = gmyth_string_list_get_string (str_list, 0);
   248 	if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
   249 		g_warning ("[%s] Stop livetv request returned %s", __FUNCTION__, tmp_str->str);
   250 		g_object_unref (str_list);
   251 		return FALSE;
   252 	}
   253 
   254 	g_object_unref (str_list);
   255 	return TRUE;
   256 
   257 }
   258 
   259 /** Sends the FRONTEND_READY command through Mythtv protocol. This command
   260  * advertises the backend to start capturing TV content.
   261  * 
   262  * @param recorder The GMythRecorder instance.
   263  * @return TRUE if success, FALSE if any error happens.
   264  */
   265 gboolean
   266 gmyth_recorder_send_frontend_ready_command (GMythRecorder *recorder)
   267 {
   268 	GMythStringList *str_list;
   269 	GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
   270 	
   271 	gmyth_debug ( "[%s] FRONTEND_READY with recorder id = %d", __FUNCTION__, recorder->recorder_num );
   272 	
   273 	str_list = gmyth_string_list_new ();
   274 	
   275 	g_string_append_printf ( tmp_str, " %d", recorder->recorder_num ); 
   276 	
   277 	gmyth_string_list_append_string (str_list, tmp_str);
   278 	gmyth_string_list_append_string (str_list, g_string_new ("FRONTEND_READY"));
   279 
   280 	gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
   281 	
   282   g_string_free (tmp_str, TRUE);
   283     
   284   tmp_str = gmyth_string_list_get_string (str_list, 0);
   285   if (tmp_str == NULL) {
   286   	g_warning ("[%s] FRONTEND_READY command request couldn't returns, reason: %s", __FUNCTION__, tmp_str->str);
   287   	return FALSE;
   288 	}
   289 	
   290   if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
   291   	g_warning ("[%s] FRONTEND_READY request returned %s", __FUNCTION__, tmp_str->str);
   292     g_object_unref (str_list);
   293   	return FALSE;
   294   }
   295 
   296   g_object_unref (str_list);
   297   return TRUE;
   298 
   299 }
   300 
   301 /** Send a CHECK_CHANNEL command request to the backend, in order to find if a 
   302  * certain channel actually exists.
   303  * 
   304  * @param recorder The GMythRecorder instance.
   305  * @param channel	 The new channel to be checked (string format).
   306  * @return true if success, false if any error happens.
   307  */
   308 gboolean
   309 gmyth_recorder_check_channel_name (GMythRecorder *recorder, gchar* channel)
   310 {
   311 	GMythStringList *str_list;
   312 	GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
   313 	
   314 	gmyth_debug ("[%s] CHECK_CHANNEL with channel = %s", __FUNCTION__, channel);
   315 	
   316 	str_list = gmyth_string_list_new ();
   317 	
   318 	g_string_append_printf ( tmp_str, " %d", recorder->recorder_num ); 
   319 	
   320 	gmyth_string_list_append_string (str_list, tmp_str);
   321 	gmyth_string_list_append_string (str_list, g_string_new ("CHECK_CHANNEL"));
   322 	gmyth_string_list_append_char_array (str_list, channel);
   323 
   324 	gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
   325 	
   326     g_string_free (tmp_str, TRUE);
   327     
   328     tmp_str = gmyth_string_list_get_string (str_list, 0);
   329     if (tmp_str == NULL) {
   330     	g_warning ("[%s] CHECK_CHANNEL request returned %s", __FUNCTION__, tmp_str->str);
   331     	return FALSE;
   332 	}
   333 	
   334     if (g_ascii_strncasecmp (tmp_str->str, "ok", 2) == 0 || g_ascii_strncasecmp (tmp_str->str, "0", 1) == 0 ) {
   335     	g_warning ("[%s] CHECK_CHANNEL request returned %s", __FUNCTION__, tmp_str->str);
   336 	    g_object_unref (str_list);
   337     	return FALSE;
   338     }
   339 
   340     g_object_unref (str_list);
   341     return TRUE;
   342 
   343 }
   344 
   345 /** Send a CHECK_CHANNEL command request to the backend, in order to find if a 
   346  * certain channel actually exists.
   347  * 
   348  * @param recorder The GMythRecorder instance.
   349  * @param channel	 The new channel to be checked (decimal integer value).
   350  * @return true if success, false if any error happens.
   351  */
   352 gboolean
   353 gmyth_recorder_check_channel (GMythRecorder *recorder, gint channel)
   354 {
   355 	return gmyth_recorder_check_channel_name( recorder, g_strdup_printf( "%d", channel ) );
   356 }
   357 
   358 /** Send a SET_CHANNEL command request to the backend, to start streaming on another 
   359  * TV content channel.
   360  * 
   361  * @param recorder The GMythRecorder instance.
   362  * @param channel	 The new channel to be loaded.
   363  * @return true if success, false if any error happens.
   364  */
   365 gboolean
   366 gmyth_recorder_set_channel (GMythRecorder *recorder, gint channel)
   367 {
   368 	GMythStringList *str_list;
   369 	GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
   370 	
   371 	gmyth_debug ("[%s] SET_CHANNEL with channel = %d", __FUNCTION__, channel);
   372 	
   373 	str_list = gmyth_string_list_new ();
   374 	
   375 	g_string_append_printf ( tmp_str, " %d", recorder->recorder_num ); 
   376 	
   377 	gmyth_string_list_append_string (str_list, tmp_str);
   378 	gmyth_string_list_append_string (str_list, g_string_new ("SET_CHANNEL"));
   379 	gmyth_string_list_append_int (str_list, channel);
   380 
   381 	gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
   382 	
   383     g_string_free (tmp_str, TRUE);
   384     
   385     tmp_str = gmyth_string_list_get_string (str_list, 0);
   386     if (tmp_str == NULL) {
   387     	g_warning ("[%s] SET_CHANNEL request returned %s", __FUNCTION__, tmp_str->str);
   388     	return FALSE;
   389 	}
   390 	
   391     if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
   392     	g_warning ("[%s] SET_CHANNEL request returned %s", __FUNCTION__, tmp_str->str);
   393 	    g_object_unref (str_list);
   394     	return FALSE;
   395     }
   396 
   397     g_object_unref (str_list);
   398     return TRUE;
   399 
   400 }
   401 
   402 /** Send a SET_CHANNEL command request to the backend, to start streaming on another 
   403  * TV content channel.
   404  * 
   405  * @param recorder The GMythRecorder instance.
   406  * @param channel	 The new channel to be loaded.
   407  * @return true if success, false if any error happens.
   408  */
   409 gboolean
   410 gmyth_recorder_set_channel_name (GMythRecorder *recorder, const gchar* channel)
   411 {
   412 	GMythStringList *str_list;
   413 	GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
   414 	
   415 	gmyth_debug ("[%s] SET_CHANNEL with channel name = %s", __FUNCTION__, channel);
   416 	
   417 	str_list = gmyth_string_list_new ();
   418 	
   419 	g_string_append_printf ( tmp_str, " %d", recorder->recorder_num ); 
   420 	
   421 	gmyth_string_list_append_string (str_list, tmp_str);
   422 	gmyth_string_list_append_string (str_list, g_string_new ("SET_CHANNEL"));
   423 	gmyth_string_list_append_char_array (str_list, channel);
   424 
   425 	gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
   426 	
   427     g_string_free (tmp_str, TRUE);
   428     
   429     tmp_str = gmyth_string_list_get_string (str_list, 0);
   430     if (tmp_str == NULL) {
   431     	g_warning ("[%s] SET_CHANNEL name request returned %s", __FUNCTION__, tmp_str->str );
   432     	return FALSE;
   433 	}
   434 	
   435     if (g_ascii_strncasecmp (tmp_str->str, "ok", 2) || g_ascii_strtoull( tmp_str->str, NULL, 10 ) == 0 ) {
   436     	g_warning ("[%s] SET_CHANNEL name request returned %s", __FUNCTION__, tmp_str->str);
   437 	    g_object_unref (str_list);
   438     	return FALSE;
   439     }
   440 
   441     g_object_unref (str_list);
   442     return TRUE;
   443 
   444 }
   445 
   446 /**
   447  * Changes the channel of the actual Recorder.
   448  * 
   449  * CHANNEL_DIRECTION_UP       - Go up one channel in the listing
   450  *
   451  * CHANNEL_DIRECTION_DOWN     - Go down one channel in the listing
   452  *
   453  * CHANNEL_DIRECTION_FAVORITE - Go to the next favorite channel
   454  *
   455  * CHANNEL_DIRECTION_SAME     - Stay
   456  * 
   457  * @param recorder 	 The GMythRecorder instance.
   458  * @param direction	 The new channel direction where to move to.
   459  * @return true if success, false if any error happens.
   460  */
   461 gboolean
   462 gmyth_recorder_change_channel (GMythRecorder *recorder, const GMythRecorderChannelChangeDirection direction)
   463 {
   464 	GMythStringList *str_list;
   465 	GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
   466 	
   467 	gmyth_debug ("[%s] CHANGE_CHANNEL to the channel direction = %u", __FUNCTION__, direction);
   468 	
   469 	str_list = gmyth_string_list_new ();
   470 	
   471 	g_string_append_printf ( tmp_str, " %d", recorder->recorder_num ); 
   472 	
   473 	gmyth_string_list_append_string (str_list, tmp_str);
   474 	gmyth_string_list_append_string (str_list, g_string_new ("CHANGE_CHANNEL"));
   475 	gmyth_string_list_append_int (str_list, direction);
   476 
   477 	gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
   478 	
   479     g_string_free (tmp_str, TRUE);
   480     
   481     tmp_str = gmyth_string_list_get_string (str_list, 0);
   482     if (tmp_str == NULL) {
   483     	g_warning ("[%s] CHANGE_CHANNEL name request returned %s", __FUNCTION__, tmp_str->str );
   484     	return FALSE;
   485 	}
   486 	
   487     if (g_ascii_strncasecmp (tmp_str->str, "ok", 2) || g_ascii_strtoull( tmp_str->str, NULL, 10 ) == 0 ) {
   488     	g_warning ("[%s] CHANGE_CHANNEL name request returned %s", __FUNCTION__, tmp_str->str);
   489 	    g_object_unref (str_list);
   490     	return FALSE;
   491     }
   492 
   493     g_object_unref (str_list);
   494     return TRUE;
   495 
   496 }
   497 
   498 /** Send a PAUSE command request to the backend, to pause streaming on another 
   499  * TV content channel.
   500  * 
   501  * @param recorder The GMythRecorder instance.
   502  * @return true if success, false if any error happens.
   503  */
   504 gboolean
   505 gmyth_recorder_pause_recording ( GMythRecorder *recorder )
   506 {
   507 	GMythStringList *str_list;
   508 	GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
   509 	
   510 	gmyth_debug ("[%s] PAUSE", __FUNCTION__);
   511 	
   512 	str_list = gmyth_string_list_new ();
   513 	
   514 	g_string_append_printf ( tmp_str, " %d", recorder->recorder_num ); 
   515 	
   516 	gmyth_string_list_append_string (str_list, tmp_str);
   517 	gmyth_string_list_append_string (str_list, g_string_new ("PAUSE"));
   518 
   519 	gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
   520 	
   521     g_string_free (tmp_str, TRUE);
   522     
   523     tmp_str = gmyth_string_list_get_string (str_list, 0);
   524     if (tmp_str == NULL) {
   525     	g_warning ("[%s] PAUSE name request returned %s", __FUNCTION__, tmp_str->str);
   526     	return FALSE;
   527 	}
   528 	
   529     if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
   530     	g_warning ("[%s] PAUSE name request returned %s", __FUNCTION__, tmp_str->str);
   531 	    g_object_unref (str_list);
   532     	return FALSE;
   533     }
   534 
   535     g_object_unref (str_list);
   536     return TRUE;
   537 
   538 }
   539 
   540 /**
   541  * Requests the actual program info from the MythTV backend server.
   542  * 
   543  * @param recorder The GMythRecorder instance.
   544  * @return The actual program info.
   545  */
   546 GMythProgramInfo *
   547 gmyth_recorder_get_current_program_info ( GMythRecorder *recorder )
   548 {
   549 	GMythStringList *str_list;
   550 	GMythProgramInfo *program_info = gmyth_program_info_new();
   551 	GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
   552 	
   553 	str_list = gmyth_string_list_new ();
   554 	
   555 	g_string_append_printf ( tmp_str, " %d", recorder->recorder_num ); 
   556 	
   557 	gmyth_string_list_append_string (str_list, tmp_str);
   558 	
   559 	if ( recorder->myth_socket->mythtv_version >= 26 )
   560 		gmyth_string_list_append_string (str_list, g_string_new ("GET_CURRENT_RECORDING"));
   561 	else
   562 		gmyth_string_list_append_string (str_list, g_string_new ("GET_PROGRAM_INFO"));
   563 
   564 	gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
   565 
   566   g_string_free (tmp_str, TRUE);
   567 
   568   if (str_list == NULL) {
   569   	g_warning ("[%s] GET_PROGRAM_INFO request returned. Error getting program info, string list equals to NULL!", __FUNCTION__);
   570   	return FALSE;
   571 	}
   572   
   573   program_info = gmyth_program_info_from_string_list( str_list );
   574 
   575   if ( NULL == program_info ) {
   576   	g_warning ("[%s] GET_PROGRAM_INFO request returned. Error getting program info, it is equals to NULL!!!", __FUNCTION__);
   577     g_object_unref (program_info);
   578   	return NULL;
   579   }
   580 
   581   g_object_unref (str_list);
   582   return program_info;
   583 
   584 }
   585 
   586 gint64
   587 gmyth_recorder_get_file_position ( GMythRecorder *recorder )
   588 {
   589   gint64 pos = 0;
   590   GString *query = g_string_new( GMYTHTV_RECORDER_HEADER );
   591 
   592   GMythStringList *str_list = gmyth_string_list_new ();
   593 
   594   g_string_append_printf( query, " %d", recorder->recorder_num );
   595 
   596   gmyth_string_list_append_string (str_list, query);
   597   gmyth_string_list_append_char_array( str_list, "GET_FILE_POSITION" );
   598 
   599   gmyth_socket_sendreceive_stringlist ( recorder->myth_socket, str_list );
   600 
   601   if ( str_list != NULL && gmyth_string_list_length(str_list) > 0 ) 
   602   {
   603     GString *str = NULL;
   604     if ( ( str = gmyth_string_list_get_string( str_list, 0 ) ) != NULL && strstr ( str->str, "bad" ) == NULL )
   605       pos = gmyth_util_decode_long_long( str_list, 0 );
   606   } 
   607 
   608 #ifndef GMYTHTV_ENABLE_DEBUG
   609   g_print( "[%s] Got file position = %lld\n", __FUNCTION__, pos );
   610 #endif
   611   if (str_list!=NULL)
   612     g_object_unref (str_list);
   613 
   614   return pos;
   615 
   616 }
   617 
   618 gboolean
   619 gmyth_recorder_is_recording ( GMythRecorder *recorder )
   620 {
   621   gboolean ret = TRUE;
   622   
   623   g_return_val_if_fail( recorder != NULL, FALSE );
   624 
   625   GMythStringList *str_list = gmyth_string_list_new ();
   626   GString *message = g_string_new ("");
   627 
   628   g_string_printf( message, "%s %d", GMYTHTV_RECORDER_HEADER, recorder->recorder_num);
   629   gmyth_string_list_append_string (str_list, message);
   630   gmyth_string_list_append_string (str_list, g_string_new ("IS_RECORDING"));
   631 
   632   gmyth_socket_sendreceive_stringlist ( recorder->myth_socket, str_list );
   633 
   634   if ( str_list != NULL && gmyth_string_list_length(str_list) > 0 )
   635   {
   636     GString *str = NULL;
   637     if ( ( str = gmyth_string_list_get_string( str_list, 0 ) ) != NULL && strcmp( str->str, "bad" )!= 0 ) 
   638     {
   639       gint is_rec = gmyth_string_list_get_int( str_list, 0 );
   640       if ( is_rec != 0 )
   641         ret = TRUE;
   642       else
   643         ret = FALSE;
   644     }
   645   }
   646   gmyth_debug( "%s, stream is %s being recorded!\n", ret ? "YES" : "NO", ret ? "" : "NOT" );
   647   //g_static_mutex_unlock (&mutex);
   648 
   649   if ( str_list != NULL )
   650     g_object_unref (str_list);
   651 
   652   return ret;
   653 
   654 }