[svn r91] Added changes proposed by melunko (buffer on plug-in).
1.1 --- a/gst-plugins-mythtv/src/gstmythtvsrc.c Thu Nov 16 21:30:58 2006 +0000
1.2 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.c Fri Nov 17 13:09:12 2006 +0000
1.3 @@ -36,17 +36,19 @@
1.4
1.5 #define GMYTHTV_VERSION_DEFAULT 30
1.6
1.7 -#define GMYTHTV_TRANSFER_MAX_WAITS 100
1.8 +#define GMYTHTV_TRANSFER_MAX_WAITS 100
1.9
1.10 -#define GMYTHTV_TRANSFER_MAX_BUFFER 128*1024
1.11 +#define GMYTHTV_TRANSFER_MAX_BUFFER 128*1024
1.12 //( 32*1024 )
1.13
1.14 /* 4*1024 ??? */
1.15 -#define MAX_READ_SIZE 2*1024
1.16 +#define MAX_READ_SIZE 12*1024
1.17 //( 32*1024 )
1.18
1.19 #define GST_FLOW_ERROR_NO_DATA -101
1.20
1.21 +#define INTERNAL_BUFFER_SIZE 18*1024
1.22 +
1.23 /* stablish a maximum iteration value to the IS_RECORDING message */
1.24 static guint wait_to_transfer = 0;
1.25
1.26 @@ -108,11 +110,12 @@
1.27
1.28 static gboolean gst_mythtv_src_handle_query (GstPad * pad, GstQuery * query);
1.29
1.30 -//static gboolean gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event);
1.31 -//static gboolean gst_mythtv_src_query ( GstPad * pad, GstQuery * query );
1.32 +static gboolean gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event);
1.33
1.34 -static gint do_read_request_response (GstMythtvSrc *src, guint64 offset,
1.35 - guint size, GstBuffer **outbuf);
1.36 +static gint do_read_request_response (GstMythtvSrc * src, guint64 offset,
1.37 + guint size, gint8 **data_ptr);
1.38 +
1.39 +GStaticRecMutex th_mutex = G_STATIC_REC_MUTEX_INIT;
1.40
1.41 static void
1.42 _urihandler_init (GType type)
1.43 @@ -281,8 +284,8 @@
1.44
1.45 //gst_base_src_set_live ( GST_BASE_SRC( this ), TRUE );
1.46
1.47 - // gst_pad_set_event_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
1.48 - // gst_mythtv_src_handle_event );
1.49 + gst_pad_set_event_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
1.50 + gst_mythtv_src_handle_event );
1.51 gst_pad_set_query_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
1.52 gst_mythtv_src_handle_query );
1.53
1.54 @@ -293,11 +296,6 @@
1.55 {
1.56 GstMythtvSrc *this = GST_MYTHTV_SRC (gobject);
1.57
1.58 - if ( this->th_mutex != NULL ) {
1.59 - g_static_rec_mutex_free( this->th_mutex );
1.60 - this->th_mutex = NULL;
1.61 - }
1.62 -
1.63 if ( this->th_read_ahead != NULL ) {
1.64 gst_task_stop( this->th_read_ahead );
1.65 this->th_read_ahead = NULL;
1.66 @@ -330,7 +328,7 @@
1.67 }
1.68
1.69 static gint
1.70 -do_read_request_response (GstMythtvSrc * src, guint64 offset, guint size, GstBuffer **outbuf)
1.71 +do_read_request_response (GstMythtvSrc * src, guint64 offset, guint size, gint8 **data_ptr)
1.72 {
1.73 gint read = 0;
1.74 guint sizetoread = size;
1.75 @@ -340,84 +338,54 @@
1.76 /* Loop sending the Myth File Transfer request:
1.77 * Retry whilst authentication fails and we supply it. */
1.78 gint len = 0;
1.79 - gint8 *data_ptr = g_malloc0( size );
1.80 + //*data_ptr = g_malloc0( size );
1.81
1.82 - GST_OBJECT_LOCK(src);
1.83 -
1.84 - while ( sizetoread > 0 ) {
1.85 + //while ( sizetoread > 0 ) {
1.86
1.87 len = gmyth_file_transfer_read( src->file_transfer,
1.88 - data_ptr + read, sizetoread, TRUE );
1.89 + *data_ptr + offset + read, sizetoread, TRUE );
1.90
1.91 if ( len > 0 ) {
1.92 read += len;
1.93 sizetoread -= len;
1.94 }
1.95 - else if ( len <= 0 )
1.96 + else if ( len < 0 )
1.97 {
1.98 - read = -1;
1.99 + read = -1;
1.100
1.101 if ( src->live_tv == FALSE )
1.102 {
1.103 - goto eos;
1.104 + goto eos;
1.105 }
1.106 else
1.107 {
1.108 - if ( len == GMYTHTV_FILE_TRANSFER_READ_ERROR ) { /* -314 */
1.109 - src->update_prog_chain = TRUE;
1.110 - goto done;
1.111 - } else
1.112 - if ( abs( src->content_size - src->bytes_read ) < GMYTHTV_TRANSFER_MAX_BUFFER ) {
1.113 - src->update_prog_chain = TRUE;
1.114 - if ( src->enable_timing_position ) {
1.115 - gint64 size_tmp = 0;
1.116 - get_file_pos:
1.117 - size_tmp = gmyth_file_transfer_get_file_position( src->file_transfer );
1.118 - if ( size_tmp > ( src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER ) )
1.119 - src->content_size = size_tmp;
1.120 - else if ( size_tmp > 0 )
1.121 - goto get_file_pos;
1.122 - g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
1.123 - __FUNCTION__, size_tmp );
1.124 - } /*else {
1.125 - gint64 new_offset = gmyth_file_transfer_get_file_position( src->file_transfer );
1.126 - if ( new_offset > 0 && src->content_size <= new_offset ) {
1.127 - src->content_size = new_offset;
1.128 - } else {
1.129 - src->update_prog_chain = TRUE;
1.130 - }
1.131 - src->prev_content_size = src->content_size;
1.132 - }*/
1.133 - }
1.134 - goto done;
1.135 - }
1.136 + if ( len == GMYTHTV_FILE_TRANSFER_READ_ERROR ) { /* -314 */
1.137 + src->update_prog_chain = TRUE;
1.138 + goto done;
1.139 + } else if ( abs( src->content_size - src->bytes_read ) < GMYTHTV_TRANSFER_MAX_BUFFER ) {
1.140 + src->update_prog_chain = TRUE;
1.141 + if ( src->enable_timing_position ) {
1.142 + gint64 size_tmp = 0;
1.143 +get_file_pos:
1.144 + size_tmp = gmyth_file_transfer_get_file_position( src->file_transfer );
1.145 + if ( size_tmp > ( src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER ) )
1.146 + src->content_size = size_tmp;
1.147 + else if ( size_tmp > 0 )
1.148 + goto get_file_pos;
1.149 + g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
1.150 + __FUNCTION__, size_tmp );
1.151 + }
1.152 + }
1.153 + goto done;
1.154 + }
1.155
1.156 }
1.157
1.158 if ( read == sizetoread )
1.159 - break;
1.160 - }
1.161 + goto done;
1.162 + //}
1.163
1.164 - if ( read > 0 ) {
1.165 - src->read_offset += read;
1.166 - src->bytes_read += read;
1.167 -
1.168 - g_print( "[%s]\tBYTES READ (actual) = %d, BYTES READ (cumulative) = %llu, "\
1.169 - "OFFSET = %llu, CONTENT SIZE = %llu.\n", __FUNCTION__, read, src->bytes_read,
1.170 - src->read_offset, src->content_size );
1.171 -
1.172 - GST_BUFFER_SIZE (*outbuf) = read; //GST_BUFFER_SIZE (buffer) = read;
1.173 - GST_BUFFER_MALLOCDATA( *outbuf ) = g_malloc0( GST_BUFFER_SIZE (*outbuf) );
1.174 - GST_BUFFER_DATA( *outbuf ) = GST_BUFFER_MALLOCDATA( *outbuf );
1.175 - g_memmove( GST_BUFFER_DATA( *outbuf ), data_ptr, read );
1.176 - GST_BUFFER_OFFSET (*outbuf) = offset; //GST_BUFFER_OFFSET (buffer) = offset;
1.177 - GST_BUFFER_OFFSET_END (*outbuf) = offset + read;//GST_BUFFER_OFFSET_END (buffer) = offset + read;
1.178 -
1.179 - g_print( "Got buffer: [%s]\t\tBUFFER --->SIZE = %d, OFFSET = %llu, "\
1.180 - "OFFSET_END = %llu.\n\n", __FUNCTION__, GST_BUFFER_SIZE (*outbuf),
1.181 - GST_BUFFER_OFFSET (*outbuf), GST_BUFFER_OFFSET_END (*outbuf) );
1.182 -
1.183 - } else if ( !src->live_tv )
1.184 + if ( read < 0 && !src->live_tv )
1.185 goto eos;
1.186
1.187 goto done;
1.188 @@ -426,7 +394,6 @@
1.189 src->eos = TRUE;
1.190
1.191 done:
1.192 - GST_OBJECT_UNLOCK(src);
1.193
1.194 return read;
1.195 }
1.196 @@ -450,7 +417,7 @@
1.197 if ( G_UNLIKELY (src->update_prog_chain) )
1.198 goto change_progchain;
1.199
1.200 - g_static_rec_mutex_lock( src->th_mutex );
1.201 + g_static_rec_mutex_lock( th_mutexth_mutex );
1.202
1.203 while ( ( ( adapter_size = gst_adapter_available_fast( src->adapter ) ) < size ) &&
1.204 --max_adapter_rep > 0 )
1.205 @@ -459,7 +426,7 @@
1.206 GST_TASK_WAIT( src->th_read_ahead );
1.207 }
1.208
1.209 - g_static_rec_mutex_unlock( src->th_mutex );
1.210 + g_static_rec_mutex_unlock( th_mutexth_mutex );
1.211
1.212 gint64 new_offset = -1;
1.213 /* just get from the adapter, no network effort... */
1.214 @@ -593,47 +560,133 @@
1.215 GstMythtvSrc *src;
1.216 GstFlowReturn ret = GST_FLOW_OK;
1.217 gint read = -1;
1.218 -
1.219 + gint adapter_size = 0;
1.220 + guint max_adapter_rep = 1;
1.221 +
1.222 src = GST_MYTHTV_SRC ( psrc );
1.223 -
1.224 +
1.225 /* The caller should know the number of bytes and not read beyond EOS. */
1.226 if (G_UNLIKELY (src->eos))
1.227 goto eos;
1.228 if ( G_UNLIKELY (src->update_prog_chain) )
1.229 goto change_progchain;
1.230 +
1.231 + //g_static_rec_mutex_lock( &th_mutex );
1.232 +
1.233 + while ( src->adapter != NULL && ( ( adapter_size = gst_adapter_available_fast( src->adapter ) ) < MAX_READ_SIZE ) &&
1.234 + --max_adapter_rep > 0 )
1.235 + {
1.236 + g_print ( "[%s] %d - Waiting for read_ahead task...\n", __FUNCTION__, max_adapter_rep );
1.237 + //GST_TASK_WAIT( src->th_read_ahead );
1.238 + }
1.239 +
1.240 + //gst_task_pause( src->th_read_ahead );
1.241 +
1.242 + //g_static_rec_mutex_unlock( &th_mutex );
1.243
1.244 /* just get from the adapter, no network effort... */
1.245 - /* Create the buffer. */
1.246 - ret = gst_pad_alloc_buffer ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
1.247 - src->read_offset /*GST_BUFFER_OFFSET_NONE*/, MAX_READ_SIZE,
1.248 - GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf );
1.249 + if ( adapter_size > 0 )
1.250 + {
1.251 + //g_static_rec_mutex_lock( &th_mutex );
1.252
1.253 - if (G_UNLIKELY (ret != GST_FLOW_OK)) {
1.254 - if ( src->live_tv )
1.255 - goto change_progchain;
1.256 - else
1.257 - goto done;
1.258 - }
1.259 -
1.260 - read = do_read_request_response ( src, src->read_offset, MAX_READ_SIZE, outbuf );
1.261 -
1.262 - if ( G_UNLIKELY (src->update_prog_chain) )
1.263 - goto change_progchain;
1.264 + *outbuf = gst_adapter_take_buffer( src->adapter, adapter_size );
1.265 + // src->read_offset += size;
1.266 + read = adapter_size;
1.267
1.268 - if (G_UNLIKELY (read <= 0) || *outbuf == NULL) {
1.269 - if ( src->live_tv )
1.270 - goto change_progchain;
1.271 - else
1.272 - goto read_error;
1.273 + gst_adapter_flush( src->adapter, adapter_size );
1.274 + //g_static_rec_mutex_unlock( &th_mutex );
1.275 +
1.276 + } else {
1.277 + guint size = (src->buffer_remain < MAX_READ_SIZE) ? src->buffer_remain : MAX_READ_SIZE;
1.278 +
1.279 + g_print ( "[%s]\t\tCreate: buffer_offset: %d, buffer_remain: %d\n", __FUNCTION__,
1.280 + (gint) src->buffer_offset,
1.281 + (gint) src->buffer_remain);
1.282 +
1.283 + /* Create the buffer. */
1.284 + ret = gst_pad_alloc_buffer ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
1.285 + src->read_offset /*GST_BUFFER_OFFSET_NONE*/, size,
1.286 + GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf );
1.287 +
1.288 + if (G_UNLIKELY (ret != GST_FLOW_OK)) {
1.289 + if ( src->live_tv )
1.290 + goto change_progchain;
1.291 + else
1.292 + goto done;
1.293 + }
1.294 +
1.295 + if (src->buffer_remain < MAX_READ_SIZE) {
1.296 + gint8 *tmp_buffer = g_malloc0( INTERNAL_BUFFER_SIZE ); // FIXME: DON'T ALLOC EVERY TIME
1.297 +
1.298 + memcpy (tmp_buffer, src->buffer + src->buffer_offset, src->buffer_remain);
1.299 +
1.300 + read = do_read_request_response( src, 0, INTERNAL_BUFFER_SIZE - src->buffer_remain, &tmp_buffer );
1.301 +
1.302 + if (G_UNLIKELY (read < 0)) {
1.303 + if ( src->live_tv )
1.304 + goto change_progchain;
1.305 + else
1.306 + goto read_error;
1.307 + }
1.308 +
1.309 + if ( G_UNLIKELY (src->update_prog_chain) )
1.310 + goto change_progchain;
1.311 +
1.312 + //len = gmyth_file_transfer_read( src->file_transfer,
1.313 + // tmp_buffer + src->buffer_remain, INTERNAL_BUFFER_SIZE - src->buffer_remain, TRUE );
1.314 + // fixme: handle eos
1.315 + // fixme: can I deallocate the previous buffer here?
1.316 + g_memmove( src->buffer + src->buffer_remain, tmp_buffer, read);
1.317 + src->buffer_offset = 0;
1.318 + src->buffer_remain = src->buffer_remain + read;
1.319 +
1.320 + // g_free( tmp_buffer );
1.321 +
1.322 + }
1.323 +
1.324 + g_print( "[%s] read = %d, buffer_remain = %d\n", __FUNCTION__, read, src->buffer_remain );
1.325 +
1.326 + GST_BUFFER_SIZE (*outbuf) = ( src->buffer_remain < MAX_READ_SIZE) ? src->buffer_remain : MAX_READ_SIZE;
1.327 + GST_BUFFER_MALLOCDATA( *outbuf ) = g_malloc0( GST_BUFFER_SIZE (*outbuf) );
1.328 + GST_BUFFER_DATA( *outbuf ) = GST_BUFFER_MALLOCDATA( *outbuf );
1.329 + g_memmove( GST_BUFFER_DATA( (*outbuf) ), src->buffer + src->buffer_offset, GST_BUFFER_SIZE(*outbuf) );
1.330 + GST_BUFFER_OFFSET (*outbuf) = src->read_offset;
1.331 + GST_BUFFER_OFFSET_END (*outbuf) = src->read_offset + GST_BUFFER_SIZE (*outbuf);
1.332 +
1.333 + src->buffer_offset += GST_BUFFER_SIZE (*outbuf);
1.334 + src->buffer_remain -= GST_BUFFER_SIZE (*outbuf);
1.335 +
1.336 + src->read_offset += GST_BUFFER_SIZE (*outbuf);
1.337 + src->bytes_read += GST_BUFFER_SIZE (*outbuf);
1.338 + g_print ( "[%s]\t\tBuffer output with size: %d\n", __FUNCTION__, GST_BUFFER_SIZE (*outbuf) );
1.339 +
1.340 + g_print( "[%s]\tBYTES READ (actual) = %d, BYTES READ (cumulative) = %llu, "\
1.341 + "OFFSET = %llu, CONTENT SIZE = %llu.\n", __FUNCTION__, read, src->bytes_read,
1.342 + src->read_offset, src->content_size );
1.343 +
1.344 + g_print( "Got buffer: [%s]\t\tBUFFER --->SIZE = %d, OFFSET = %llu, "\
1.345 + "OFFSET_END = %llu.\n\n", __FUNCTION__, GST_BUFFER_SIZE (*outbuf),
1.346 + GST_BUFFER_OFFSET (*outbuf), GST_BUFFER_OFFSET_END (*outbuf) );
1.347 +
1.348 + /* just get from the adapter, no network effort... */
1.349 +
1.350 }
1.351
1.352 + return ret;
1.353 +
1.354 + //g_static_rec_mutex_lock( &th_mutex );
1.355 +
1.356 + //GST_TASK_SIGNAL( src->th_read_ahead );
1.357 +
1.358 + //g_static_rec_mutex_unlock( &th_mutex );
1.359 +
1.360 done:
1.361 - {
1.362 + {
1.363 const gchar *reason = gst_flow_get_name (ret);
1.364
1.365 GST_DEBUG_OBJECT (src, "DONE task, reason %s", reason);
1.366 - return ret;
1.367 - }
1.368 + return ret;
1.369 + }
1.370 eos:
1.371 {
1.372 const gchar *reason = gst_flow_get_name (ret);
1.373 @@ -646,23 +699,23 @@
1.374 {
1.375 GST_ELEMENT_ERROR (src, RESOURCE, READ,
1.376 (NULL), ("Could not read any bytes (%i, %s)", read,
1.377 - src->uri_name));
1.378 + src->uri_name));
1.379 return GST_FLOW_ERROR;
1.380 }
1.381 change_progchain:
1.382 {
1.383 GST_ELEMENT_ERROR (src, RESOURCE, READ,
1.384 - (NULL), ("Seek failed, go to the next program info... (%i, %s)", read,
1.385 - src->uri_name));
1.386 -
1.387 - gst_pad_push_event ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
1.388 - gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1, 0 ) );
1.389 - // go to the next program chain
1.390 - src->unique_setup = FALSE;
1.391 - src->update_prog_chain = TRUE;
1.392 -
1.393 - gst_mythtv_src_next_program_chain( src );
1.394 -
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 (psrc)),
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_mythtv_src_next_program_chain( src );
1.405 +
1.406 return GST_FLOW_ERROR_NO_DATA;
1.407 }
1.408
1.409 @@ -698,13 +751,25 @@
1.410 gst_mythtv_src_do_seek( GstBaseSrc *base, GstSegment *segment )
1.411 {
1.412 GstMythtvSrc *src = GST_MYTHTV_SRC( base );
1.413 - gint64 new_offset = 0;
1.414 + gint64 new_offset = -1;
1.415 + gint64 actual_seek = segment->start;
1.416 gboolean ret = TRUE;
1.417
1.418 g_print( "[%s]DO Seek called! (start = %lld, stop = %lld)\n", __FUNCTION__, segment->start, segment->stop );
1.419 + //g_static_rec_mutex_lock( &th_mutex );
1.420
1.421 + //GST_TASK_WAIT( src->th_read_ahead );
1.422 +
1.423 + //g_static_rec_mutex_unlock( &th_mutex );
1.424 +
1.425 + if ( segment->format == GST_FORMAT_TIME )
1.426 + {
1.427 + goto done;
1.428 + //actual_seek = ( ( segment->start / 1000 ) * 28 ) * 4000;
1.429 + }
1.430 + g_print( "[%s]Trying to seek at the value (actual_seek = %lld, read_offset = %lld)\n", __FUNCTION__, actual_seek, src->read_offset );
1.431 /* verify if it needs to seek */
1.432 - if ( src->read_offset != segment->start )
1.433 + if ( src->read_offset != actual_seek )
1.434 {
1.435
1.436 new_offset = gmyth_file_transfer_seek( src->file_transfer, segment->start, SEEK_SET );
1.437 @@ -722,15 +787,27 @@
1.438
1.439 src->read_offset = new_offset;
1.440
1.441 + //gst_segment_set_seek( segment, segment->rate, GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
1.442 + //GST_SEEK_TYPE_CUR, src->read_offset, GST_SEEK_TYPE_CUR, segment->stop, &ret );
1.443 +
1.444 + if ( ret == FALSE ) {
1.445 + g_print( "[%s] Failed to set the SEEK on segment!\n", __FUNCTION__ );
1.446 + }
1.447 +
1.448 }
1.449 -
1.450 + //g_static_rec_mutex_lock( &th_mutex );
1.451 +
1.452 + //GST_TASK_SIGNAL( src->th_read_ahead );
1.453 +
1.454 + //g_static_rec_mutex_unlock( &th_mutex );
1.455 +done:
1.456 return ret;
1.457
1.458 eos:
1.459 {
1.460
1.461 GST_DEBUG_OBJECT (src, "EOS found on seeking!!!");
1.462 - gst_object_unref( src );
1.463 + //gst_object_unref( src );
1.464 return FALSE;
1.465 }
1.466 change_progchain:
1.467 @@ -755,37 +832,58 @@
1.468 #if 0
1.469 static void
1.470 gst_mythtv_src_read_ahead ( void *data ) {
1.471 -
1.472 - GstMythtvSrc *src = NULL;
1.473 -
1.474 - GstBuffer *buffer = NULL;
1.475 -
1.476 - guint size = 512;
1.477 -
1.478 - gint read = 0;
1.479 -
1.480 - src = GST_MYTHTV_SRC( data );
1.481 -
1.482 - GST_PAD_STREAM_TRYLOCK( GST_BASE_SRC_PAD (GST_BASE_SRC (src)) );
1.483 -
1.484 - /*if ( gst_adapter_available( src->adapter ) ) && ( read < MAX_READ_SIZE )) */
1.485 - do {
1.486 - buffer = gst_buffer_new_and_alloc( size );
1.487
1.488 - read += do_read_request_response ( src, src->adapter_offset, size, &buffer );
1.489 -
1.490 - gst_adapter_push( src->adapter, buffer );
1.491 -
1.492 - //gst_buffer_unref( buffer );
1.493 - } while ( read < MAX_READ_SIZE );
1.494 -
1.495 - GST_PAD_BLOCK_SIGNAL( GST_BASE_SRC_PAD (GST_BASE_SRC (src)) );
1.496 -
1.497 - GST_PAD_STREAM_UNLOCK( GST_BASE_SRC_PAD (GST_BASE_SRC (src)) );
1.498 -
1.499 - gst_object_unref( src );
1.500 -
1.501 - return;
1.502 + GstMythtvSrc *src = NULL;
1.503 +
1.504 + GstBuffer *outbuf = NULL;
1.505 +
1.506 + guint size = 5*2048;
1.507 + gint total = 0;
1.508 + gint read = -1;
1.509 +
1.510 + src = GST_MYTHTV_SRC( data );
1.511 +
1.512 + //GST_PAD_STREAM_TRYLOCK( GST_BASE_SRC_PAD (GST_BASE_SRC (src)) );
1.513 +
1.514 + do {
1.515 + GST_TASK_WAIT( src->th_read_ahead );
1.516 +
1.517 + gint8 *data = NULL;
1.518 +
1.519 + outbuf = gst_buffer_new_and_alloc( size );
1.520 +
1.521 + read = do_read_request_response ( src, src->adapter_offset, size, &data );
1.522 +
1.523 + if ( read > 0 ) {
1.524 + src->read_offset += read;
1.525 + src->bytes_read += read;
1.526 + total += read;
1.527 +
1.528 + g_print( "[%s]\tBYTES READ (actual) = %d, BYTES READ (cumulative) = %llu, "\
1.529 + "OFFSET = %llu, CONTENT SIZE = %llu.\n", __FUNCTION__, read, src->bytes_read,
1.530 + src->read_offset, src->content_size );
1.531 +
1.532 + GST_BUFFER_SIZE (outbuf) = read;
1.533 + GST_BUFFER_MALLOCDATA( outbuf ) = g_malloc0( GST_BUFFER_SIZE (outbuf) );
1.534 + GST_BUFFER_DATA( outbuf ) = GST_BUFFER_MALLOCDATA( outbuf );
1.535 + g_memmove( GST_BUFFER_DATA( outbuf ), data, read );
1.536 + GST_BUFFER_OFFSET (outbuf) = src->adapter_offset;
1.537 + GST_BUFFER_OFFSET_END (outbuf) = src->adapter_offset + read;
1.538 + g_print( "Got buffer: [%s]\t\tBUFFER --->SIZE = %d, OFFSET = %llu, "\
1.539 + "OFFSET_END = %llu.\n\n", __FUNCTION__, GST_BUFFER_SIZE (outbuf),
1.540 + GST_BUFFER_OFFSET (outbuf), GST_BUFFER_OFFSET_END (outbuf) );
1.541 +
1.542 + }
1.543 +
1.544 + gst_adapter_push( src->adapter, outbuf );
1.545 +
1.546 + GST_TASK_SIGNAL( src->th_read_ahead );
1.547 +
1.548 + } while ( read < size );
1.549 +
1.550 + //GST_PAD_STREAM_UNLOCK( GST_BASE_SRC_PAD (GST_BASE_SRC (src)) );
1.551 +
1.552 + return;
1.553 }
1.554 #endif
1.555
1.556 @@ -798,7 +896,7 @@
1.557 GString *chain_id_local = NULL;
1.558
1.559 gboolean ret = TRUE;
1.560 -
1.561 +
1.562 if ( G_UNLIKELY (src->update_prog_chain) )
1.563 goto change_progchain;
1.564
1.565 @@ -808,13 +906,10 @@
1.566 goto done;
1.567 }
1.568
1.569 - //GST_OBJECT_LOCK(src);
1.570 -
1.571 if ( src->live_tv ) {
1.572 src->spawn_livetv = gmyth_livetv_new( );
1.573 if ( gmyth_livetv_setup( src->spawn_livetv ) == FALSE ) {
1.574 ret = FALSE;
1.575 - //GST_OBJECT_UNLOCK( src );
1.576 goto init_failed;
1.577 }
1.578
1.579 @@ -833,8 +928,6 @@
1.580 g_string_new( src->uri_name ), -1, src->mythtv_version );
1.581
1.582 if ( src->file_transfer == NULL ) {
1.583 - //GST_OBJECT_UNLOCK(src);
1.584 -
1.585 goto init_failed;
1.586 }
1.587
1.588 @@ -846,7 +939,7 @@
1.589 wait_to_transfer = 0;
1.590
1.591 while ( wait_to_transfer++ < GMYTHTV_TRANSFER_MAX_WAITS &&
1.592 - ( gmyth_file_transfer_is_recording( src->file_transfer ) == FALSE
1.593 + ( gmyth_file_transfer_is_recording( src->file_transfer ) == FALSE
1.594 /*|| ( gmyth_file_transfer_get_file_position( src->file_transfer ) < ( src->content_size + 327680 ) )*/ ) )
1.595 g_usleep( 100 );
1.596 }
1.597 @@ -855,7 +948,6 @@
1.598 ret = gmyth_file_transfer_setup( &(src->file_transfer), src->live_tv );
1.599
1.600 if ( ret == FALSE ) {
1.601 - //GST_OBJECT_UNLOCK(src);
1.602 #ifndef GST_DISABLE_GST_DEBUG
1.603 if ( src->mythtv_msgs_dbg )
1.604 g_printerr( "MythTV FileTransfer request failed when setting up socket connection!\n" );
1.605 @@ -866,16 +958,20 @@
1.606 src->content_size = src->file_transfer->filesize;
1.607
1.608 src->do_start = FALSE;
1.609 -
1.610 - if ( src->live_tv ) {
1.611 - //src->adapter = gst_adapter_new();
1.612 - //g_static_rec_mutex_init( src->th_mutex );
1.613 - //src->th_read_ahead = gst_task_create( (GstTaskFunction)gst_mythtv_src_read_ahead, src );
1.614 - }
1.615 +
1.616 + //if ( src->live_tv ) {
1.617 + src->adapter = gst_adapter_new();
1.618 + //src->th_read_ahead = gst_task_create( (GstTaskFunction)gst_mythtv_src_read_ahead, src );
1.619 + //gst_task_set_lock( src->th_read_ahead, &th_mutex );
1.620 + //gst_task_start( src->th_read_ahead );
1.621 + // }
1.622 //gst_pad_push_event ( GST_BASE_SRC_PAD (bsrc),
1.623 // gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_BYTES, 0, src->content_size, 0 ) );
1.624
1.625 - //GST_OBJECT_UNLOCK(src);
1.626 + src->buffer = g_malloc0 (INTERNAL_BUFFER_SIZE);
1.627 + src->buffer_offset = 0;
1.628 + src->buffer_remain = 0;
1.629 +
1.630
1.631 done:
1.632 return TRUE;
1.633 @@ -899,18 +995,18 @@
1.634 change_progchain:
1.635 {
1.636 GST_ELEMENT_ERROR (src, RESOURCE, READ,
1.637 - (NULL), ("Seek failed, go to the next program info... (%s)",
1.638 - src->uri_name));
1.639 -
1.640 - gst_pad_push_event ( GST_BASE_SRC_PAD (GST_BASE_SRC (src)),
1.641 - gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1, 0 ) );
1.642 -
1.643 - // go to the next program chain
1.644 - src->unique_setup = FALSE;
1.645 - src->update_prog_chain = TRUE;
1.646 -
1.647 - gst_mythtv_src_next_program_chain( src );
1.648 -
1.649 + (NULL), ("Seek failed, go to the next program info... (%s)",
1.650 + src->uri_name));
1.651 +
1.652 + gst_pad_push_event ( GST_BASE_SRC_PAD (GST_BASE_SRC (src)),
1.653 + gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1, 0 ) );
1.654 +
1.655 + // go to the next program chain
1.656 + src->unique_setup = FALSE;
1.657 + src->update_prog_chain = TRUE;
1.658 +
1.659 + gst_mythtv_src_next_program_chain( src );
1.660 +
1.661 return TRUE;
1.662 }
1.663 }
1.664 @@ -1113,12 +1209,12 @@
1.665 return TRUE;
1.666 }
1.667
1.668 -#if 0
1.669 static gboolean
1.670 gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event)
1.671 {
1.672 GstMythtvSrc *src = GST_MYTHTV_SRC (GST_PAD_PARENT (pad));
1.673 gint64 cont_size = 0;
1.674 + gboolean ret = FALSE;
1.675
1.676 switch (GST_EVENT_TYPE (event)) {
1.677 #if 0
1.678 @@ -1166,15 +1262,16 @@
1.679 }
1.680 } else
1.681 src->eos = TRUE;
1.682 + ret = TRUE;
1.683 break;
1.684 -#if 0
1.685 case GST_EVENT_NEWSEGMENT:
1.686 g_print( "[%s] Got NEWSEGMENT!!!\n", __FUNCTION__ );
1.687 - src->eos = FALSE;
1.688 + ret = gst_pad_event_default (pad, event);
1.689 break;
1.690 case GST_EVENT_SEEK:
1.691 {
1.692 - g_print( "[%s] Got EVENT_SEEK!!!\n", __FUNCTION__ );
1.693 + gst_event_ref( event );
1.694 +
1.695 gdouble rate;
1.696 //gboolean update = TRUE;
1.697 GstFormat format;
1.698 @@ -1185,24 +1282,23 @@
1.699 &flags, &cur_type, &cur,
1.700 &stop_type, &stop );
1.701
1.702 - g_print( "[%s] Got EVENT_SEEK.\n", __FUNCTION__ );
1.703 + g_print( "[%s] Got EVENT_SEEK (pos = %lld)!!!\n", __FUNCTION__, cur );
1.704 if ( !( flags & GST_SEEK_FLAG_FLUSH ) ) {
1.705 g_print( "[%s] Could get the FLAG_FLUSH message.\n", __FUNCTION__ );
1.706 }
1.707 - //gboolean ret = gst_event_parse_new_segment ( event,
1.708 - // &update, &rate, &format, &start, &stop,
1.709 - // &position );
1.710 - //GstFlowReturn flow_ret = gst_mythtv_src_create (GST_BASE_SRC( GST_PAD_PARENT( psrc ) ),
1.711 - // cur, stop - cur + 1, GstBuffer)
1.712 + if ( format == GST_FORMAT_TIME && ( ret = gst_pad_event_default (pad, event) ) == FALSE ) {
1.713 + gst_event_unref( event );
1.714 + break;
1.715 + }
1.716 +
1.717 + break;
1.718 }
1.719 -#endif
1.720 default:
1.721 - return gst_pad_event_default (pad, event);
1.722 + ret = gst_pad_event_default (pad, event);
1.723 }
1.724
1.725 - return gst_pad_event_default (pad, event);
1.726 + return ret;
1.727 }
1.728 -#endif
1.729
1.730 static gboolean
1.731 gst_mythtv_src_is_seekable( GstBaseSrc *push_src )
2.1 --- a/gst-plugins-mythtv/src/gstmythtvsrc.h Thu Nov 16 21:30:58 2006 +0000
2.2 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.h Fri Nov 17 13:09:12 2006 +0000
2.3 @@ -54,14 +54,14 @@
2.4 GMythFileTransfer *file_transfer;
2.5
2.6 GMythLiveTV *spawn_livetv;
2.7 -
2.8 +
2.9 GstMythtvState state;
2.10
2.11 gchar *uri_name;
2.12 gchar *user_agent;
2.13
2.14 gchar *live_chain_id;
2.15 -
2.16 +
2.17 gint mythtv_version;
2.18
2.19 gint64 content_size;
2.20 @@ -75,32 +75,39 @@
2.21 gint64 read_offset;
2.22 gint64 adapter_offset;
2.23
2.24 + //guint64 file_size;
2.25 + /* added by melunko */
2.26 + guint8* buffer;
2.27 +
2.28 + gint buffer_offset;
2.29 + gint buffer_remain;
2.30 +
2.31 gboolean eos;
2.32 -
2.33 +
2.34 gboolean do_start;
2.35
2.36 gboolean unique_setup;
2.37
2.38 gboolean live_tv;
2.39 -
2.40 +
2.41 gboolean enable_timing_position;
2.42
2.43 gint live_tv_id;
2.44 -
2.45 +
2.46 gint channel_num;
2.47 -
2.48 +
2.49 guint mode;
2.50
2.51 /* MythTV capabilities */
2.52 GstCaps *mythtv_caps;
2.53 -
2.54 +
2.55 GstPad *sinkpad;
2.56 GstPad *srcpad;
2.57 -
2.58 +
2.59 GstTask *th_read_ahead;
2.60 -
2.61 - GStaticRecMutex *th_mutex;
2.62 -
2.63 +
2.64 + GStaticRecMutex *th_mutex;
2.65 +
2.66 GstAdapter *adapter;
2.67
2.68 /* enable Myth TV debug messages */