gst-plugins-mythtv/src/gstmythtvsrc.c
branchtrunk
changeset 92 e594fc21deef
parent 87 9ea342c364de
child 93 ae73b4837eed
     1.1 --- a/gst-plugins-mythtv/src/gstmythtvsrc.c	Wed Nov 15 18:07:23 2006 +0000
     1.2 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.c	Fri Nov 17 14:46:38 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 )