[svn r31] Some changes, in order to use the newly added nuvdemux features.
1.1 --- a/gst-plugins-mythtv/src/gstmythtvsrc.c Wed Oct 11 22:46:27 2006 +0100
1.2 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.c Thu Oct 12 01:50:27 2006 +0100
1.3 @@ -3,8 +3,8 @@
1.4 * Copyright (C) <2006> Rosfran Borges <rosfran.borges@indt.org.br>
1.5 *
1.6 * This library is free software; you can redistribute it and/or
1.7 - * modify it under the terms of the GNU Library General Public
1.8 - * License as published by the Free Software Foundation; either
1.9 + * modify it under the terms of the GNU Library Lesser General
1.10 + * Public License as published by the Free Software Foundation; either
1.11 * version 2 of the License, or (at your option) any later version.
1.12 *
1.13 * This library is distributed in the hope that it will be useful,
1.14 @@ -36,10 +36,12 @@
1.15
1.16 #define MYTHTV_TRANSFER_MAX_WAITS 100
1.17
1.18 -#define MYTHTV_TRANSFER_MAX_BUFFER ( 32*1024 )
1.19 +#define MYTHTV_TRANSFER_MAX_BUFFER 32*1024
1.20 +//( 32*1024 )
1.21
1.22 /* 4*1024 ??? */
1.23 -#define MAX_READ_SIZE ( 16*1024 )
1.24 +#define MAX_READ_SIZE 12*1024
1.25 +//( 32*1024 )
1.26
1.27 #define ENABLE_TIMING_POSITION 1
1.28
1.29 @@ -47,15 +49,20 @@
1.30 static guint wait_to_transfer = 0;
1.31
1.32 static const GstElementDetails gst_mythtv_src_details =
1.33 -GST_ELEMENT_DETAILS ("MythTV client source",
1.34 +GST_ELEMENT_DETAILS ( "MythTV client source",
1.35 "Source/Network",
1.36 "Control and receive data as a client over the network via raw socket connections using the MythTV protocol",
1.37 - "Rosfran Borges <rosfran.borges@indt.org.br>");
1.38 + "Rosfran Borges <rosfran.borges@indt.org.br>" );
1.39
1.40 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
1.41 GST_PAD_SRC,
1.42 GST_PAD_ALWAYS,
1.43 - GST_STATIC_CAPS_ANY);
1.44 + GST_STATIC_CAPS ("video/x-nuv") );
1.45 + //GST_STATIC_CAPS_ANY);
1.46 +
1.47 +static GThread *update_size_task = NULL;
1.48 +
1.49 +static GStaticMutex update_size_mutex = G_STATIC_MUTEX_INIT;
1.50
1.51 enum
1.52 {
1.53 @@ -73,23 +80,30 @@
1.54
1.55 static void gst_mythtv_src_finalize (GObject * gobject);
1.56
1.57 -static GstFlowReturn gst_mythtv_src_create (GstBaseSrc * psrc,
1.58 - guint64 offset, guint size, GstBuffer ** outbuf);
1.59 +static GstFlowReturn gst_mythtv_src_create (GstBaseSrc * psrc, guint64 offset,
1.60 + guint size, GstBuffer ** outbuf);
1.61 +//static GstFlowReturn gst_mythtv_src_create (GstPushSrc * psrc, GstBuffer ** outbuf);
1.62 static gboolean gst_mythtv_src_start (GstBaseSrc * bsrc);
1.63 static gboolean gst_mythtv_src_stop (GstBaseSrc * bsrc);
1.64 static gboolean gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size);
1.65 -static gboolean gst_mythtv_src_is_seekable( GstBaseSrc *base_src );
1.66 +static gboolean gst_mythtv_src_is_seekable( GstBaseSrc *push_src );
1.67 +//static gboolean gst_mythtv_new_segment ( GstBaseSrc * psrc );
1.68
1.69 static void gst_mythtv_src_set_property (GObject * object, guint prop_id,
1.70 const GValue * value, GParamSpec * pspec);
1.71 static void gst_mythtv_src_get_property (GObject * object, guint prop_id,
1.72 GValue * value, GParamSpec * pspec);
1.73
1.74 -static void
1.75 -gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
1.76 +//static GstFlowReturn gst_mythtv_src_chain (GstPad * pad, GstBuffer * buf);
1.77
1.78 -static gboolean
1.79 -gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event);
1.80 +static void gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
1.81 +
1.82 +//static gboolean gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event);
1.83 +//static gboolean gst_mythtv_src_query ( GstPad * pad, GstQuery * query );
1.84 +
1.85 +static guint do_read_request_response (GstMythtvSrc *src, guint64 offset,
1.86 + guint size, GstBuffer **outbuf);
1.87 +//static gboolean gst_mythtv_src_sink_activate_pull (GstPad * srcpad, gboolean active);
1.88
1.89 static void
1.90 _urihandler_init (GType type)
1.91 @@ -107,8 +121,11 @@
1.92 }
1.93
1.94 GST_BOILERPLATE_FULL (GstMythtvSrc, gst_mythtv_src, GstBaseSrc,
1.95 - GST_TYPE_BASE_SRC, _urihandler_init);
1.96 -
1.97 + GST_TYPE_BASE_SRC, _urihandler_init)
1.98 +
1.99 +//GST_BOILERPLATE_FULL (GstMythtvSrc, gst_mythtv_src, GstPushSrc,
1.100 +// GST_TYPE_PUSH_SRC, _urihandler_init)
1.101 +
1.102 static void
1.103 gst_mythtv_src_base_init (gpointer g_class)
1.104 {
1.105 @@ -120,14 +137,16 @@
1.106 gst_element_class_set_details (element_class, &gst_mythtv_src_details);
1.107 }
1.108
1.109 - static void
1.110 +static void
1.111 gst_mythtv_src_class_init (GstMythtvSrcClass * klass)
1.112 {
1.113 GObjectClass *gobject_class;
1.114 + //GstPushSrcClass *gstpushsrc_class;
1.115 GstBaseSrcClass *gstbasesrc_class;
1.116
1.117 gobject_class = (GObjectClass *) klass;
1.118 gstbasesrc_class = (GstBaseSrcClass *) klass;
1.119 + //gstpushsrc_class = (GstPushSrcClass *) klass;
1.120
1.121 gobject_class->set_property = gst_mythtv_src_set_property;
1.122 gobject_class->get_property = gst_mythtv_src_get_property;
1.123 @@ -184,15 +203,15 @@
1.124 gstbasesrc_class->stop = gst_mythtv_src_stop;
1.125 gstbasesrc_class->get_size = gst_mythtv_src_get_size;
1.126 gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable;
1.127 + //gstpushsrc_class->newsegment = gst_mythtv_src_new_segment;
1.128
1.129 gstbasesrc_class->create = gst_mythtv_src_create;
1.130 -
1.131 -
1.132 +
1.133 GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0,
1.134 "MythTV Client Source");
1.135 }
1.136
1.137 - static void
1.138 +static void
1.139 gst_mythtv_src_init (GstMythtvSrc * this, GstMythtvSrcClass * g_class)
1.140 {
1.141 this->file_transfer = NULL;
1.142 @@ -209,14 +228,29 @@
1.143 this->live_tv = FALSE;
1.144
1.145 this->user_agent = g_strdup ("mythtvsrc");
1.146 - this->mythtv_caps = NULL;
1.147 + this->mythtv_caps = NULL;
1.148 +
1.149 + gst_base_src_set_format( GST_BASE_SRC( this ), GST_FORMAT_BYTES );
1.150
1.151 - gst_pad_set_event_function (GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
1.152 - GST_DEBUG_FUNCPTR (gst_mythtv_src_handle_event));
1.153 + gst_base_src_set_live ( GST_BASE_SRC( this ), TRUE );
1.154 +
1.155 + //gst_pad_set_chain_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
1.156 + // gst_mythtv_src_chain );
1.157 +
1.158 +/*
1.159 + gst_pad_set_event_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
1.160 + gst_mythtv_src_handle_event );
1.161 +
1.162 + gst_pad_set_query_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
1.163 + gst_mythtv_src_query );
1.164 +*/
1.165 + //gst_pad_set_activatepull_function( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
1.166 + // gst_mythtv_src_sink_activate_pull );
1.167 +
1.168
1.169 }
1.170
1.171 - static void
1.172 +static void
1.173 gst_mythtv_src_finalize (GObject * gobject)
1.174 {
1.175 GstMythtvSrc *this = GST_MYTHTV_SRC (gobject);
1.176 @@ -244,172 +278,146 @@
1.177 G_OBJECT_CLASS (parent_class)->finalize (gobject);
1.178 }
1.179
1.180 -#if 0
1.181 - static guint
1.182 -do_seek( GstMythtvSrc *src, guint64 offset, guint size, GstBuffer *outbuf )
1.183 -{
1.184 - guint64 off_uint64 = myth_file_transfer_seek(src->file_transfer, offset, 1);
1.185 -
1.186 - g_print( "[%s] Call MythTV SEEK with offset %llu, got a new one %llu...\n", __FUNCTION__,
1.187 - offset, off_uint64 );
1.188 -
1.189 - return off_uint64;
1.190 -
1.191 -}
1.192 -#endif
1.193 -
1.194 - static guint
1.195 -do_read_request_response (GstMythtvSrc * src, guint64 offset, guint size, GstBuffer * outbuf)
1.196 +static guint
1.197 +do_read_request_response (GstMythtvSrc * src, guint64 offset, guint size, GstBuffer **outbuf)
1.198 {
1.199 guint read = 0;
1.200 guint sizetoread = size; //GST_BUFFER_SIZE (outbuf);
1.201 + GstBuffer *buffer = gst_buffer_new_and_alloc( size );
1.202
1.203 - g_print( "[%s] Reading %d bytes...\n", __FUNCTION__, sizetoread );
1.204 + g_print( "Starting: [%s] Reading %d bytes...\n", __FUNCTION__, sizetoread );
1.205
1.206 - /* Loop sending the request:
1.207 + /* Loop sending the Myth File Transfer request:
1.208 * Retry whilst authentication fails and we supply it. */
1.209 + guint len = 0;
1.210
1.211 - ssize_t len = 0;
1.212 -
1.213 - GST_OBJECT_LOCK(src);
1.214 + //GST_OBJECT_LOCK(src);
1.215
1.216 while ( sizetoread > 0 ) {
1.217
1.218 len = myth_file_transfer_read( src->file_transfer,
1.219 - GST_BUFFER_DATA (outbuf) + read, sizetoread, TRUE );
1.220 + GST_BUFFER_DATA( buffer ) + read, sizetoread, TRUE );
1.221
1.222 if ( len > 0 ) {
1.223 read += len;
1.224 src->read_offset += read;
1.225 sizetoread -= len;
1.226 - } else if ( len < 0 ) {
1.227 - goto done;
1.228 + } else if ( len <= 0 ) {
1.229 +
1.230 + if ( src->live_tv == FALSE ) {
1.231 + goto done;
1.232 + } else if ( src->content_size >= src->read_offset &&
1.233 + abs ( src->content_size - src->read_offset ) <= MYTHTV_TRANSFER_MAX_BUFFER ) {
1.234 + guint64 new_offset = myth_file_transfer_get_file_position( src->file_transfer );
1.235 + if ( src->content_size < new_offset ) {
1.236 + src->content_size = new_offset;
1.237 + goto done;
1.238 + } else
1.239 + goto eos;
1.240 + } else
1.241 + goto eos;
1.242 +
1.243 }
1.244 - /*else if ( len == 0 ) {
1.245 - goto eos;
1.246 - }*/
1.247
1.248 - if ( len == sizetoread )
1.249 + if ( read == sizetoread )
1.250 break;
1.251 -
1.252 }
1.253 -
1.254 +
1.255 if ( read > 0 ) {
1.256 src->bytes_read += read;
1.257 -
1.258 - GST_BUFFER_SIZE (outbuf) = read;
1.259 - } else if ( read <= 0 || len <= 0 ) {
1.260 - if ( src->live_tv == FALSE )
1.261 - goto eos;
1.262 - else
1.263 - goto done;
1.264 }
1.265 - //GST_BUFFER_OFFSET (outbuf) = src->read_offset;
1.266
1.267 g_print( "[%s]\tBYTES READ (actual) = %d, BYTES READ (cumulative) = %llu, "\
1.268 "OFFSET = %llu, CONTENT SIZE = %llu.\n", __FUNCTION__, read, src->bytes_read,
1.269 src->read_offset, src->content_size );
1.270
1.271 - GST_OBJECT_UNLOCK(src);
1.272 -
1.273 - if ( len < 0 ) {
1.274 - read = len;
1.275 - if ( src->live_tv == FALSE )
1.276 - goto eos;
1.277 - else
1.278 - goto done;
1.279 - }
1.280 -
1.281 - if ( src->bytes_read < src->content_size )
1.282 - goto done;
1.283 + *outbuf = buffer;
1.284 + memcpy( GST_BUFFER_DATA( *outbuf ), GST_BUFFER_DATA( buffer ), read );
1.285 + GST_BUFFER_SIZE (buffer) = read;
1.286 + GST_BUFFER_OFFSET (buffer) = offset;
1.287 + GST_BUFFER_OFFSET_END (buffer) = offset + read;
1.288 +
1.289 + g_print( "Stopping: [%s]\t\tBUFFER --->SIZE = %d, OFFSET = %llu, "\
1.290 + "OFFSET_END = %llu.\n\n", __FUNCTION__, GST_BUFFER_SIZE (*outbuf),
1.291 + GST_BUFFER_OFFSET (*outbuf), GST_BUFFER_OFFSET_END (*outbuf) );
1.292 + //GST_OBJECT_UNLOCK(src);
1.293 + goto done;
1.294
1.295 eos:
1.296 - GST_OBJECT_UNLOCK(src);
1.297 + //GST_OBJECT_UNLOCK(src);
1.298
1.299 src->eos = TRUE;
1.300 +
1.301 done:
1.302 - GST_OBJECT_UNLOCK(src);
1.303
1.304 return read;
1.305 }
1.306
1.307 - static GstFlowReturn
1.308 -gst_mythtv_src_create ( GstBaseSrc * psrc, guint64 offset,
1.309 - guint size, GstBuffer **outbuf )
1.310 +static GstFlowReturn
1.311 +gst_mythtv_src_create ( GstBaseSrc * psrc, guint64 offset, guint size, GstBuffer **outbuf)
1.312 {
1.313 GstMythtvSrc *src;
1.314 GstFlowReturn ret = GST_FLOW_OK;
1.315 - guint read;
1.316 - guint64 size_tmp = 0;
1.317 + guint read = 0;
1.318 + //GstBuffer *buffer = NULL;
1.319 + //guint size = MAX_READ_SIZE;
1.320 +
1.321 + src = GST_MYTHTV_SRC (psrc);
1.322 +
1.323 + if ( src->content_size >= src->read_offset &&
1.324 + abs ( src->content_size - src->read_offset ) <= MYTHTV_TRANSFER_MAX_BUFFER ) {
1.325 + guint64 new_offset = myth_file_transfer_get_file_position( src->file_transfer );
1.326 + if ( src->content_size < new_offset ) {
1.327 + src->content_size = new_offset;
1.328 + }
1.329 + }
1.330
1.331 - src = GST_MYTHTV_SRC (psrc);
1.332 + if (G_UNLIKELY (src->read_offset != offset)) {
1.333 + guint64 new_offset = myth_file_transfer_seek(src->file_transfer, offset, SEEK_SET);
1.334
1.335 - g_print( "[%s]\tBUFFER OFFSET = %llu, BUFFER SIZE = %d.\n", __FUNCTION__, offset,
1.336 - size );
1.337 + if (G_UNLIKELY (new_offset < 0 || new_offset != offset))
1.338 + goto read_error;
1.339
1.340 -
1.341 + src->read_offset = offset;
1.342 + }
1.343 +
1.344 /* The caller should know the number of bytes and not read beyond EOS. */
1.345 if (G_UNLIKELY (src->eos))
1.346 goto eos;
1.347
1.348 /* Create the buffer. */
1.349 - ret = gst_pad_alloc_buffer ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
1.350 - // GST_BUFFER_OFFSET_NONE, GST_BASE_SRC (psrc)->blocksize,
1.351 - offset, size,
1.352 - src->mythtv_caps ? src->mythtv_caps :
1.353 - GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf );
1.354 + //ret = gst_pad_alloc_buffer ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
1.355 + // GST_BUFFER_OFFSET_NONE, size, src->mythtv_caps ? src->mythtv_caps :
1.356 + // GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf );
1.357 +
1.358 + //if (G_UNLIKELY (ret != GST_FLOW_OK))
1.359 + // goto eos;
1.360 + //if (G_UNLIKELY (ret == GST_FLOW_ERROR))
1.361 + // goto read_error;
1.362 +
1.363 + g_static_mutex_lock( &update_size_mutex );
1.364 + read = do_read_request_response ( src, 0, size, outbuf );
1.365 + g_static_mutex_unlock( &update_size_mutex );
1.366
1.367 - if (G_UNLIKELY (ret == GST_FLOW_UNEXPECTED))
1.368 - goto eos;
1.369 -
1.370 - if (G_UNLIKELY (ret != GST_FLOW_OK))
1.371 - goto done;
1.372 -
1.373 - read = do_read_request_response ( src, offset, size, *outbuf );
1.374 -
1.375 -#if ENABLE_TIMING_POSITION == 1
1.376 - if (src->live_tv == TRUE) {
1.377 - //g_usleep( 1000 );
1.378 -get_file_pos:
1.379 - //g_usleep( 100 );
1.380 - size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
1.381 - if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
1.382 - src->content_size = size_tmp;
1.383 - else
1.384 - goto get_file_pos;
1.385 - g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n",
1.386 - __FUNCTION__, size_tmp);
1.387 -
1.388 - }
1.389 -#endif
1.390 -
1.391 - if (G_UNLIKELY (read < 0))
1.392 + if (G_UNLIKELY (read < 0) || *outbuf == NULL)
1.393 goto read_error;
1.394
1.395 + gst_buffer_set_caps( *outbuf, GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))) );
1.396 +
1.397 + //*outbuf = buffer;
1.398 +
1.399 if (G_UNLIKELY(src->eos))
1.400 goto eos;
1.401 + else
1.402 + goto done;
1.403
1.404 done:
1.405 return ret;
1.406 eos:
1.407 -#if ENABLE_TIMING_POSITION == 1
1.408 - if ( src->live_tv == TRUE ) {
1.409 - //g_usleep( 1000 );
1.410 - guint64 size_tmp = 0;
1.411 -get_file_pos_eos:
1.412 - //g_usleep( 100 );
1.413 - size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
1.414 - if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
1.415 - src->content_size = size_tmp;
1.416 - else
1.417 - goto get_file_pos_eos;
1.418 - g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n",
1.419 - __FUNCTION__, size_tmp);
1.420 - goto done;
1.421 - } else
1.422 -#endif
1.423 {
1.424 - GST_DEBUG_OBJECT (src, "EOS reached");
1.425 + const gchar *reason = gst_flow_get_name (ret);
1.426 +
1.427 + GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);
1.428 return GST_FLOW_UNEXPECTED;
1.429 }
1.430 /* ERRORS */
1.431 @@ -420,48 +428,76 @@
1.432 src->uri_name));
1.433 return GST_FLOW_ERROR;
1.434 }
1.435 +
1.436 +#if 0
1.437 +need_pause:
1.438 + {
1.439 + const gchar *reason = gst_flow_get_name (ret);
1.440 +
1.441 + GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);
1.442 + return GST_FLOW_UNEXPECTED;
1.443 + }
1.444 +#endif
1.445 }
1.446
1.447 -#if 0
1.448 -/* The following two charset mangling functions were copied from gnomevfssrc.
1.449 - * Preserve them under the unverified assumption that they do something vaguely
1.450 - * worthwhile.
1.451 - */
1.452 - static char *
1.453 -unicodify (const char *str, int len, ...)
1.454 +void
1.455 +update_size_func( void *mythtv_data )
1.456 {
1.457 - char *ret = NULL, *cset;
1.458 - va_list args;
1.459 - gsize bytes_read, bytes_written;
1.460 + GstMythtvSrc *src;
1.461
1.462 - if (g_utf8_validate (str, len, NULL))
1.463 - return g_strndup (str, len >= 0 ? len : strlen (str));
1.464 + g_return_if_fail( mythtv_data != NULL );
1.465
1.466 - va_start (args, len);
1.467 - while ((cset = va_arg (args, char *)) != NULL)
1.468 - {
1.469 - if (!strcmp (cset, "locale"))
1.470 - ret = g_locale_to_utf8 (str, len, &bytes_read, &bytes_written, NULL);
1.471 - else
1.472 - ret = g_convert (str, len, "UTF-8", cset,
1.473 - &bytes_read, &bytes_written, NULL);
1.474 - if (ret)
1.475 - break;
1.476 + src = GST_MYTHTV_SRC ( mythtv_data );
1.477 +
1.478 + g_static_mutex_lock( &update_size_mutex );
1.479 +
1.480 + if ( src->do_start ) {
1.481 +#if ENABLE_TIMING_POSITION == 1
1.482 + guint64 size_tmp = 0;
1.483 + if (src->live_tv == TRUE) {
1.484 +get_file_pos:
1.485 + g_usleep( 50 );
1.486 + size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
1.487 + if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
1.488 + src->content_size = size_tmp;
1.489 + else
1.490 + goto get_file_pos;
1.491 + g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n",
1.492 + __FUNCTION__, size_tmp );
1.493 + }
1.494 +#endif
1.495 }
1.496 - va_end (args);
1.497 + g_static_mutex_unlock( &update_size_mutex );
1.498
1.499 - return ret;
1.500 }
1.501
1.502 - static char *
1.503 -gst_mythtv_src_unicodify (const char *str)
1.504 +guint64
1.505 +gst_mythtv_src_get_position ( GstMythtvSrc* src )
1.506 {
1.507 - return unicodify (str, -1, "locale", "ISO-8859-1", NULL);
1.508 +
1.509 + if ( src->do_start ) {
1.510 +#if ENABLE_TIMING_POSITION == 1
1.511 + guint64 size_tmp = 0;
1.512 + if (src->live_tv == TRUE) {
1.513 +get_file_pos:
1.514 + g_usleep( 50 );
1.515 + size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
1.516 + if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
1.517 + src->content_size = size_tmp;
1.518 + else
1.519 + goto get_file_pos;
1.520 + g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n",
1.521 + __FUNCTION__, size_tmp );
1.522 + }
1.523 +#endif
1.524 + }
1.525 +
1.526 + return src->content_size;
1.527 +
1.528 }
1.529 -#endif
1.530
1.531 /* create a socket for connecting to remote server */
1.532 - static gboolean
1.533 +static gboolean
1.534 gst_mythtv_src_start ( GstBaseSrc * bsrc )
1.535 {
1.536 GstMythtvSrc *src = GST_MYTHTV_SRC (bsrc);
1.537 @@ -469,15 +505,7 @@
1.538 GString *chain_id_local = NULL;
1.539
1.540 gboolean ret = TRUE;
1.541 -#if 0
1.542 - if (src->live_tv == TRUE && src->file_transfer != NULL) {
1.543 - guint64 size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
1.544 - if (size_tmp > src->content_size)
1.545 - src->content_size = size_tmp;
1.546 - g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n",
1.547 - __FUNCTION__, size_tmp);
1.548 - }
1.549 -#endif
1.550 +
1.551 if (src->unique_setup == FALSE) {
1.552 src->unique_setup = TRUE;
1.553 } else {
1.554 @@ -489,8 +517,8 @@
1.555 if ( src->live_tv ) {
1.556 src->spawn_livetv = myth_livetv_new( );
1.557 if ( myth_livetv_setup( src->spawn_livetv ) == FALSE ) {
1.558 - ret = FALSE;
1.559 - goto init_failed;
1.560 + ret = FALSE;
1.561 + goto init_failed;
1.562 }
1.563 /* set up the uri variable */
1.564 src->uri_name = g_strdup( src->spawn_livetv->proginfo->pathname->str );
1.565 @@ -544,70 +572,143 @@
1.566 src->content_size = src->file_transfer->filesize;
1.567
1.568 GST_OBJECT_UNLOCK(src);
1.569 + if ( src->live_tv ) {
1.570 +
1.571 + //GError* error;
1.572 +
1.573 + //update_size_task = g_thread_create( (GThreadFunc)update_size_func, src, FALSE, &error );
1.574 +
1.575 + g_print( "[%s] Update Size task = %s\n", __FUNCTION__, update_size_task != NULL ? "OK !" : "ERROR!!!" );
1.576 +
1.577 + }
1.578 + src->do_start = TRUE;
1.579 +
1.580 +done:
1.581 + return TRUE;
1.582 +
1.583 + /* ERRORS */
1.584 +init_failed:
1.585 + {
1.586 + if (src->spawn_livetv != NULL )
1.587 + g_object_unref( src->spawn_livetv );
1.588 +
1.589 + GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1.590 + (NULL), ("Could not initialize MythTV library (%i, %s)", ret, src->uri_name));
1.591 + return FALSE;
1.592 + }
1.593 +begin_req_failed:
1.594 + {
1.595 + GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1.596 + (NULL), ("Could not begin request sent to MythTV server (%i, %s)", ret, src->uri_name));
1.597 + return FALSE;
1.598 + }
1.599 +}
1.600
1.601 #if 0
1.602 - const char *str_value;
1.603 - gint gint_value;
1.604 +/* handles queries for location in the stream in the requested format */
1.605 +static gboolean
1.606 +gst_mythtv_src_query ( GstPad * pad, GstQuery * query )
1.607 +{
1.608 + gboolean res = TRUE;
1.609 + GstMythtvSrc *mythtv;
1.610
1.611 - str_value = ne_get_response_header (src->request, "myth-metaint");
1.612 - if (str_value) {
1.613 - if ( sscanf (str_value, "%d", &gint_value) == 1 ) {
1.614 - if (src->myth_caps) {
1.615 - gst_caps_unref (src->myth_caps);
1.616 - src->myth_caps = NULL;
1.617 + guint64 size = 0;
1.618 +
1.619 + mythtv = GST_MYTHTV_SRC( GST_PAD_PARENT (pad) );
1.620 +
1.621 + size = gst_mythtv_src_get_position (mythtv);
1.622 +
1.623 + switch (GST_QUERY_TYPE (query)) {
1.624 +
1.625 + case GST_QUERY_POSITION:
1.626 + {
1.627 +
1.628 + //GstFormat format;
1.629 + gint64 cur = 0;
1.630 +
1.631 + /* save requested format */
1.632 + gst_query_parse_position (query, NULL, &cur);
1.633 +
1.634 + /* query peer for current position in time */
1.635 + g_print( "[%s] Actual size is %s than current size from sink. [ %lld, %lld ]\n", __FUNCTION__,
1.636 + ( size > cur ) ? "greater" : "lower", size, cur );
1.637 + gst_query_set_position (query, GST_FORMAT_BYTES, size);
1.638 + if ( size < cur )
1.639 + goto error;
1.640 +
1.641 + break;
1.642 }
1.643 - src->myth_metaint = gint_value;
1.644 + #if 0
1.645 + case GST_QUERY_DURATION:
1.646 + {
1.647 + //GstFormat format;
1.648 + gint64 cur = 0;
1.649 +
1.650 + /* save requested format */
1.651 + gst_query_parse_position (query, NULL, &cur);
1.652 +
1.653 + /* query peer for current position in time */
1.654 + g_print( "[%s] Actual size is %s than current size from sink. [ %lld, %lld ]\n", __FUNCTION__,
1.655 + ( size * GST_SECOND > cur * GST_SECOND ) ? "greater" : "lower", size * GST_SECOND,
1.656 + cur * GST_SECOND );
1.657 + gst_query_set_position (query, GST_FORMAT_TIME, size * GST_SECOND );
1.658 +
1.659 + if ( size * GST_SECOND < cur * GST_SECOND )
1.660 + goto error;
1.661 +
1.662 + break;
1.663 + }
1.664 + #endif
1.665 + default:
1.666 + res = FALSE;
1.667 + break;
1.668 + }
1.669 +
1.670 + return res;
1.671 +
1.672 +error:
1.673 +
1.674 + return FALSE;
1.675 +}
1.676 #endif
1.677 - //src->mythtv_caps = gst_caps_new_simple ("application/x-gst_ff-nuv", NULL);
1.678 - // }
1.679 - // }
1.680 -done:
1.681 - return TRUE;
1.682
1.683 - /* ERRORS */
1.684 -init_failed:
1.685 - {
1.686 - if (src->spawn_livetv != NULL )
1.687 - g_object_unref( src->spawn_livetv );
1.688 -
1.689 - GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1.690 - (NULL), ("Could not initialize MythTV library (%i, %s)", ret, src->uri_name));
1.691 - return FALSE;
1.692 - }
1.693 -begin_req_failed:
1.694 - {
1.695 - GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1.696 - (NULL), ("Could not begin request sent to MythTV server (%i, %s)", ret, src->uri_name));
1.697 - return FALSE;
1.698 - }
1.699 -}
1.700 -
1.701 - static gboolean
1.702 +static gboolean
1.703 gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size)
1.704 {
1.705 GstMythtvSrc *src;
1.706 + gboolean ret = TRUE;
1.707
1.708 src = GST_MYTHTV_SRC (bsrc);
1.709 +
1.710 + if (src->content_size <= 0) {
1.711 + ret= FALSE;
1.712 +
1.713 + } else if ( src->live_tv && src->content_size < MYTHTV_TRANSFER_MAX_BUFFER ) {
1.714 + g_static_mutex_lock( &update_size_mutex );
1.715 +
1.716 #if ENABLE_TIMING_POSITION == 1
1.717 - guint64 size_tmp = 0;
1.718 - if (src->live_tv == TRUE) {
1.719 + guint64 size_tmp = 0;
1.720 + if (src->live_tv == TRUE) {
1.721 get_file_pos:
1.722 - //g_usleep( 100 );
1.723 - size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
1.724 - if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
1.725 - src->content_size = size_tmp;
1.726 - else
1.727 - goto get_file_pos;
1.728 - g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n",
1.729 - __FUNCTION__, size_tmp);
1.730 + g_usleep( 50 );
1.731 + size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
1.732 + if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
1.733 + src->content_size = size_tmp;
1.734 + else
1.735 + goto get_file_pos;
1.736 + g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n",
1.737 + __FUNCTION__, size_tmp );
1.738 + }
1.739 +#endif
1.740 + g_static_mutex_unlock( &update_size_mutex );
1.741 +
1.742 }
1.743 -#endif
1.744 - if (src->content_size <= 0)
1.745 - return FALSE;
1.746
1.747 *size = src->content_size;
1.748 + g_print( "[%s] Content size = %llu\n", __FUNCTION__, src->content_size );
1.749
1.750 - return TRUE;
1.751 + return ret;
1.752 +
1.753 }
1.754
1.755 /* close the socket and associated resources
1.756 @@ -634,12 +735,14 @@
1.757 return TRUE;
1.758 }
1.759
1.760 - static gboolean
1.761 +#if 0
1.762 +static gboolean
1.763 gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event)
1.764 {
1.765 GstMythtvSrc *src = GST_MYTHTV_SRC (GST_PAD_PARENT (pad));
1.766
1.767 switch (GST_EVENT_TYPE (event)) {
1.768 +#if 0
1.769 case GST_EVENT_FLUSH_START:
1.770 src->eos = FALSE;
1.771 break;
1.772 @@ -648,10 +751,28 @@
1.773 src->do_start = TRUE;
1.774 src->eos = FALSE;
1.775 gst_element_set_state (GST_ELEMENT(src), GST_STATE_NULL);
1.776 - gst_element_set_locked_state (GST_ELEMENT(src), TRUE);
1.777 + //gst_element_set_locked_state (GST_ELEMENT(src), TRUE);
1.778 + break;
1.779 +#endif
1.780 + case GST_EVENT_EOS:
1.781 + g_print( "[%s] Got EOS event!!!\n", __FUNCTION__ );
1.782 + src->content_size = gst_mythtv_src_get_position (src);
1.783 + if ( cont_size > src->content_size ) {
1.784 + src->content_size = cont_size;
1.785 + } else {
1.786 + src->eos = TRUE;
1.787 + gst_element_set_state ( GST_ELEMENT (src), GST_STATE_NULL );
1.788 + gst_element_set_locked_state ( GST_ELEMENT (src), FALSE );
1.789 + }
1.790 + break;
1.791 +#if 0
1.792 + case GST_EVENT_NEWSEGMENT:
1.793 + g_print( "[%s] Got NEWSEGMENT!!!\n", __FUNCTION__ );
1.794 + src->eos = FALSE;
1.795 break;
1.796 case GST_EVENT_SEEK:
1.797 {
1.798 + g_print( "[%s] Got EVENT_SEEK!!!\n", __FUNCTION__ );
1.799 gdouble rate;
1.800 //gboolean update = TRUE;
1.801 GstFormat format;
1.802 @@ -671,22 +792,23 @@
1.803 // &position );
1.804 //GstFlowReturn flow_ret = gst_mythtv_src_create (GST_BASE_SRC( GST_PAD_PARENT( psrc ) ),
1.805 // cur, stop - cur + 1, GstBuffer)
1.806 -
1.807 - }
1.808 + }
1.809 +#endif
1.810 default:
1.811 return gst_pad_event_default (pad, event);
1.812 }
1.813
1.814 return gst_pad_event_default (pad, event);
1.815 }
1.816 +#endif
1.817
1.818 - static gboolean
1.819 -gst_mythtv_src_is_seekable( GstBaseSrc *base_src )
1.820 +static gboolean
1.821 +gst_mythtv_src_is_seekable( GstBaseSrc *push_src )
1.822 {
1.823 return TRUE;
1.824 }
1.825
1.826 - static void
1.827 +static void
1.828 gst_mythtv_src_set_property (GObject * object, guint prop_id,
1.829 const GValue * value, GParamSpec * pspec)
1.830 {
2.1 --- a/gst-plugins-mythtv/src/myth_file_transfer.c Wed Oct 11 22:46:27 2006 +0100
2.2 +++ b/gst-plugins-mythtv/src/myth_file_transfer.c Thu Oct 12 01:50:27 2006 +0100
2.3 @@ -143,7 +143,7 @@
2.4
2.5 transfer->rec_id = -1;
2.6
2.7 - transfer->recordernum = 0;
2.8 + transfer->recordernum = num;
2.9 transfer->uri = myth_uri_new ( uri_str->str );
2.10
2.11 transfer->hostname = g_string_new( myth_uri_gethost(transfer->uri) );
2.12 @@ -223,10 +223,10 @@
2.13 printf("[%s] Running config to the %s...\n", __FUNCTION__, live_tv ? "LiveTV" : "FileTransfer" );
2.14
2.15 #if 0
2.16 - /* configure the event socket */
2.17 - if ((*transfer)->event_sock == NULL) {
2.18 + /* configure the control socket */
2.19 + if ((*transfer)->control_sock == NULL) {
2.20
2.21 - if ( myth_connect_to_transfer_backend ( transfer, MYTH_MONITOR_TYPE ) == NULL ) {
2.22 + if ( myth_connect_to_transfer_backend ( transfer, MYTH_PLAYBACK_TYPE ) == NULL ) {
2.23 g_printerr( "Connection to backend failed (Event Socket).\n" );
2.24 ret = FALSE;
2.25 }
2.26 @@ -611,16 +611,17 @@
2.27
2.28 GMythStringList *strlist = gmyth_string_list_new();
2.29 g_string_printf (transfer->query, "%s %d", MYTHTV_QUERY_HEADER, transfer->recordernum);
2.30 - gmyth_string_list_append_string( strlist, transfer->query );
2.31 + gmyth_string_list_append_string( strlist, transfer->query );
2.32 gmyth_string_list_append_char_array( strlist, "SEEK" );
2.33 gmyth_string_list_append_uint64( strlist, pos );
2.34 - // gmyth_string_list_append_int( strlist, whence );
2.35 +
2.36 + gmyth_string_list_append_int( strlist, whence );
2.37
2.38 if (pos > 0 )
2.39 gmyth_string_list_append_uint64( strlist, pos );
2.40 else
2.41 gmyth_string_list_append_uint64( strlist, transfer->readposition );
2.42 -
2.43 +
2.44 gmyth_socket_sendreceive_stringlist( transfer->control_sock, strlist );
2.45
2.46 guint64 retval = gmyth_string_list_get_uint64(strlist, 0);
2.47 @@ -726,6 +727,7 @@
2.48 if ( io_status == G_IO_STATUS_NORMAL )
2.49 g_print( "[%s] Setting encoding to binary data socket).\n", __FUNCTION__ );
2.50
2.51 +
2.52 io_cond = g_io_channel_get_buffer_condition( io_channel );
2.53
2.54 io_cond_control = g_io_channel_get_buffer_condition( io_channel );
2.55 @@ -772,32 +774,36 @@
2.56
2.57 wait_to_transfer = 0;
2.58
2.59 - while ( transfer->live_tv && ( myth_file_transfer_get_file_position( transfer ) < 4096 ) &&
2.60 - wait_to_transfer++ < MYTHTV_TRANSFER_MAX_WAITS )
2.61 - g_usleep( 1000*50 ); /* waits just for 2/10 second */
2.62 + //while ( transfer->live_tv && ( myth_file_transfer_get_file_position( transfer ) < 4096 ) &&
2.63 + // wait_to_transfer++ < MYTHTV_TRANSFER_MAX_WAITS )
2.64 + // g_usleep( 1000*50 ); /* waits just for 2/10 second */
2.65
2.66 //g_thread_create( myth_init_io_watchers, (void*)transfer, FALSE, NULL );
2.67 //g_printerr( "[%s] Watch listener function to the IO control channel on thread %p.\n", __FUNCTION__, g_thread_self() );
2.68
2.69 - g_static_mutex_lock (&mutex);
2.70 - strlist = gmyth_string_list_new();
2.71 + //g_static_mutex_lock (&mutex);
2.72 + //strlist = gmyth_string_list_new();
2.73
2.74 g_string_printf ( transfer->query, "%s %d", /*transfer->live_tv ? MYTHTV_RECORDER_HEADER :*/ MYTHTV_QUERY_HEADER,
2.75 /* transfer->live_tv ? transfer->card_id :*/ transfer->recordernum ); // transfer->recordernum
2.76 g_print( "\t[%s] Transfer_query = %s\n", __FUNCTION__, transfer->query->str );
2.77 +
2.78 strlist = gmyth_string_list_new();
2.79
2.80 - gmyth_string_list_append_string( strlist, transfer->query );
2.81 + gmyth_string_list_append_char_array( strlist, transfer->query->str );
2.82 gmyth_string_list_append_char_array( strlist, /*transfer->live_tv ? "REQUEST_BLOCK_RINGBUF" :*/ "REQUEST_BLOCK" );
2.83 gmyth_string_list_append_int( strlist, size );
2.84
2.85 gmyth_socket_write_stringlist( transfer->control_sock, strlist );
2.86 sent = size;
2.87 + //g_static_mutex_unlock( &mutex );
2.88
2.89 //data = (void*)g_new0( gchar, size );
2.90
2.91 g_io_channel_flush( io_channel_control, NULL );
2.92 -// g_io_channel_flush( io_channel, NULL );
2.93 + //g_io_channel_flush( io_channel, NULL );
2.94 +
2.95 + g_static_mutex_lock( &mutex );
2.96
2.97 io_cond = g_io_channel_get_buffer_condition( io_channel );
2.98
2.99 @@ -814,7 +820,7 @@
2.100 buf_len = ( sent - recv ) > MYTHTV_BUFFER_SIZE ? MYTHTV_BUFFER_SIZE : ( sent - recv );
2.101
2.102 io_status = g_io_channel_read_chars( io_channel, data + recv,
2.103 - buf_len, &bytes_read, &error );
2.104 + buf_len, &bytes_read, &error );
2.105 /*
2.106 GString *sss = g_string_new("");
2.107 sss = g_string_append_len( sss, (gchar*)data+recv, bytes_read );
2.108 @@ -884,6 +890,7 @@
2.109 g_error_free( error );
2.110 }
2.111 }
2.112 + //g_static_mutex_unlock( &mutex );
2.113
2.114 cleanup:
2.115
2.116 @@ -894,6 +901,7 @@
2.117 g_object_unref( strlist );
2.118
2.119 g_static_mutex_unlock (&mutex);
2.120 +
2.121 g_print( "myth_file_transfer_read(): reqd=%d, rcvd=%d, rept=%d, "\
2.122 "(rcvd and rept MUST be the same!)\n", size,
2.123 recv, sent );
2.124 @@ -902,9 +910,11 @@
2.125 // recv = -1;
2.126 //}
2.127
2.128 - if ( error != NULL )
2.129 + if ( error != NULL ) {
2.130 g_printerr( "ERROR: %s [msg = %s, code = %d]\n", __FUNCTION__, error->message,
2.131 error->code );
2.132 + g_error_free( error );
2.133 + }
2.134
2.135 return recv;
2.136 }