# HG changeset patch # User rosfran # Date 1161824743 -3600 # Node ID 51fd70b817a8466eefa719fd877ef21704cd4a28 # Parent 26845a19d06e5e0bfdc5455801e719ecc36d3172 [svn r55] Fixes on the TVChain manipulation, error when trying to get the last program chain. diff -r 26845a19d06e -r 51fd70b817a8 gmyth/src/gmyth_file_transfer.c --- a/gmyth/src/gmyth_file_transfer.c Thu Oct 26 02:04:40 2006 +0100 +++ b/gmyth/src/gmyth_file_transfer.c Thu Oct 26 02:05:43 2006 +0100 @@ -24,29 +24,29 @@ #include #include -#define GMYTHTV_QUERY_HEADER "QUERY_FILETRANSFER" -#define GMYTHTV_RECORDER_HEADER "QUERY_RECORDER" +#define GMYTHTV_QUERY_HEADER "QUERY_FILETRANSFER" +#define GMYTHTV_RECORDER_HEADER "QUERY_RECORDER" /* default values to the file transfer parameters */ -#define GMYTHTV_USER_READ_AHEAD FALSE -#define GMYTHTV_RETRIES 1 -#define GMYTHTV_FILE_SIZE -1 +#define GMYTHTV_USER_READ_AHEAD FALSE +#define GMYTHTV_RETRIES 1 +#define GMYTHTV_FILE_SIZE 0 -#define GMYTHTV_BUFFER_SIZE 8*1024 +#define GMYTHTV_BUFFER_SIZE 8*1024 -#define GMYTHTV_VERSION 30 +#define GMYTHTV_VERSION 30 #define GMYTHTV_TRANSFER_MAX_WAITS 700 #ifdef GMYTHTV_ENABLE_DEBUG -#define GMYTHTV_ENABLE_DEBUG 1 +#define GMYTHTV_ENABLE_DEBUG 1 #else #undef GMYTHTV_ENABLE_DEBUG #endif /* this NDEBUG is to maintain compatibility with GMyth library */ #ifndef NDEBUG -#define GMYTHTV_ENABLE_DEBUG 1 +#define GMYTHTV_ENABLE_DEBUG 1 #endif static guint wait_to_transfer = 0; @@ -168,6 +168,8 @@ transfer->retries = GMYTHTV_RETRIES; transfer->live_tv = FALSE; + + transfer->backend_msgs = g_hash_table_new( g_int_hash, g_int_equal ); transfer->query = g_string_new( GMYTHTV_QUERY_HEADER ); g_string_append_printf ( transfer->query, " %d", transfer->recordernum ); @@ -703,6 +705,29 @@ return NULL; } +static gboolean +gmyth_file_transfer_is_backend_message( GMythFileTransfer *transfer, + GMythStringList* strlist ) +{ + gboolean found_backend_msg = FALSE; + GString *back_msg = NULL; + + back_msg = gmyth_string_list_get_string( strlist, 0 ); + if ( back_msg != NULL && back_msg->str != NULL && + strstr( back_msg->str, "BACKEND" ) != NULL ) + { + found_backend_msg = TRUE; + if ( transfer->backend_msgs != NULL ) { + + g_hash_table_insert ( transfer->backend_msgs, + &(transfer->readposition), back_msg ); + + } + } + + return found_backend_msg; + +} gint gmyth_file_transfer_read(GMythFileTransfer *transfer, void *data, gint size, gboolean read_unlimited) @@ -724,6 +749,7 @@ GMythStringList *strlist = NULL; GError *error = NULL; + gboolean found_backend_msg = FALSE; gchar *trash = g_strdup(""); @@ -819,7 +845,7 @@ //g_io_channel_flush( io_channel, NULL ); - //g_static_mutex_lock( &mutex ); + g_static_mutex_lock( &mutex ); io_cond = g_io_channel_get_buffer_condition( io_channel ); @@ -832,13 +858,57 @@ gmyth_string_list_append_char_array( strlist, /*transfer->live_tv ? "REQUEST_BLOCK_RINGBUF" :*/ "REQUEST_BLOCK" ); gmyth_string_list_append_int( strlist, remaining ); - gmyth_socket_write_stringlist( transfer->control_sock, strlist ); + gmyth_socket_write_stringlist( transfer->control_sock, strlist ); + + gint backend_msg_count = 2; + + /* iterates until find some non-MythTV backend message */ + do { + gmyth_socket_read_stringlist( transfer->control_sock, strlist ); + if ( strlist != NULL && gmyth_string_list_length( strlist ) > 0 ) + { + if ( gmyth_file_transfer_is_backend_message( transfer, strlist ) ) + { + recv = 0; + sent = 0; + response = FALSE; + found_backend_msg = TRUE; + } + else + { + sent = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error + g_print( "[%s] got SENT buffer message = %d\n", __FUNCTION__, sent ); + if ( sent != 0 ) + { + g_print( "[%s]\t received = %d bytes, backend says %d bytes sent, "\ + "io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__, + recv, sent, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" ); - guint count_bytes = 0; + if ( sent == remaining ) + { + //response = ( recv == size ); + g_print( "[%s]\t\tsent %d, which is equals to requested size = %d\n\n", + __FUNCTION__, sent, remaining ); + } + else + { + g_print( "[%s]\t\tsent %d, which is NOT equals to requested size = %d\n\n", + __FUNCTION__, sent, remaining ); + goto cleanup; + + } + } else { + break; + //goto cleanup; + } // if + } + } + } while ( found_backend_msg && --backend_msg_count > 0 ); + + guint count_bytes = 0; do { - //buf_len = ( sent - recv ) > GMYTHTV_BUFFER_SIZE ? GMYTHTV_BUFFER_SIZE : ( sent - recv ); if ( remaining > GMYTHTV_BUFFER_SIZE ) { buf_len = GMYTHTV_BUFFER_SIZE; } else { @@ -849,44 +919,39 @@ io_status = g_io_channel_read_chars( io_channel, data + recv, buf_len, &bytes_read, &error ); - - //g_static_mutex_unlock( &mutex ); + /* - GString *sss = g_string_new(""); - sss = g_string_append_len( sss, (gchar*)data+recv, bytes_read ); - - g_print( "[%s] Reading buffer (length = %d)\n", __FUNCTION__, bytes_read); - */ + GString *sss = g_string_new(""); + sss = g_string_append_len( sss, (gchar*)data+recv, bytes_read ); + + g_print( "[%s] Reading buffer (length = %d)\n", __FUNCTION__, bytes_read); + */ if ( bytes_read > 0 ) { - //if ( bytes_read <= buf_len ) - recv += bytes_read; - count_bytes += bytes_read; - remaining -= bytes_read; - g_print( "[%s] Reading buffer (bytes read = %d, remaining = %d)\n", __FUNCTION__, bytes_read, remaining ); - if ( remaining == 0 ) { - break; - } + recv += bytes_read; + count_bytes += bytes_read; + remaining -= bytes_read; + g_print( "[%s] Reading buffer (bytes read = %d, remaining = %d)\n", __FUNCTION__, bytes_read, remaining ); + /* + if ( remaining == 0 ) { + break; + } + */ } else { break; } - - //if ( remaining > 0 ) { if ( io_status == G_IO_STATUS_EOF ) { - g_print( "[%s] got EOS!", __FUNCTION__ ); - break; + g_print( "[%s] got EOS!", __FUNCTION__ ); + break; } else if ( io_status == G_IO_STATUS_ERROR ) { - g_print( "[%s] gmyth_file_transfer_read(): socket error.\n", __FUNCTION__ ); - break; + g_print( "[%s] gmyth_file_transfer_read(): socket error.\n", __FUNCTION__ ); + break; } - //} /* increase buffer size, to allow get more data (do not obey to the buffer size) */ if ( read_unlimited == TRUE ) { // FOR NOW, DO NOTHING!!! - //if ( recv > buf_len ) - // sent += (bytes_read - buf_len) + 1; } /* verify if the input (read) buffer is ready to receive data */ @@ -894,98 +959,39 @@ g_print( "[%s]\t io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" ); - - //if ( recv == size ) - //break; } while ( remaining > 0 );//&& ( io_status == G_IO_STATUS_NORMAL ) ); - // if ( ( recv < size ) ) { - // finish_read = FALSE; - //} - io_cond_control = g_io_channel_get_buffer_condition( io_channel_control ); if ( remaining == 0 )//( io_cond_control & G_IO_IN ) != 0 ) { - gmyth_socket_read_stringlist( transfer->control_sock, strlist ); - if ( strlist != NULL && gmyth_string_list_length( strlist ) > 0 ) - { - GString *back_msg = NULL; - back_msg = gmyth_string_list_get_string( strlist, 0 ); - if ( back_msg != NULL && back_msg->str != NULL && strstr( back_msg, "BACKEND" ) != NULL ) - { - recv = 0; - sent = 0; - } - else - { - sent = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error - g_print( "[%s] got SENT buffer message = %d\n", __FUNCTION__, sent ); - if ( sent != 0 ) - { - g_print( "[%s]\t received = %d bytes, backend says %d bytes sent, "\ - "io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__, - recv, sent, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" ); - - if ( sent == count_bytes ) - { - response = ( recv == size ); - g_print( "[%s]\t\tsent %d, which is equals to bytes_read = %d\n\n", - __FUNCTION__, sent, count_bytes ); - if ( response == TRUE ) - break; - } - else - { - g_print( "[%s]\t\tsent %d, which is NOT equals to bytes_read = %d\n\n", - __FUNCTION__, sent, count_bytes ); - goto cleanup; - //response = FALSE; - //break; - } - } else { - break; - //goto cleanup; - } // if - } - } // if - reading control response from backend - } else { - response = FALSE; - } // if - stringlist response + response = TRUE; + break; + } } // while io_cond_control = g_io_channel_get_buffer_condition( io_channel_control ); - // io_cond = g_io_channel_get_buffer_condition( io_channel ); - if ( ( ( io_cond_control & G_IO_IN ) != 0 ) && - //( response || ( recv == size ) ) ) - ( recv <= 0 || sent <= 0 ) ) + if ( ( ( io_cond_control & G_IO_IN ) != 0 ) /*&& + ( response || ( recv == size ) ) ) + ( recv <= 0 || sent <= 0 ) */ ) { if ( gmyth_socket_read_stringlist( transfer->control_sock, strlist ) > 0 ) { if ( strlist != NULL && gmyth_string_list_length(strlist) > 0 ) { - sent = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error - g_print( "[%s]\t received = %d bytes -\tNOW returning from reading buffer I/O socket "\ - "[%s prepared for reading]! (G_IO_IN) !!!\n\n", __FUNCTION__, - sent, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" ); + gint backend_code = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error + g_print( "[%s]\t backend code = %d -\t"\ + "[%s prepared for reading]! (G_IO_IN) !!!\n\n", __FUNCTION__, + backend_code, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" ); } } - else - { - g_printerr ( "gmyth_file_transfer_read(): No response from control socket."); - recv = -1; - } - - } - else if ( error != NULL ) - { - g_printerr( "[%s] Error occurred: (%d, %s)\n", __FUNCTION__, error->code, error->message ); } cleanup: - //g_static_mutex_unlock (&mutex); + g_static_mutex_unlock (&mutex); + g_io_channel_flush( io_channel_control, NULL ); if ( trash != NULL ) g_free( trash ); @@ -997,15 +1003,17 @@ "(rcvd and rept MUST be the same!)\n", size, recv, sent ); - //if ( ( recv != size ) || ( sent != size ) ) { - //recv = size; - //} - if ( error != NULL ) { g_printerr( "Cleaning-up ERROR: %s [msg = %s, code = %d]\n", __FUNCTION__, error->message, - error->code ); - g_error_free( error ); + error->code ); + g_error_free( error ); } + + if ( !response ) { + recv = GMYTHTV_FILE_TRANSFER_READ_ERROR; + } else { + transfer->readposition += recv; + } return recv; } diff -r 26845a19d06e -r 51fd70b817a8 gmyth/src/gmyth_file_transfer.h --- a/gmyth/src/gmyth_file_transfer.h Thu Oct 26 02:04:40 2006 +0100 +++ b/gmyth/src/gmyth_file_transfer.h Thu Oct 26 02:05:43 2006 +0100 @@ -4,6 +4,7 @@ #define __GMYTH_FILE_TRANSFER_H__ #include +#include #include "gmyth_socket.h" #include "gmyth_uri.h" @@ -25,6 +26,7 @@ #define IS_GMYTH_FILE_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TRANSFER_TYPE)) #define GMYTH_FILE_TRANSFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferClass)) +#define GMYTHTV_FILE_TRANSFER_READ_ERROR -314 typedef struct _GMythFileTransfer GMythFileTransfer; typedef struct _GMythFileTransferClass GMythFileTransferClass; @@ -52,7 +54,7 @@ GMythSocket *event_sock; GMythSocket *sock; - guint64 readposition; + gint64 readposition; guint64 filesize; gboolean timeoutisfast; gboolean userreadahead; @@ -66,6 +68,9 @@ gint card_id; GString *hostname; gint port; + + /* stores the messages coming from the backend */ + GHashTable *backend_msgs; }; GType gmyth_file_transfer_get_type (void); diff -r 26845a19d06e -r 51fd70b817a8 gmyth/src/gmyth_livetv.c --- a/gmyth/src/gmyth_livetv.c Thu Oct 26 02:04:40 2006 +0100 +++ b/gmyth/src/gmyth_livetv.c Thu Oct 26 02:05:43 2006 +0100 @@ -162,6 +162,63 @@ return res; error: + g_print( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ ); + if ( livetv->backend_hostname != NULL ) { + g_string_free( livetv->backend_hostname, TRUE ); + res = FALSE; + } + + if ( livetv->local_hostname != NULL ) { + g_string_free( livetv->local_hostname, TRUE ); + res = FALSE; + } + + if ( livetv->remote_encoder != NULL ) { + g_object_unref (livetv->remote_encoder); + livetv->remote_encoder = NULL; + } + + if ( livetv->tvchain != NULL ) { + g_object_unref (livetv->tvchain); + livetv->tvchain = NULL; + } + + if ( livetv->proginfo != NULL ) { + g_object_unref (livetv->proginfo); + livetv->proginfo = NULL; + } + + return res; + +} + +gboolean +gmyth_livetv_next_program_chain ( GMythLiveTV *livetv ) +{ + gboolean res = TRUE; + + // Reload all TV chain from Mysql database. + gmyth_tvchain_reload_all (livetv->tvchain); + + if ( livetv->tvchain == NULL ) { + res = FALSE; + goto error; + } + + // Get program info from database using chanid and starttime + livetv->proginfo = gmyth_tvchain_get_program_at (livetv->tvchain, -1 ); + if ( livetv->proginfo == NULL ) { + g_warning ("[%s] LiveTV not successfully started on the next program chain.\n", __FUNCTION__ ); + res = FALSE; + goto error; + } else { + g_debug ("[%s] GMythLiveTV: All requests to backend to start TV were OK, TV chain changed.\n", __FUNCTION__ ); + } + + return res; + +error: + g_print( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ ); if ( livetv->backend_hostname != NULL ) { g_string_free( livetv->backend_hostname, TRUE ); res = FALSE; diff -r 26845a19d06e -r 51fd70b817a8 gmyth/src/gmyth_livetv.h --- a/gmyth/src/gmyth_livetv.h Thu Oct 26 02:04:40 2006 +0100 +++ b/gmyth/src/gmyth_livetv.h Thu Oct 26 02:05:43 2006 +0100 @@ -53,6 +53,7 @@ void gmyth_livetv_stop_playing (GMythLiveTV *livetv); gboolean gmyth_livetv_setup (GMythLiveTV *livetv); +gboolean gmyth_livetv_next_program_chain ( GMythLiveTV *livetv ); #define G_END_DECLS diff -r 26845a19d06e -r 51fd70b817a8 gmyth/src/gmyth_tvchain.c --- a/gmyth/src/gmyth_tvchain.c Thu Oct 26 02:04:40 2006 +0100 +++ b/gmyth/src/gmyth_tvchain.c Thu Oct 26 02:05:43 2006 +0100 @@ -155,7 +155,8 @@ GString *stmt_str; g_static_mutex_lock( &mutex ); - + + /* gets the initial size of the TVChain entries list */ guint prev_size = g_list_length (tvchain->tvchain_list); g_debug ("[%s] chainid: %s", __FUNCTION__, tvchain->tvchain_id->str); @@ -199,6 +200,12 @@ entry->inputname = g_string_new (msql_row[8]); //m_maxpos = query.value(4).toInt() + 1; + g_print( "[%s] Reading TV chain entry: [%s, %s, %s]\n", __FUNCTION__, entry->chanid->str, + (gchar*)msql_row[1], (gchar*)msql_row[2] ); + + /* add this to get the actual start timestamp of the last recording */ + if ( tvchain->cur_startts < entry->starttime ) + tvchain->cur_startts = entry->starttime; tvchain->tvchain_list = g_list_append (tvchain->tvchain_list, entry); } @@ -213,6 +220,7 @@ g_static_mutex_unlock( &mutex ); tvchain->cur_pos = gmyth_tvchain_program_is_at (tvchain, tvchain->cur_chanid, tvchain->cur_startts); + g_print( "[%s] TVChain current position = %d.\n", __FUNCTION__, tvchain->cur_pos ); if (tvchain->cur_pos < 0) tvchain->cur_pos = 0; @@ -250,10 +258,11 @@ int count = 0; struct LiveTVChainEntry *entry; GList *tmp_list = tvchain->tvchain_list; + guint list_size = g_list_length (tvchain->tvchain_list); g_static_mutex_lock( &mutex ); - for (; tmp_list; tmp_list = tvchain->tvchain_list->next, ++count) + for (; tmp_list && ( count < list_size ); tmp_list = tvchain->tvchain_list->next, count++) { entry = (struct LiveTVChainEntry*) tmp_list->data; if (!g_strncasecmp (entry->chanid->str, chanid->str, chanid->len)