[svn r53] LiveTV working fine, adjustments in some GMyth functions dealing with the TVChain.
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