[svn r82] Changed the MythTV source to the PUSH mode.
1.1 --- a/gst-plugins-mythtv/src/gstmythtvsrc.c Mon Nov 13 19:11:55 2006 +0000
1.2 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.c Mon Nov 13 19:58:37 2006 +0000
1.3 @@ -38,14 +38,14 @@
1.4
1.5 #define GMYTHTV_TRANSFER_MAX_WAITS 100
1.6
1.7 -#define GMYTHTV_TRANSFER_MAX_BUFFER 4*1024
1.8 +#define GMYTHTV_TRANSFER_MAX_BUFFER 128*1024
1.9 //( 32*1024 )
1.10
1.11 /* 4*1024 ??? */
1.12 -#define MAX_READ_SIZE 4*1024
1.13 +#define MAX_READ_SIZE 2*1024
1.14 //( 32*1024 )
1.15
1.16 -#define GST_FLOW_ERROR_NO_DATA -101
1.17 +#define GST_FLOW_ERROR_NO_DATA -101
1.18
1.19 /* stablish a maximum iteration value to the IS_RECORDING message */
1.20 static guint wait_to_transfer = 0;
1.21 @@ -56,18 +56,11 @@
1.22 "Control and receive data as a client over the network via raw socket connections using the MythTV protocol",
1.23 "Rosfran Borges <rosfran.borges@indt.org.br>" );
1.24
1.25 -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
1.26 +static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ( "src",
1.27 GST_PAD_SRC,
1.28 GST_PAD_ALWAYS,
1.29 GST_STATIC_CAPS ("video/x-nuv") );
1.30 -
1.31 -/*
1.32 -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
1.33 - GST_PAD_SINK,
1.34 - GST_PAD_SOMETIMES,
1.35 - GST_STATIC_CAPS ("video/x-nuv") );
1.36 -*/
1.37 -
1.38 +
1.39 enum
1.40 {
1.41 PROP_0,
1.42 @@ -86,13 +79,18 @@
1.43
1.44 static void gst_mythtv_src_finalize (GObject * gobject);
1.45
1.46 +/*
1.47 static GstFlowReturn gst_mythtv_src_create (GstBaseSrc * psrc, guint64 offset,
1.48 guint size, GstBuffer ** outbuf);
1.49 +*/
1.50 +
1.51 +//static GstFlowReturn gst_mythtv_src_chain ( GstPad* pad, GstBuffer* outbuf );
1.52 +static GstFlowReturn gst_mythtv_src_create ( GstPushSrc* psrc, GstBuffer** outbuf );
1.53
1.54 static gboolean gst_mythtv_src_start (GstBaseSrc * bsrc);
1.55 static gboolean gst_mythtv_src_stop (GstBaseSrc * bsrc);
1.56 static gboolean gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size);
1.57 -static gboolean gst_mythtv_src_is_seekable( GstBaseSrc *push_src );
1.58 +//static gboolean gst_mythtv_src_is_seekable( GstBaseSrc *push_src );
1.59
1.60 static gboolean gst_mythtv_src_next_program_chain ( GstMythtvSrc *src );
1.61
1.62 @@ -127,11 +125,11 @@
1.63 "MythTV src");
1.64 }
1.65
1.66 -GST_BOILERPLATE_FULL (GstMythtvSrc, gst_mythtv_src, GstBaseSrc,
1.67 - GST_TYPE_BASE_SRC, _urihandler_init)
1.68 +//GST_BOILERPLATE_FULL (GstMythtvSrc, gst_mythtv_src, GstBaseSrc,
1.69 +// GST_TYPE_BASE_SRC, _urihandler_init)
1.70
1.71 -//GST_BOILERPLATE_FULL (GstMythtvSrc, gst_mythtv_src, GstPushSrc,
1.72 -// GST_TYPE_PUSH_SRC, _urihandler_init)
1.73 +GST_BOILERPLATE_FULL (GstMythtvSrc, gst_mythtv_src, GstPushSrc,
1.74 + GST_TYPE_PUSH_SRC, _urihandler_init)
1.75
1.76 static void
1.77 gst_mythtv_src_base_init (gpointer g_class)
1.78 @@ -140,21 +138,23 @@
1.79
1.80 gst_element_class_add_pad_template (element_class,
1.81 gst_static_pad_template_get (&srctemplate));
1.82 -
1.83 +
1.84 gst_element_class_set_details (element_class, &gst_mythtv_src_details);
1.85
1.86 element_class->change_state = gst_mythtv_src_change_state;
1.87 +
1.88 }
1.89
1.90 static void
1.91 gst_mythtv_src_class_init (GstMythtvSrcClass * klass)
1.92 {
1.93 GObjectClass *gobject_class;
1.94 - //GstPushSrcClass *gstpushsrc_class;
1.95 + GstPushSrcClass *gstpushsrc_class;
1.96 GstBaseSrcClass *gstbasesrc_class;
1.97
1.98 gobject_class = (GObjectClass *) klass;
1.99 gstbasesrc_class = (GstBaseSrcClass *) klass;
1.100 + gstpushsrc_class = (GstPushSrcClass *) klass;
1.101
1.102 gobject_class->set_property = gst_mythtv_src_set_property;
1.103 gobject_class->get_property = gst_mythtv_src_get_property;
1.104 @@ -222,9 +222,10 @@
1.105 gstbasesrc_class->start = gst_mythtv_src_start;
1.106 gstbasesrc_class->stop = gst_mythtv_src_stop;
1.107 gstbasesrc_class->get_size = gst_mythtv_src_get_size;
1.108 - gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable;
1.109 -
1.110 - gstbasesrc_class->create = gst_mythtv_src_create;
1.111 + //gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable;
1.112 +
1.113 + //gstbasesrc_class->create = gst_mythtv_src_create;
1.114 + gstpushsrc_class->create = gst_mythtv_src_create;
1.115
1.116 GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0,
1.117 "MythTV Client Source");
1.118 @@ -265,24 +266,21 @@
1.119
1.120 this->adapter = NULL;
1.121
1.122 - //this->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
1.123 - //gst_element_add_pad (GST_ELEMENT (this), this->sinkpad);
1.124 + //this->th_read_ahead = NULL;
1.125
1.126 - /*
1.127 + this->th_mutex = NULL;
1.128 +
1.129 this->srcpad = gst_pad_new_from_static_template (&srctemplate, "src");
1.130 + //gst_pad_set_chain_function ( GST_BASE_SRC_PAD( GST_BASE_SRC( this ) ),
1.131 + // GST_DEBUG_FUNCPTR ( gst_mythtv_src_chain ) );
1.132 gst_element_add_pad (GST_ELEMENT (this), this->srcpad);
1.133 - */
1.134
1.135 - gst_base_src_set_format( GST_BASE_SRC( this ), GST_FORMAT_BYTES );
1.136 + //gst_base_src_set_format( GST_BASE_SRC( this ), GST_FORMAT_BYTES );
1.137
1.138 gst_base_src_set_live ( GST_BASE_SRC( this ), TRUE );
1.139 -
1.140 +
1.141 // gst_pad_set_event_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
1.142 // gst_mythtv_src_handle_event );
1.143 -/*
1.144 - gst_pad_set_query_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
1.145 - gst_mythtv_src_query );
1.146 -*/
1.147
1.148 }
1.149
1.150 @@ -290,6 +288,16 @@
1.151 gst_mythtv_src_finalize (GObject * gobject)
1.152 {
1.153 GstMythtvSrc *this = GST_MYTHTV_SRC (gobject);
1.154 +
1.155 + if ( this->th_mutex != NULL ) {
1.156 + g_static_rec_mutex_free( this->th_mutex );
1.157 + this->th_mutex = NULL;
1.158 + }
1.159 +
1.160 + if ( this->th_read_ahead != NULL ) {
1.161 + gst_task_stop( this->th_read_ahead );
1.162 + this->th_read_ahead = NULL;
1.163 + }
1.164
1.165 if (this->mythtv_caps) {
1.166 gst_caps_unref (this->mythtv_caps);
1.167 @@ -328,19 +336,20 @@
1.168 /* Loop sending the Myth File Transfer request:
1.169 * Retry whilst authentication fails and we supply it. */
1.170 gint len = 0;
1.171 + gint8 *data_ptr = g_malloc0( size );
1.172
1.173 - GST_OBJECT_LOCK(src);
1.174 + //GST_OBJECT_LOCK(src);
1.175
1.176 while ( sizetoread > 0 ) {
1.177
1.178 len = gmyth_file_transfer_read( src->file_transfer,
1.179 - GST_BUFFER_DATA( *outbuf ) + read, sizetoread, TRUE );
1.180 + data_ptr + read, sizetoread, TRUE );
1.181
1.182 if ( len > 0 ) {
1.183 - read += len;
1.184 + read += len;
1.185 sizetoread -= len;
1.186 }
1.187 - else if ( len <= 0 )
1.188 + else if ( len <= 0 )
1.189 {
1.190 read = -1;
1.191
1.192 @@ -366,16 +375,15 @@
1.193 goto get_file_pos;
1.194 g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
1.195 __FUNCTION__, size_tmp );
1.196 - } else if ( abs( src->content_size - src->bytes_read ) < GMYTHTV_TRANSFER_MAX_BUFFER ) {
1.197 - src->prev_content_size = src->content_size;
1.198 + } /*else {
1.199 gint64 new_offset = gmyth_file_transfer_get_file_position( src->file_transfer );
1.200 if ( new_offset > 0 && src->content_size <= new_offset ) {
1.201 src->content_size = new_offset;
1.202 } else {
1.203 src->update_prog_chain = TRUE;
1.204 }
1.205 - }
1.206 - goto done;
1.207 + src->prev_content_size = src->content_size;
1.208 + }*/
1.209 }
1.210 goto done;
1.211 }
1.212 @@ -389,19 +397,21 @@
1.213 if ( read > 0 ) {
1.214 src->read_offset += read;
1.215 src->bytes_read += read;
1.216 - //src->content_size += src->bytes_read;
1.217
1.218 g_print( "[%s]\tBYTES READ (actual) = %d, BYTES READ (cumulative) = %llu, "\
1.219 - "OFFSET = %llu, CONTENT SIZE = %llu.\n", __FUNCTION__, read, src->bytes_read,
1.220 - src->read_offset, src->content_size );
1.221 + "OFFSET = %llu, CONTENT SIZE = %llu.\n", __FUNCTION__, read, src->bytes_read,
1.222 + src->read_offset, src->content_size );
1.223
1.224 GST_BUFFER_SIZE (*outbuf) = read; //GST_BUFFER_SIZE (buffer) = read;
1.225 + GST_BUFFER_MALLOCDATA( *outbuf ) = g_malloc0( GST_BUFFER_SIZE (*outbuf) );
1.226 + GST_BUFFER_DATA( *outbuf ) = GST_BUFFER_MALLOCDATA( *outbuf );
1.227 + g_memmove( GST_BUFFER_DATA( *outbuf ), data_ptr, read );
1.228 GST_BUFFER_OFFSET (*outbuf) = offset; //GST_BUFFER_OFFSET (buffer) = offset;
1.229 GST_BUFFER_OFFSET_END (*outbuf) = offset + read;//GST_BUFFER_OFFSET_END (buffer) = offset + read;
1.230
1.231 g_print( "Got buffer: [%s]\t\tBUFFER --->SIZE = %d, OFFSET = %llu, "\
1.232 - "OFFSET_END = %llu.\n\n", __FUNCTION__, GST_BUFFER_SIZE (*outbuf),
1.233 - GST_BUFFER_OFFSET (*outbuf), GST_BUFFER_OFFSET_END (*outbuf) );
1.234 + "OFFSET_END = %llu.\n\n", __FUNCTION__, GST_BUFFER_SIZE (*outbuf),
1.235 + GST_BUFFER_OFFSET (*outbuf), GST_BUFFER_OFFSET_END (*outbuf) );
1.236
1.237 } else if ( !src->live_tv )
1.238 goto eos;
1.239 @@ -412,58 +422,91 @@
1.240 src->eos = TRUE;
1.241
1.242 done:
1.243 - GST_OBJECT_UNLOCK(src);
1.244 + //GST_OBJECT_UNLOCK(src);
1.245
1.246 return read;
1.247 }
1.248
1.249 +#if 0
1.250 static GstFlowReturn
1.251 gst_mythtv_src_create ( GstBaseSrc * psrc, guint64 offset, guint size, GstBuffer **outbuf)
1.252 {
1.253 GstMythtvSrc *src;
1.254 GstFlowReturn ret = GST_FLOW_OK;
1.255 gint read = -1;
1.256 + gint adapter_size = -1;
1.257 +
1.258 + guint max_adapter_rep = 40;
1.259
1.260 src = GST_MYTHTV_SRC (psrc);
1.261 +
1.262 /* The caller should know the number of bytes and not read beyond EOS. */
1.263 if (G_UNLIKELY (src->eos))
1.264 goto eos;
1.265 if ( G_UNLIKELY (src->update_prog_chain) )
1.266 goto change_progchain;
1.267 +
1.268 + g_static_rec_mutex_lock( src->th_mutex );
1.269
1.270 - GST_OBJECT_LOCK(src);
1.271 + while ( ( ( adapter_size = gst_adapter_available_fast( src->adapter ) ) < size ) &&
1.272 + --max_adapter_rep > 0 )
1.273 + {
1.274 + g_print ( "[%s] %d - Waiting for read_ahead task...\n", __FUNCTION__, max_adapter_rep );
1.275 + GST_TASK_WAIT( src->th_read_ahead );
1.276 + }
1.277 +
1.278 + g_static_rec_mutex_unlock( src->th_mutex );
1.279
1.280 - if (G_UNLIKELY (src->read_offset != offset)) {
1.281 - gint64 new_offset = gmyth_file_transfer_seek(src->file_transfer, offset, SEEK_SET);
1.282 - g_print( "[%s] SRC Offset = %lld, NEW actual backend SEEK Offset = %lld.\n",
1.283 - __FUNCTION__, src->read_offset, new_offset );
1.284 - if (G_UNLIKELY (new_offset < 0 ) )//|| new_offset != src->read_offset)) {
1.285 - {
1.286 - GST_OBJECT_UNLOCK(src);
1.287 - if ( src->live_tv )
1.288 - goto change_progchain;
1.289 - else
1.290 - goto eos;
1.291 - }
1.292 -
1.293 + gint64 new_offset = -1;
1.294 + /* just get from the adapter, no network effort... */
1.295 + if ( offset > src->adapter_offset && size <= adapter_size )
1.296 + {
1.297 +
1.298 + GstBuffer *buf = gst_adapter_take_buffer( src->adapter, size );
1.299 + *outbuf = gst_buffer_create_sub( buf, offset, size );
1.300 + src->read_offset = new_offset = offset;
1.301 + read = size;
1.302 +
1.303 + gst_adapter_flush( src->adapter, size );
1.304 +
1.305 + } else {
1.306 + /* no data on adapter... do all these mythtv network calls! */
1.307 +
1.308 + /* verify if it needs to seek */
1.309 + if ( src->read_offset != offset )
1.310 + {
1.311 +
1.312 + new_offset = gmyth_file_transfer_seek( src->file_transfer, offset, SEEK_SET );
1.313 +
1.314 + g_print( "[%s] SRC Offset = %lld, NEW actual backend SEEK Offset = %lld.\n",
1.315 + __FUNCTION__, src->read_offset, new_offset );
1.316 + if ( G_UNLIKELY (new_offset < 0 ) )
1.317 + {
1.318 + if ( src->live_tv )
1.319 + goto change_progchain;
1.320 + else
1.321 + goto eos;
1.322 + }
1.323 +
1.324 + }
1.325 +
1.326 src->read_offset = offset;
1.327 - }
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 - src->read_offset, size,
1.333 - //src->icy_caps ? src->icy_caps :
1.334 - GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf);
1.335 -
1.336 - if (G_UNLIKELY (ret != GST_FLOW_OK)) {
1.337 - if ( src->live_tv )
1.338 - goto change_progchain;
1.339 - else
1.340 - goto done;
1.341 - }
1.342 -
1.343 - read = do_read_request_response ( src, src->read_offset, size, outbuf );
1.344 +
1.345 + /* Create the buffer. */
1.346 + ret = gst_pad_alloc_buffer ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
1.347 + src->read_offset, size,
1.348 + GST_PAD_CAPS ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)) ), outbuf);
1.349 +
1.350 + if (G_UNLIKELY (ret != GST_FLOW_OK)) {
1.351 + if ( src->live_tv )
1.352 + goto change_progchain;
1.353 + else
1.354 + goto done;
1.355 + }
1.356 +
1.357 + read = do_read_request_response ( src, src->read_offset, size, outbuf );
1.358 +
1.359 + }
1.360
1.361 if (G_UNLIKELY (src->update_prog_chain) )
1.362 goto change_progchain;
1.363 @@ -474,6 +517,29 @@
1.364 else
1.365 goto read_error;
1.366 }
1.367 +
1.368 + if ( read > 0 ) {
1.369 + src->read_offset += read;
1.370 + src->bytes_read += read;
1.371 +
1.372 + #if 0
1.373 + g_print( "[%s]\tBYTES READ (actual) = %d, BYTES READ (cumulative) = %llu, "\
1.374 + "OFFSET = %llu, CONTENT SIZE = %llu.\n", __FUNCTION__, read, src->bytes_read,
1.375 + src->read_offset, src->content_size );
1.376 +
1.377 + GST_BUFFER_SIZE (*outbuf) = read; //GST_BUFFER_SIZE (buffer) = read;
1.378 + //GST_BUFFER_MALLOCDATA( *outbuf ) = g_malloc0( GST_BUFFER_SIZE (*outbuf) );
1.379 + //GST_BUFFER_DATA( *outbuf ) = GST_BUFFER_MALLOCDATA( *outbuf );
1.380 + //g_memmove( GST_BUFFER_DATA( *outbuf ), data_ptr, read );
1.381 + GST_BUFFER_OFFSET (*outbuf) = offset; //GST_BUFFER_OFFSET (buffer) = offset;
1.382 + GST_BUFFER_OFFSET_END (*outbuf) = offset + read;//GST_BUFFER_OFFSET_END (buffer) = offset + read;
1.383 +
1.384 + g_print( "Got buffer: [%s]\t\tBUFFER --->SIZE = %d, OFFSET = %llu, "\
1.385 + "OFFSET_END = %llu.\n\n", __FUNCTION__, GST_BUFFER_SIZE (*outbuf),
1.386 + GST_BUFFER_OFFSET (*outbuf), GST_BUFFER_OFFSET_END (*outbuf) );
1.387 + #endif
1.388 +
1.389 + }
1.390
1.391 done:
1.392 {
1.393 @@ -502,13 +568,101 @@
1.394 GST_ELEMENT_ERROR (src, RESOURCE, READ,
1.395 (NULL), ("Seek failed, go to the next program info... (%i, %s)", read,
1.396 src->uri_name));
1.397 +
1.398 + gst_pad_push_event ( GST_BASE_SRC_PAD (GST_BASE_SRC (src)),
1.399 + gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1, 0 ) );
1.400 // go to the next program chain
1.401 src->unique_setup = FALSE;
1.402 src->update_prog_chain = TRUE;
1.403
1.404 - //GST_OBJECT_LOCK(src);
1.405 gst_mythtv_src_next_program_chain( src );
1.406 - //GST_OBJECT_UNLOCK(src);
1.407 +
1.408 + return GST_FLOW_ERROR_NO_DATA;
1.409 + }
1.410 +
1.411 +}
1.412 +#endif
1.413 +
1.414 +static GstFlowReturn
1.415 +gst_mythtv_src_create ( GstPushSrc* psrc, GstBuffer** outbuf )
1.416 +{
1.417 + GstMythtvSrc *src;
1.418 + GstFlowReturn ret = GST_FLOW_OK;
1.419 + gint read = -1;
1.420 +
1.421 + src = GST_MYTHTV_SRC ( psrc );
1.422 +
1.423 + /* The caller should know the number of bytes and not read beyond EOS. */
1.424 + if (G_UNLIKELY (src->eos))
1.425 + goto eos;
1.426 + if ( G_UNLIKELY (src->update_prog_chain) )
1.427 + goto change_progchain;
1.428 +
1.429 + //gint64 new_offset = -1;
1.430 + /* just get from the adapter, no network effort... */
1.431 + //do
1.432 + //{
1.433 + /* Create the buffer. */
1.434 + ret = gst_pad_alloc_buffer ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
1.435 + GST_BUFFER_OFFSET_NONE, MAX_READ_SIZE,
1.436 + GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf );
1.437 +
1.438 + if (G_UNLIKELY (ret != GST_FLOW_OK)) {
1.439 + if ( src->live_tv )
1.440 + goto change_progchain;
1.441 + else
1.442 + goto done;
1.443 + }
1.444 +
1.445 + read = do_read_request_response ( src, src->read_offset, MAX_READ_SIZE, outbuf );
1.446 +
1.447 + if (G_UNLIKELY (src->update_prog_chain) )
1.448 + goto change_progchain;
1.449 +
1.450 + if (G_UNLIKELY (read <= 0) || *outbuf == NULL) {
1.451 + if ( src->live_tv )
1.452 + goto change_progchain;
1.453 + else
1.454 + goto read_error;
1.455 + }
1.456 +
1.457 + //} while ( TRUE );
1.458 +
1.459 +done:
1.460 + {
1.461 + const gchar *reason = gst_flow_get_name (ret);
1.462 +
1.463 + GST_DEBUG_OBJECT (src, "DONE task, reason %s", reason);
1.464 + return ret;
1.465 + }
1.466 +eos:
1.467 + {
1.468 + const gchar *reason = gst_flow_get_name (ret);
1.469 +
1.470 + GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);
1.471 + return GST_FLOW_UNEXPECTED;
1.472 + }
1.473 + /* ERRORS */
1.474 +read_error:
1.475 + {
1.476 + GST_ELEMENT_ERROR (src, RESOURCE, READ,
1.477 + (NULL), ("Could not read any bytes (%i, %s)", read,
1.478 + src->uri_name));
1.479 + return GST_FLOW_ERROR;
1.480 + }
1.481 +change_progchain:
1.482 + {
1.483 + GST_ELEMENT_ERROR (src, RESOURCE, READ,
1.484 + (NULL), ("Seek failed, go to the next program info... (%i, %s)", read,
1.485 + src->uri_name));
1.486 +
1.487 + gst_pad_push_event ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
1.488 + gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1, 0 ) );
1.489 + // go to the next program chain
1.490 + src->unique_setup = FALSE;
1.491 + src->update_prog_chain = TRUE;
1.492 +
1.493 + gst_mythtv_src_next_program_chain( src );
1.494
1.495 return GST_FLOW_ERROR_NO_DATA;
1.496 }
1.497 @@ -541,6 +695,43 @@
1.498
1.499 }
1.500
1.501 +#if 0
1.502 +static void
1.503 +gst_mythtv_src_read_ahead ( void *data ) {
1.504 +
1.505 + GstMythtvSrc *src = NULL;
1.506 +
1.507 + GstBuffer *buffer = NULL;
1.508 +
1.509 + guint size = 512;
1.510 +
1.511 + gint read = 0;
1.512 +
1.513 + src = GST_MYTHTV_SRC( data );
1.514 +
1.515 + GST_PAD_STREAM_TRYLOCK( GST_BASE_SRC_PAD (GST_BASE_SRC (src)) );
1.516 +
1.517 + /*if ( gst_adapter_available( src->adapter ) ) && ( read < MAX_READ_SIZE )) */
1.518 + do {
1.519 + buffer = gst_buffer_new_and_alloc( size );
1.520 +
1.521 + read += do_read_request_response ( src, src->adapter_offset, size, &buffer );
1.522 +
1.523 + gst_adapter_push( src->adapter, buffer );
1.524 +
1.525 + //gst_buffer_unref( buffer );
1.526 + } while ( read < MAX_READ_SIZE );
1.527 +
1.528 + GST_PAD_BLOCK_SIGNAL( GST_BASE_SRC_PAD (GST_BASE_SRC (src)) );
1.529 +
1.530 + GST_PAD_STREAM_UNLOCK( GST_BASE_SRC_PAD (GST_BASE_SRC (src)) );
1.531 +
1.532 + gst_object_unref( src );
1.533 +
1.534 + return;
1.535 +}
1.536 +#endif
1.537 +
1.538 /* create a socket for connecting to remote server */
1.539 static gboolean
1.540 gst_mythtv_src_start ( GstBaseSrc * bsrc )
1.541 @@ -560,13 +751,13 @@
1.542 goto done;
1.543 }
1.544
1.545 - GST_OBJECT_LOCK(src);
1.546 + //GST_OBJECT_LOCK(src);
1.547
1.548 if ( src->live_tv ) {
1.549 src->spawn_livetv = gmyth_livetv_new( );
1.550 if ( gmyth_livetv_setup( src->spawn_livetv ) == FALSE ) {
1.551 ret = FALSE;
1.552 - GST_OBJECT_UNLOCK( src );
1.553 + //GST_OBJECT_UNLOCK( src );
1.554 goto init_failed;
1.555 }
1.556
1.557 @@ -585,7 +776,7 @@
1.558 g_string_new( src->uri_name ), -1, src->mythtv_version );
1.559
1.560 if ( src->file_transfer == NULL ) {
1.561 - GST_OBJECT_UNLOCK(src);
1.562 + //GST_OBJECT_UNLOCK(src);
1.563
1.564 goto init_failed;
1.565 }
1.566 @@ -607,7 +798,7 @@
1.567 ret = gmyth_file_transfer_setup( &(src->file_transfer), src->live_tv );
1.568
1.569 if ( ret == FALSE ) {
1.570 - GST_OBJECT_UNLOCK(src);
1.571 + //GST_OBJECT_UNLOCK(src);
1.572 #ifndef GST_DISABLE_GST_DEBUG
1.573 if ( src->mythtv_msgs_dbg )
1.574 g_printerr( "MythTV FileTransfer request failed when setting up socket connection!\n" );
1.575 @@ -618,8 +809,14 @@
1.576 src->content_size = src->file_transfer->filesize;
1.577
1.578 src->do_start = FALSE;
1.579 +
1.580 + if ( src->live_tv ) {
1.581 + //src->adapter = gst_adapter_new();
1.582 + //g_static_rec_mutex_init( src->th_mutex );
1.583 + //src->th_read_ahead = gst_task_create( (GstTaskFunction)gst_mythtv_src_read_ahead, src );
1.584 + }
1.585
1.586 - GST_OBJECT_UNLOCK(src);
1.587 + //GST_OBJECT_UNLOCK(src);
1.588
1.589 done:
1.590 return TRUE;
1.591 @@ -645,13 +842,15 @@
1.592 GST_ELEMENT_ERROR (src, RESOURCE, READ,
1.593 (NULL), ("Seek failed, go to the next program info... (%s)",
1.594 src->uri_name));
1.595 +
1.596 + gst_pad_push_event ( GST_BASE_SRC_PAD (GST_BASE_SRC (src)),
1.597 + gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1, 0 ) );
1.598 +
1.599 // go to the next program chain
1.600 src->unique_setup = FALSE;
1.601 src->update_prog_chain = TRUE;
1.602
1.603 - //GST_OBJECT_LOCK(src);
1.604 gst_mythtv_src_next_program_chain( src );
1.605 - //GST_OBJECT_UNLOCK(src);
1.606
1.607 return TRUE;
1.608 }
1.609 @@ -673,6 +872,8 @@
1.610 } else {
1.611 goto done;
1.612 }
1.613 +
1.614 + GST_PAD_STREAM_LOCK( GST_BASE_SRC_PAD (GST_BASE_SRC (src)) );
1.615
1.616 if (src->file_transfer) {
1.617 g_object_unref (src->file_transfer);
1.618 @@ -748,11 +949,13 @@
1.619 while ( src->content_size < GMYTHTV_TRANSFER_MAX_BUFFER*4 )
1.620 src->content_size = gst_mythtv_src_get_position( src );
1.621
1.622 - src->read_offset = 0;
1.623 -
1.624 - src->update_prog_chain = FALSE;
1.625 + src->read_offset = 0;
1.626
1.627 done:
1.628 + src->update_prog_chain = FALSE;
1.629 +
1.630 + GST_PAD_STREAM_UNLOCK( GST_BASE_SRC_PAD (GST_BASE_SRC (src)) );
1.631 +
1.632 return TRUE;
1.633
1.634 /* ERRORS */
1.635 @@ -1007,11 +1210,13 @@
1.636 }
1.637 #endif
1.638
1.639 +#if 0
1.640 static gboolean
1.641 gst_mythtv_src_is_seekable( GstBaseSrc *push_src )
1.642 {
1.643 return TRUE;
1.644 }
1.645 +#endif
1.646
1.647 #if 0
1.648 static GstFlowReturn
1.649 @@ -1172,15 +1377,14 @@
1.650 case GST_STATE_CHANGE_PAUSED_TO_READY:
1.651 g_print( "[%s] PAUSED to READY called!\n", __FUNCTION__ );
1.652 if ( src->live_tv && src->update_prog_chain ) {
1.653 - GstPad *pad_peer;
1.654 - gst_pad_push_event ( pad_peer = gst_pad_get_peer( GST_BASE_SRC_PAD (GST_BASE_SRC (src)) ),
1.655 - gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_BYTES, 0, -1, 0 ) );
1.656 +
1.657 + gst_pad_push_event ( GST_BASE_SRC_PAD (GST_BASE_SRC (src)),
1.658 + gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1, 0 ) );
1.659 +
1.660 src->read_offset = 0;
1.661 src->bytes_read = 0;
1.662 - src->unique_setup = FALSE;
1.663 - GST_OBJECT_LOCK( src );
1.664 + src->unique_setup = FALSE;
1.665 gst_mythtv_src_next_program_chain( src );
1.666 - GST_OBJECT_UNLOCK( src );
1.667 }
1.668 break;
1.669 default:
2.1 --- a/gst-plugins-mythtv/src/gstmythtvsrc.h Mon Nov 13 19:11:55 2006 +0000
2.2 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.h Mon Nov 13 19:58:37 2006 +0000
2.3 @@ -41,15 +41,14 @@
2.4 typedef struct _GstMythtvSrc GstMythtvSrc;
2.5 typedef struct _GstMythtvSrcClass GstMythtvSrcClass;
2.6
2.7 -
2.8 -typedef enum {
2.9 +typedef enum {
2.10 GST_MYTHTV_SRC_FILE_TRANSFER,
2.11 GST_MYTHTV_SRC_NEXT_PROGRAM_CHAIN,
2.12 GST_MYTHTV_SRC_INVALID_DATA
2.13 } GstMythtvState;
2.14
2.15 struct _GstMythtvSrc {
2.16 - GstBaseSrc element;
2.17 + GstPushSrc element;
2.18
2.19 /* MythFileTransfer */
2.20 GMythFileTransfer *file_transfer;
2.21 @@ -74,7 +73,7 @@
2.22 guint64 bytes_read;
2.23
2.24 gint64 read_offset;
2.25 - gint64 old_offset;
2.26 + gint64 adapter_offset;
2.27
2.28 gboolean eos;
2.29
2.30 @@ -88,7 +87,7 @@
2.31
2.32 gint live_tv_id;
2.33
2.34 - gint channel_num;
2.35 + gint channel_num;
2.36
2.37 guint mode;
2.38
2.39 @@ -98,6 +97,10 @@
2.40 GstPad *sinkpad;
2.41 GstPad *srcpad;
2.42
2.43 + GstTask *th_read_ahead;
2.44 +
2.45 + GStaticRecMutex *th_mutex;
2.46 +
2.47 GstAdapter *adapter;
2.48
2.49 /* enable Myth TV debug messages */
2.50 @@ -107,7 +110,7 @@
2.51 };
2.52
2.53 struct _GstMythtvSrcClass {
2.54 - GstBaseSrcClass parent_class;
2.55 + GstPushSrcClass parent_class;
2.56 };
2.57
2.58 GType gst_mythtv_src_get_type (void);