[svn r53] LiveTV working fine, adjustments in some GMyth functions dealing with the TVChain. trunk
authorrosfran
Thu Oct 26 01:48:46 2006 +0100 (2006-10-26)
branchtrunk
changeset 5267e72eadeef2
parent 51 3e490ac963ce
child 53 26845a19d06e
[svn r53] LiveTV working fine, adjustments in some GMyth functions dealing with the TVChain.
gst-plugins-mythtv/src/gstmythtvsrc.c
gst-plugins-mythtv/src/gstmythtvsrc.h
     1.1 --- a/gst-plugins-mythtv/src/gstmythtvsrc.c	Wed Oct 25 00:26:33 2006 +0100
     1.2 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.c	Thu Oct 26 01:48:46 2006 +0100
     1.3 @@ -18,8 +18,8 @@
     1.4  #endif
     1.5  
     1.6  #include "gstmythtvsrc.h"
     1.7 -#include "gmyth_file_transfer.h"
     1.8 -#include "gmyth_livetv.h"
     1.9 +#include <gmyth/gmyth_file_transfer.h>
    1.10 +#include <gmyth/gmyth_livetv.h>
    1.11  
    1.12  #include <gmyth/gmyth_socket.h>
    1.13  #include <gmyth/gmyth_tvchain.h>
    1.14 @@ -32,19 +32,17 @@
    1.15  
    1.16  #define GST_GMYTHTV_ID_NUM		1
    1.17  
    1.18 -#define GMYTHTV_VERSION_DEFAULT		30
    1.19 +#define GMYTHTV_VERSION_DEFAULT			30
    1.20  
    1.21  #define GMYTHTV_TRANSFER_MAX_WAITS	100
    1.22  
    1.23 -#define GMYTHTV_TRANSFER_MAX_BUFFER	1024*1024
    1.24 +#define GMYTHTV_TRANSFER_MAX_BUFFER	16*1024
    1.25  //( 32*1024  )
    1.26  
    1.27  /* 4*1024 ??? */
    1.28  #define MAX_READ_SIZE              	12*1024
    1.29  //( 32*1024 )
    1.30  
    1.31 -#define ENABLE_TIMING_POSITION		0
    1.32 -
    1.33  /* stablish a maximum iteration value to the IS_RECORDING message */
    1.34  static guint wait_to_transfer = 0;
    1.35  
    1.36 @@ -58,9 +56,6 @@
    1.37      GST_PAD_SRC,
    1.38      GST_PAD_ALWAYS,
    1.39      GST_STATIC_CAPS ("video/x-nuv") );
    1.40 -    //GST_STATIC_CAPS_ANY);
    1.41 -
    1.42 -static GThread *update_size_task = NULL;
    1.43  
    1.44  static GStaticMutex update_size_mutex = G_STATIC_MUTEX_INIT;
    1.45  
    1.46 @@ -75,27 +70,30 @@
    1.47    PROP_GMYTHTV_VERSION,
    1.48    PROP_GMYTHTV_LIVE,
    1.49    PROP_GMYTHTV_LIVEID,
    1.50 -  PROP_GMYTHTV_LIVE_CHAINID
    1.51 +  PROP_GMYTHTV_LIVE_CHAINID,
    1.52 +  PROP_GMYTHTV_ENABLE_TIMING_POSITION
    1.53  };
    1.54  
    1.55  static void gst_mythtv_src_finalize (GObject * gobject);
    1.56  
    1.57  static GstFlowReturn gst_mythtv_src_create (GstBaseSrc * psrc, guint64 offset, 
    1.58  	guint size, GstBuffer ** outbuf);
    1.59 -//static GstFlowReturn gst_mythtv_src_create (GstPushSrc * psrc, GstBuffer ** outbuf);
    1.60 +
    1.61  static gboolean gst_mythtv_src_start (GstBaseSrc * bsrc);
    1.62  static gboolean gst_mythtv_src_stop (GstBaseSrc * bsrc);
    1.63  static gboolean gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size);
    1.64  static gboolean gst_mythtv_src_is_seekable( GstBaseSrc *push_src );
    1.65 -//static gboolean gst_mythtv_new_segment ( GstBaseSrc * psrc );
    1.66 +
    1.67 +static gboolean gst_mythtv_src_next_program_chain ( GstMythtvSrc *src );
    1.68 +
    1.69 +static GstStateChangeReturn
    1.70 +gst_mythtv_src_change_state (GstElement * element, GstStateChange transition);
    1.71  
    1.72  static void gst_mythtv_src_set_property (GObject * object, guint prop_id,
    1.73      const GValue * value, GParamSpec * pspec);
    1.74  static void gst_mythtv_src_get_property (GObject * object, guint prop_id,
    1.75      GValue * value, GParamSpec * pspec);
    1.76  
    1.77 -//static GstFlowReturn gst_mythtv_src_chain (GstPad * pad, GstBuffer * buf);
    1.78 -
    1.79  static void gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
    1.80  
    1.81  static gboolean gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event);
    1.82 @@ -105,7 +103,7 @@
    1.83  		guint size, GstBuffer **outbuf);
    1.84  //static gboolean gst_mythtv_src_sink_activate_pull (GstPad * srcpad, gboolean active);
    1.85  
    1.86 -  static void
    1.87 +static void
    1.88  _urihandler_init (GType type)
    1.89  {
    1.90    static const GInterfaceInfo urihandler_info = {
    1.91 @@ -135,6 +133,8 @@
    1.92        gst_static_pad_template_get (&srctemplate));
    1.93  
    1.94    gst_element_class_set_details (element_class, &gst_mythtv_src_details);
    1.95 +  
    1.96 +  element_class->change_state = gst_mythtv_src_change_state;
    1.97  }
    1.98  
    1.99  static void
   1.100 @@ -146,7 +146,6 @@
   1.101  
   1.102    gobject_class = (GObjectClass *) klass;
   1.103    gstbasesrc_class = (GstBaseSrcClass *) klass;
   1.104 -  //gstpushsrc_class = (GstPushSrcClass *) klass;
   1.105  
   1.106    gobject_class->set_property = gst_mythtv_src_set_property;
   1.107    gobject_class->get_property = gst_mythtv_src_get_property;
   1.108 @@ -191,6 +190,12 @@
   1.109         "Enable MythTV Live TV content streaming",
   1.110         FALSE, G_PARAM_READWRITE));
   1.111  
   1.112 +  g_object_class_install_property
   1.113 +    (gobject_class, PROP_GMYTHTV_ENABLE_TIMING_POSITION,
   1.114 +     g_param_spec_boolean ("mythtv-enable-timing-position", "mythtv-enable-timing-position",
   1.115 +       "Enable MythTV Live TV content size continuous updating",
   1.116 +       FALSE, G_PARAM_READWRITE));
   1.117 +
   1.118  #ifndef GST_DISABLE_GST_DEBUG
   1.119    g_object_class_install_property
   1.120      (gobject_class, PROP_GMYTHTV_DBG,
   1.121 @@ -203,10 +208,9 @@
   1.122    gstbasesrc_class->stop = gst_mythtv_src_stop;
   1.123    gstbasesrc_class->get_size = gst_mythtv_src_get_size;
   1.124    gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable;
   1.125 -  //gstpushsrc_class->newsegment = gst_mythtv_src_new_segment;
   1.126  
   1.127    gstbasesrc_class->create = gst_mythtv_src_create;
   1.128 -  
   1.129 +    
   1.130    GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0,
   1.131        "MythTV Client Source");
   1.132  }
   1.133 @@ -222,29 +226,30 @@
   1.134  
   1.135    this->bytes_read = 0;
   1.136  
   1.137 -  this->content_size = -1;
   1.138 +  this->content_size = 0;
   1.139    this->read_offset = 0;
   1.140  
   1.141    this->live_tv = FALSE;
   1.142 +  
   1.143 +  this->enable_timing_position = FALSE;
   1.144 +  this->update_prog_chain = FALSE;    
   1.145  
   1.146    this->user_agent = g_strdup ("mythtvsrc");
   1.147 -  this->mythtv_caps = NULL;  
   1.148 +  this->mythtv_caps = NULL;
   1.149 +  this->update_prog_chain = FALSE;
   1.150 +  
   1.151 +  this->eos = FALSE;
   1.152    
   1.153    gst_base_src_set_format( GST_BASE_SRC( this ), GST_FORMAT_BYTES );  
   1.154  
   1.155    gst_base_src_set_live ( GST_BASE_SRC( this ), TRUE );
   1.156  
   1.157 -  //gst_pad_set_chain_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
   1.158 -  //    gst_mythtv_src_chain );
   1.159 -
   1.160    gst_pad_set_event_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
   1.161        gst_mythtv_src_handle_event );
   1.162  /*
   1.163    gst_pad_set_query_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
   1.164        gst_mythtv_src_query );
   1.165  */
   1.166 -  //gst_pad_set_activatepull_function( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
   1.167 -  //    gst_mythtv_src_sink_activate_pull );
   1.168  
   1.169  }
   1.170  
   1.171 @@ -253,8 +258,6 @@
   1.172  {
   1.173    GstMythtvSrc *this = GST_MYTHTV_SRC (gobject);
   1.174  
   1.175 -  g_free (this->user_agent);
   1.176 -
   1.177    if (this->mythtv_caps) {
   1.178      gst_caps_unref (this->mythtv_caps);
   1.179      this->mythtv_caps = NULL;
   1.180 @@ -265,6 +268,11 @@
   1.181      this->file_transfer = NULL;
   1.182    }
   1.183  
   1.184 +	if (this->spawn_livetv) {
   1.185 +    //g_object_unref (this->spawn_livetv);
   1.186 +    this->spawn_livetv = NULL;
   1.187 +  }
   1.188 +
   1.189    if (this->uri_name) {
   1.190      g_free (this->uri_name);
   1.191    }
   1.192 @@ -280,8 +288,7 @@
   1.193  do_read_request_response (GstMythtvSrc * src, guint64 offset, guint size, GstBuffer **outbuf)
   1.194  {
   1.195    gint read = 0;
   1.196 -  guint sizetoread = size; //GST_BUFFER_SIZE (outbuf);
   1.197 -  //GstBuffer *buffer = gst_buffer_new_and_alloc( size ); 
   1.198 +  guint sizetoread = size;
   1.199  
   1.200    g_print( "Starting: [%s] Reading %d bytes...\n", __FUNCTION__, sizetoread ); 
   1.201  
   1.202 @@ -299,43 +306,53 @@
   1.203      if ( len > 0 ) {
   1.204        read += len;      
   1.205        sizetoread -= len;
   1.206 -    } else if ( len <= 0 ) {
   1.207 +    } 
   1.208 +    else if ( len <= 0 ) 
   1.209 +    {
   1.210      	
   1.211 -      if ( src->live_tv == FALSE ) {
   1.212 -		goto done;
   1.213 -      } else if ( len == 0 ) {
   1.214 -      	src->update_prog_chain = TRUE;
   1.215 -      	goto done;
   1.216 -      } else if ( /*src->content_size >= src->read_offset && 
   1.217 -      			abs ( src->content_size - src->read_offset ) <= 1024 ) ||*/
   1.218 -      			( src->content_size <= ( src->read_offset + size + GMYTHTV_TRANSFER_MAX_BUFFER ) ) )
   1.219 -  {
   1.220 -#if ENABLE_TIMING_POSITION == 1
   1.221 -    gint64 size_tmp = 0;
   1.222 -    if (src->live_tv == TRUE) {
   1.223 -get_file_pos:
   1.224 -      size_tmp = gmyth_file_transfer_get_file_position( src->file_transfer );
   1.225 -      if ( size_tmp > ( src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER ) )
   1.226 -	src->content_size = size_tmp;
   1.227 -      else if ( size_tmp > 0 )
   1.228 -	goto get_file_pos;
   1.229 -      g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
   1.230 -	  __FUNCTION__, size_tmp );
   1.231 -    }
   1.232 -#else
   1.233 -  	gint64 new_offset = gmyth_file_transfer_get_file_position( src->file_transfer );
   1.234 -	if ( new_offset > 0 ) {
   1.235 -	  if ( src->content_size < new_offset ) {
   1.236 -	    src->content_size = new_offset;
   1.237 -	  }
   1.238 -	} else {
   1.239 -	  src->update_prog_chain = TRUE;
   1.240 -	}
   1.241 -#endif
   1.242 -	goto done;
   1.243 -  }
   1.244 +      if ( src->live_tv == FALSE ) 
   1.245 +      {
   1.246 +				goto done;
   1.247 +      } 
   1.248 +      else  
   1.249 +      {
   1.250 +      	if ( len == GMYTHTV_FILE_TRANSFER_READ_ERROR ) { /* -314 */
   1.251 +	      	src->update_prog_chain = TRUE;
   1.252 +	      	if ( gst_mythtv_src_next_program_chain ( src ) )
   1.253 +	      		continue;
   1.254 +	      	else
   1.255 +	      		goto done;
   1.256 +	      } else 
   1.257 +	      	if ( src->content_size <= 
   1.258 +	      					( src->read_offset + size + GMYTHTV_TRANSFER_MAX_BUFFER ) ) {
   1.259 +	      		src->update_prog_chain = TRUE;
   1.260 +						if ( src->enable_timing_position ) {
   1.261 +						    gint64 size_tmp = 0;
   1.262 +						    if (src->live_tv == TRUE) {
   1.263 +						get_file_pos:
   1.264 +						      size_tmp = gmyth_file_transfer_get_file_position( src->file_transfer );
   1.265 +						      if ( size_tmp > ( src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER ) )
   1.266 +										src->content_size = size_tmp;
   1.267 +						      else if ( size_tmp > 0 )
   1.268 +							goto get_file_pos;
   1.269 +						      g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
   1.270 +							  __FUNCTION__, size_tmp );
   1.271 +						    }
   1.272 +						} else {
   1.273 +						  	gint64 new_offset = gmyth_file_transfer_get_file_position( src->file_transfer );
   1.274 +								if ( new_offset > 0 ) {
   1.275 +								  if ( src->content_size < new_offset ) {
   1.276 +								    src->content_size = new_offset;
   1.277 +								  }
   1.278 +								} else {
   1.279 +								  src->update_prog_chain = TRUE;
   1.280 +								}
   1.281 +						}
   1.282 +						goto done;
   1.283 +		  		}
   1.284 +	      }
   1.285  
   1.286 -    }
   1.287 +  	}
   1.288      
   1.289      if ( read == sizetoread )
   1.290        break;
   1.291 @@ -349,11 +366,9 @@
   1.292        "OFFSET = %llu, CONTENT SIZE = %llu.\n", __FUNCTION__, read, src->bytes_read, 
   1.293        src->read_offset, src->content_size );
   1.294        
   1.295 -  //GST_BUFFER_TIMESTAMP( buffer ) = GST_BUFFER_TIMESTAMP ( *outbuf );
   1.296    GST_BUFFER_SIZE (*outbuf) = read; //GST_BUFFER_SIZE (buffer) = read;
   1.297    GST_BUFFER_OFFSET (*outbuf) = offset; //GST_BUFFER_OFFSET (buffer) = offset;
   1.298    GST_BUFFER_OFFSET_END (*outbuf) = offset + read;//GST_BUFFER_OFFSET_END (buffer) = offset + read;
   1.299 -  //memcpy( GST_BUFFER_DATA( *outbuf ), GST_BUFFER_DATA( buffer ), read );
   1.300       
   1.301    g_print( "Stopping: [%s]\t\tBUFFER --->SIZE = %d, OFFSET = %llu, "\
   1.302        "OFFSET_END = %llu.\n\n", __FUNCTION__, GST_BUFFER_SIZE (*outbuf), 
   1.303 @@ -387,7 +402,7 @@
   1.304    if ( G_UNLIKELY (src->update_prog_chain) )
   1.305      goto change_progchain;
   1.306    
   1.307 -  //GST_OBJECT_LOCK(src);
   1.308 +  GST_OBJECT_LOCK(src);
   1.309  
   1.310    if (G_UNLIKELY (src->read_offset != offset)) {
   1.311      gint64 new_offset = gmyth_file_transfer_seek(src->file_transfer, offset, SEEK_SET);
   1.312 @@ -395,13 +410,16 @@
   1.313      	__FUNCTION__, src->read_offset, new_offset );
   1.314      if (G_UNLIKELY (new_offset < 0 ) )//|| new_offset != src->read_offset)) {
   1.315      {
   1.316 -      //GST_OBJECT_UNLOCK(src);
   1.317 -      goto change_progchain;
   1.318 +      GST_OBJECT_UNLOCK(src);
   1.319 +      if ( src->live_tv )
   1.320 +      	goto change_progchain;
   1.321 +      else
   1.322 +      	goto eos;
   1.323      }
   1.324  
   1.325      src->read_offset = offset;
   1.326    }
   1.327 -  //GST_OBJECT_UNLOCK(src);
   1.328 +  GST_OBJECT_UNLOCK(src);
   1.329    
   1.330    /* Create the buffer. */
   1.331    ret = gst_pad_alloc_buffer (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
   1.332 @@ -419,20 +437,13 @@
   1.333    if (G_UNLIKELY (src->update_prog_chain) )
   1.334      goto change_progchain;
   1.335  
   1.336 -  if (G_UNLIKELY (read < 0) || *outbuf == NULL) {
   1.337 -  	//if ( src->live_tv )
   1.338 -    //	goto done;
   1.339 -    //else
   1.340 -    goto read_error;
   1.341 +  if (G_UNLIKELY (read <= 0) || *outbuf == NULL) {
   1.342 +  	if ( src->live_tv )
   1.343 +    	goto change_progchain;
   1.344 +    else
   1.345 +    	goto read_error;
   1.346    }
   1.347  
   1.348 -/* 
   1.349 -  if (G_UNLIKELY(src->eos))
   1.350 -    goto eos;
   1.351 -  else
   1.352 -    goto done;
   1.353 -*/
   1.354 -
   1.355  done:
   1.356   {
   1.357      const gchar *reason = gst_flow_get_name (ret);
   1.358 @@ -458,13 +469,13 @@
   1.359  change_progchain:
   1.360    {
   1.361      GST_ELEMENT_ERROR (src, RESOURCE, READ,
   1.362 -	(NULL), ("Seek failed, go to the next program info... (%i, %s)", read,
   1.363 -	  src->uri_name));
   1.364 -	// go to the next program chain
   1.365 -	src->unique_setup = FALSE;
   1.366 -	gst_mythtv_src_start( psrc );
   1.367 -  
   1.368 -    return GST_FLOW_OK;
   1.369 +		(NULL), ("Seek failed, go to the next program info... (%i, %s)", read,
   1.370 +		  src->uri_name));
   1.371 +		// go to the next program chain
   1.372 +		src->unique_setup = FALSE;
   1.373 +		src->update_prog_chain = TRUE;
   1.374 +		gst_mythtv_src_next_program_chain( src );  
   1.375 +    return -101;
   1.376    }
   1.377  
   1.378  }
   1.379 @@ -481,46 +492,42 @@
   1.380    g_static_mutex_lock( &update_size_mutex );
   1.381  
   1.382    if ( src->do_start ) {
   1.383 -#if ENABLE_TIMING_POSITION == 1
   1.384 -    gint64 size_tmp = 0;
   1.385 -    if (src->live_tv == TRUE) {
   1.386 -get_file_pos:
   1.387 -      g_usleep( 50 );
   1.388 -      size_tmp = gmyth_file_transfer_get_file_position( src->file_transfer );
   1.389 -      if ( size_tmp > ( src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER ) )
   1.390 -	src->content_size = size_tmp;
   1.391 -      else if ( size_tmp > 0 )
   1.392 -	goto get_file_pos;
   1.393 -      g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
   1.394 -	  __FUNCTION__, size_tmp );
   1.395 -    }
   1.396 -#endif
   1.397 +	if ( src->enable_timing_position ) {
   1.398 +	    gint64 size_tmp = 0;
   1.399 +	    if (src->live_tv == TRUE) {
   1.400 +	get_file_pos:
   1.401 +	      g_usleep( 50 );
   1.402 +	      size_tmp = gmyth_file_transfer_get_file_position( src->file_transfer );
   1.403 +	      if ( size_tmp > ( src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER ) )
   1.404 +		src->content_size = size_tmp;
   1.405 +	      else if ( size_tmp > 0 )
   1.406 +		goto get_file_pos;
   1.407 +	      g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
   1.408 +		  __FUNCTION__, size_tmp );
   1.409 +	    }
   1.410 +	}
   1.411    }
   1.412    g_static_mutex_unlock( &update_size_mutex );
   1.413  
   1.414  }
   1.415  
   1.416 -guint64
   1.417 +gint64
   1.418  gst_mythtv_src_get_position ( GstMythtvSrc* src ) 
   1.419  {
   1.420  
   1.421 -  if ( src->do_start ) {
   1.422 -#if ENABLE_TIMING_POSITION == 1
   1.423 -    gint64 size_tmp = 0;
   1.424 -    if (src->live_tv == TRUE) {
   1.425 +  gint64 size_tmp = 0;
   1.426 +  if (src->live_tv == TRUE) {
   1.427  get_file_pos:
   1.428 -      g_usleep( 50 );
   1.429 -      size_tmp = gmyth_file_transfer_get_file_position( src->file_transfer );
   1.430 -      if ( size_tmp > ( src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER ) )
   1.431 -		src->content_size = size_tmp;
   1.432 -      else if ( size_tmp > 0 )
   1.433 -	goto get_file_pos;
   1.434 -      g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
   1.435 -	  __FUNCTION__, size_tmp );
   1.436 -    }
   1.437 -#endif
   1.438 +    g_usleep( 50 );
   1.439 +    size_tmp = gmyth_file_transfer_get_file_position( src->file_transfer );
   1.440 +    if ( size_tmp > ( src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER ) )
   1.441 +			src->content_size = size_tmp;
   1.442 +    else if ( size_tmp > 0 )
   1.443 +			goto get_file_pos;
   1.444 +    g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
   1.445 +  __FUNCTION__, size_tmp );
   1.446    }
   1.447 -  
   1.448 +
   1.449    return src->content_size;	
   1.450  
   1.451  }
   1.452 @@ -534,6 +541,9 @@
   1.453    GString *chain_id_local = NULL;
   1.454  
   1.455    gboolean ret = TRUE;
   1.456 +  
   1.457 +  if ( !src->do_start )
   1.458 +  	goto done;
   1.459  
   1.460    if (src->unique_setup == FALSE) {
   1.461      src->unique_setup = TRUE;
   1.462 @@ -547,8 +557,10 @@
   1.463      src->spawn_livetv = gmyth_livetv_new( );
   1.464      if ( gmyth_livetv_setup( src->spawn_livetv ) == FALSE ) {
   1.465        ret = FALSE;
   1.466 +      GST_OBJECT_UNLOCK( src );
   1.467        goto init_failed;
   1.468      }
   1.469 +
   1.470      /* set up the uri variable */
   1.471      src->uri_name = g_strdup( src->spawn_livetv->proginfo->pathname->str );
   1.472      chain_id_local = gmyth_tvchain_get_id( src->spawn_livetv->tvchain );
   1.473 @@ -596,14 +608,8 @@
   1.474    src->content_size = src->file_transfer->filesize;
   1.475  
   1.476    GST_OBJECT_UNLOCK(src);
   1.477 -  if ( src->live_tv ) {
   1.478  
   1.479 -    //GError* error;
   1.480 -    //update_size_task = g_thread_create( (GThreadFunc)update_size_func, src, FALSE, &error );
   1.481 -    g_print( "[%s] Update Size task = %s\n", __FUNCTION__, update_size_task != NULL ?  "OK !" : "ERROR!!!" );
   1.482 -
   1.483 -  }
   1.484 -  src->do_start = TRUE;  
   1.485 +  src->do_start = FALSE;
   1.486  
   1.487  done:
   1.488    return TRUE;
   1.489 @@ -626,6 +632,109 @@
   1.490    }
   1.491  }
   1.492  
   1.493 +/* create a new socket for connecting to the next program chain */
   1.494 +static gboolean
   1.495 +gst_mythtv_src_next_program_chain ( GstMythtvSrc *src )
   1.496 +{
   1.497 +  GString *chain_id_local = NULL;
   1.498 +
   1.499 +  gboolean ret = TRUE;
   1.500 +  
   1.501 +  if ( !src->live_tv )
   1.502 +  	goto init_failed;
   1.503 +  
   1.504 +  if (src->file_transfer) {
   1.505 +    g_object_unref (src->file_transfer);
   1.506 +    src->file_transfer = NULL;
   1.507 +  }
   1.508 +  
   1.509 +  if (src->uri_name) {
   1.510 +    g_free (src->uri_name);
   1.511 +  }
   1.512 +  
   1.513 +  if ( src->live_tv ) {
   1.514 +  	if ( src->update_prog_chain )
   1.515 +  	{
   1.516 +    	if ( gmyth_livetv_next_program_chain( src->spawn_livetv ) == FALSE ) {
   1.517 +	      ret = FALSE;
   1.518 +	      goto init_failed;
   1.519 +    	}
   1.520 +    	src->update_prog_chain = FALSE;
   1.521 +    }
   1.522 +    /* set up the uri variable */
   1.523 +    src->uri_name = g_strdup( src->spawn_livetv->proginfo->pathname->str );
   1.524 +    chain_id_local = gmyth_tvchain_get_id( src->spawn_livetv->tvchain );
   1.525 +    if ( chain_id_local != NULL ) {
   1.526 +      src->live_chain_id = g_strdup( chain_id_local->str );
   1.527 +      g_print( "\t[%s]\tLocal chain ID = %s.\n", __FUNCTION__, src->live_chain_id );
   1.528 +    }
   1.529 +    src->live_tv_id = src->spawn_livetv->remote_encoder->recorder_num;
   1.530 +    g_print ( "[%s] LiveTV id = %d, URI path = %s.\n", __FUNCTION__, src->live_tv_id, src->uri_name );
   1.531 +  }
   1.532 +
   1.533 +  src->file_transfer = gmyth_file_transfer_new( src->live_tv_id, 
   1.534 +      g_string_new( src->uri_name ), -1, src->mythtv_version );
   1.535 +
   1.536 +  if ( src->file_transfer == NULL ) {
   1.537 +    goto init_failed;
   1.538 +  }
   1.539 +
   1.540 +  /* sets the Playback monitor connection */
   1.541 +  ret = gmyth_file_transfer_playback_setup( &(src->file_transfer), src->live_tv );
   1.542 +
   1.543 +  if ( src->live_tv == TRUE && ret == TRUE ) {
   1.544 +    /* loop finished, set the max tries variable to zero again... */
   1.545 +    wait_to_transfer = 0;
   1.546 +    
   1.547 +    g_usleep( 500 );
   1.548 +
   1.549 +    while ( wait_to_transfer++ < GMYTHTV_TRANSFER_MAX_WAITS && 
   1.550 +    		( gmyth_file_transfer_is_recording( src->file_transfer ) == FALSE ) )
   1.551 +      		g_usleep( 100 );
   1.552 +  }
   1.553 +
   1.554 +  /* sets the FileTransfer instance connection (video/audio download) */
   1.555 +  ret = gmyth_file_transfer_setup( &(src->file_transfer), src->live_tv );
   1.556 +
   1.557 +  if ( ret == FALSE ) {
   1.558 +#ifndef GST_DISABLE_GST_DEBUG  
   1.559 +    if ( src->mythtv_msgs_dbg )
   1.560 +      g_printerr( "MythTV FileTransfer request failed when setting up socket connection!\n" );  	  
   1.561 +#endif
   1.562 +    goto begin_req_failed;
   1.563 +  }
   1.564 +  
   1.565 +  if ( src->content_size < src->file_transfer->filesize ) {
   1.566 +  	src->content_size = src->file_transfer->filesize;
   1.567 +  } else {
   1.568 +  	gint64 pos = gst_mythtv_src_get_position(src);
   1.569 +  	if ( pos > src->file_transfer->filesize )
   1.570 +  		src->content_size = pos;  	
   1.571 +  }
   1.572 +  
   1.573 +  src->update_prog_chain = FALSE;
   1.574 +
   1.575 +  return TRUE;
   1.576 +
   1.577 +  /* ERRORS */
   1.578 +init_failed:
   1.579 +  {
   1.580 +    if (src->spawn_livetv != NULL )
   1.581 +      g_object_unref( src->spawn_livetv );
   1.582 +
   1.583 +    GST_ELEMENT_ERROR (src, LIBRARY, INIT,
   1.584 +	(NULL), ("Could not initialize MythTV library (%i, %s)", ret, src->uri_name));
   1.585 +    return FALSE;
   1.586 +  }
   1.587 +begin_req_failed:
   1.588 +  {
   1.589 +    GST_ELEMENT_ERROR (src, LIBRARY, INIT,
   1.590 +	(NULL), ("Could not begin request sent to MythTV server (%i, %s)", ret, src->uri_name));
   1.591 +    return FALSE;
   1.592 +  }
   1.593 +  
   1.594 +}
   1.595 +
   1.596  #if 0
   1.597  /* handles queries for location in the stream in the requested format */
   1.598  static gboolean
   1.599 @@ -703,40 +812,39 @@
   1.600    if (src->content_size <= 0) {
   1.601      ret= FALSE;
   1.602    } else if ( abs ( src->content_size - src->read_offset ) <= GMYTHTV_TRANSFER_MAX_BUFFER ) {
   1.603 -    //g_static_mutex_lock( &update_size_mutex );
   1.604 -    GST_OBJECT_LOCK(src);
   1.605 +  //g_static_mutex_lock( &update_size_mutex );
   1.606 +  //GST_OBJECT_LOCK(src);
   1.607  
   1.608 -  	gint64 new_offset = gmyth_file_transfer_get_file_position( src->file_transfer );
   1.609 +	gint64 new_offset = gmyth_file_transfer_get_file_position( src->file_transfer );
   1.610  	if ( new_offset > 0 ) {
   1.611  	  if ( src->content_size < new_offset ) {
   1.612  	    src->content_size = new_offset;
   1.613  	  }
   1.614  	} else {
   1.615 -	  src->update_prog_chain = TRUE;
   1.616 -	  src->content_size = 0;
   1.617 +		if ( src->live_tv )
   1.618 +			src->update_prog_chain = TRUE;
   1.619  	}
   1.620   
   1.621 -#if ENABLE_TIMING_POSITION == 1
   1.622 -    gint64 size_tmp = 0;
   1.623 -    if (src->live_tv == TRUE) {
   1.624 -get_file_pos:
   1.625 -      g_usleep( 5 );
   1.626 -      size_tmp = gmyth_file_transfer_get_file_position( src->file_transfer );
   1.627 -      if ( size_tmp > ( src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER ) )
   1.628 -	src->content_size = size_tmp;
   1.629 -      else if ( size_tmp > 0  )
   1.630 -	goto get_file_pos;
   1.631 -      g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
   1.632 -	  __FUNCTION__, size_tmp );
   1.633 -    }
   1.634 -#endif
   1.635 -	GST_OBJECT_UNLOCK(src);
   1.636 -    //g_static_mutex_unlock( &update_size_mutex );
   1.637 -
   1.638 +	if ( src->enable_timing_position ) {
   1.639 +	    gint64 size_tmp = 0;
   1.640 +	    if (src->live_tv == TRUE) {
   1.641 +	get_file_pos:
   1.642 +	      g_usleep( 5 );
   1.643 +	      size_tmp = gmyth_file_transfer_get_file_position( src->file_transfer );
   1.644 +	      if ( size_tmp > ( src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER ) )
   1.645 +					src->content_size = size_tmp;
   1.646 +	      else if ( size_tmp > 0  )
   1.647 +					goto get_file_pos;
   1.648 +	      g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
   1.649 +		  __FUNCTION__, size_tmp );
   1.650 +	    }
   1.651 +	}
   1.652 +	//GST_OBJECT_UNLOCK(src);
   1.653 +  //g_static_mutex_unlock( &update_size_mutex );
   1.654    }
   1.655  
   1.656    *size = src->content_size;
   1.657 -  g_print( "[%s] Content size = %llu\n", __FUNCTION__, src->content_size );
   1.658 +  g_print( "[%s] Content size = %lld\n", __FUNCTION__, src->content_size );
   1.659  
   1.660    return ret;
   1.661  
   1.662 @@ -744,7 +852,7 @@
   1.663  
   1.664  /* close the socket and associated resources
   1.665   * used both to recover from errors and go to NULL state */
   1.666 -  static gboolean
   1.667 +static gboolean
   1.668  gst_mythtv_src_stop (GstBaseSrc * bsrc)
   1.669  {
   1.670    GstMythtvSrc *src;
   1.671 @@ -770,13 +878,32 @@
   1.672  gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event)
   1.673  {
   1.674    GstMythtvSrc *src = GST_MYTHTV_SRC (GST_PAD_PARENT (pad));
   1.675 +  gint64 cont_size = 0;
   1.676  
   1.677    switch (GST_EVENT_TYPE (event)) {
   1.678  #if 0
   1.679      case GST_EVENT_FLUSH_START:
   1.680 -      src->eos = FALSE;
   1.681 -      break;
   1.682 -      //return TRUE;
   1.683 +      //src->eos = FALSE;
   1.684 +      g_print( "\n\n\n[%s]\t\tGot FLUSH_START event!!!\n\n\n", __FUNCTION__ );
   1.685 +		  cont_size = gst_mythtv_src_get_position (src);
   1.686 +		  if ( !src->live_tv ) {
   1.687 +			  if ( cont_size > src->content_size ) {
   1.688 +			  	src->content_size = cont_size;
   1.689 +			  	src->eos = FALSE;
   1.690 +	  	  } else {
   1.691 +	      	src->eos = TRUE;
   1.692 +	      	gst_element_set_state ( GST_ELEMENT (src), GST_STATE_NULL );
   1.693 +	      	gst_element_set_locked_state ( GST_ELEMENT (src), FALSE );
   1.694 +	  	  }
   1.695 +		  } else {
   1.696 +		  	if ( cont_size <= 0 ) {
   1.697 +		  		src->update_prog_chain = TRUE;
   1.698 +		  		src->eos = TRUE;
   1.699 +		  		src->unique_setup = FALSE;
   1.700 +		  		src->do_start = TRUE;		  				  		
   1.701 +		  	}		  	
   1.702 +		  }
   1.703 +	    break;
   1.704      case GST_EVENT_FLUSH_STOP:
   1.705        src->do_start = TRUE;
   1.706        src->eos = FALSE;
   1.707 @@ -786,7 +913,7 @@
   1.708  #endif
   1.709      case GST_EVENT_EOS:
   1.710        g_print( "[%s] Got EOS event!!!\n", __FUNCTION__ );
   1.711 -	  guint64 cont_size = gst_mythtv_src_get_position (src);
   1.712 +	  cont_size = gst_mythtv_src_get_position (src);
   1.713  	  if ( !src->live_tv ) {
   1.714  		  if ( cont_size > src->content_size ) {
   1.715  		  	src->content_size = cont_size;
   1.716 @@ -841,6 +968,47 @@
   1.717    return TRUE;
   1.718  }
   1.719  
   1.720 +static GstStateChangeReturn
   1.721 +gst_mythtv_src_change_state (GstElement * element, GstStateChange transition)
   1.722 +{
   1.723 +  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
   1.724 +  GstMythtvSrc *src = GST_MYTHTV_SRC (element);
   1.725 +
   1.726 +  switch (transition) {
   1.727 +    case GST_STATE_CHANGE_NULL_TO_READY:
   1.728 +      src->content_size = 0;
   1.729 +      src->read_offset = 0;
   1.730 +      src->bytes_read = 0;
   1.731 +      src->do_start = TRUE;
   1.732 +      src->unique_setup = FALSE;      
   1.733 +      src->eos = TRUE;
   1.734 +      break;
   1.735 +    case GST_STATE_CHANGE_READY_TO_PAUSED:
   1.736 +    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
   1.737 +      src->eos = FALSE;
   1.738 +      break;
   1.739 +    default:
   1.740 +      break;
   1.741 +  }
   1.742 +  
   1.743 + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
   1.744 +  if (ret == GST_STATE_CHANGE_FAILURE)
   1.745 +    return ret;
   1.746 +
   1.747 +  switch (transition) {
   1.748 +    case GST_STATE_CHANGE_READY_TO_NULL:
   1.749 +      break;
   1.750 +    case GST_STATE_CHANGE_PAUSED_TO_READY:
   1.751 +    	if ( src->live_tv && src->update_prog_chain )
   1.752 +    		gst_mythtv_src_next_program_chain( src );
   1.753 +    	break;
   1.754 +    default:
   1.755 +      break;
   1.756 +  }
   1.757 +
   1.758 +  return ret;
   1.759 +}
   1.760 +
   1.761  static void
   1.762  gst_mythtv_src_set_property (GObject * object, guint prop_id,
   1.763      const GValue * value, GParamSpec * pspec)
   1.764 @@ -887,6 +1055,11 @@
   1.765  	mythtvsrc->live_tv = g_value_get_boolean (value);
   1.766  	break;
   1.767        }
   1.768 +    case PROP_GMYTHTV_ENABLE_TIMING_POSITION:
   1.769 +      {
   1.770 +	mythtvsrc->enable_timing_position = g_value_get_boolean (value);
   1.771 +	break;
   1.772 +      }      
   1.773      case PROP_GMYTHTV_LIVE_CHAINID:
   1.774        {
   1.775  	if (!g_value_get_string (value)) {
   1.776 @@ -899,7 +1072,6 @@
   1.777  	  mythtvsrc->live_chain_id = NULL;
   1.778  	}
   1.779  	mythtvsrc->live_chain_id = g_value_dup_string (value);
   1.780 -
   1.781  	break;
   1.782        }
   1.783  
   1.784 @@ -952,6 +1124,9 @@
   1.785      case PROP_GMYTHTV_LIVE:
   1.786        g_value_set_boolean ( value, mythtvsrc->live_tv );
   1.787        break;
   1.788 +    case PROP_GMYTHTV_ENABLE_TIMING_POSITION:
   1.789 +      g_value_set_boolean ( value, mythtvsrc->enable_timing_position );
   1.790 +      break;
   1.791      case PROP_GMYTHTV_LIVE_CHAINID:
   1.792        {
   1.793  	gchar *str = g_strdup( "" );
     2.1 --- a/gst-plugins-mythtv/src/gstmythtvsrc.h	Wed Oct 25 00:26:33 2006 +0100
     2.2 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.h	Thu Oct 26 01:48:46 2006 +0100
     2.3 @@ -21,8 +21,8 @@
     2.4  #include <stdio.h>
     2.5  
     2.6  #include <gmyth/gmyth_socket.h>
     2.7 -#include "gmyth_file_transfer.h"
     2.8 -#include "gmyth_livetv.h"
     2.9 +#include <gmyth/gmyth_file_transfer.h>
    2.10 +#include <gmyth/gmyth_livetv.h>
    2.11  
    2.12  G_BEGIN_DECLS
    2.13  
    2.14 @@ -55,11 +55,11 @@
    2.15    
    2.16    gint mythtv_version;
    2.17  
    2.18 -  guint64 content_size;
    2.19 +  gint64 content_size;
    2.20  
    2.21    guint64 bytes_read;
    2.22  
    2.23 -  guint64 read_offset;
    2.24 +  gint64 read_offset;
    2.25  
    2.26    gboolean eos;
    2.27    
    2.28 @@ -68,6 +68,8 @@
    2.29    gboolean unique_setup;
    2.30  
    2.31    gboolean live_tv;
    2.32 +  
    2.33 +  gboolean enable_timing_position;
    2.34  
    2.35    gint live_tv_id;
    2.36