gst-plugins-mythtv/src/gstmythtvsrc.c
branchtrunk
changeset 89 edcd63c2ac77
parent 81 56e39289fa96
child 90 f6a9705509a1
     1.1 --- a/gst-plugins-mythtv/src/gstmythtvsrc.c	Mon Nov 13 19:58:37 2006 +0000
     1.2 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.c	Thu Nov 16 21:30:58 2006 +0000
     1.3 @@ -90,7 +90,9 @@
     1.4  static gboolean gst_mythtv_src_start (GstBaseSrc * bsrc);
     1.5  static gboolean gst_mythtv_src_stop (GstBaseSrc * bsrc);
     1.6  static gboolean gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size);
     1.7 -//static gboolean gst_mythtv_src_is_seekable( GstBaseSrc *push_src );
     1.8 +static gboolean gst_mythtv_src_is_seekable( GstBaseSrc *push_src );
     1.9 +
    1.10 +static gboolean gst_mythtv_src_do_seek( GstBaseSrc *base, GstSegment *segment );
    1.11  
    1.12  static gboolean gst_mythtv_src_next_program_chain ( GstMythtvSrc *src );
    1.13  
    1.14 @@ -104,6 +106,8 @@
    1.15  
    1.16  static void gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
    1.17  
    1.18 +static gboolean gst_mythtv_src_handle_query (GstPad * pad, GstQuery * query);
    1.19 +
    1.20  //static gboolean gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event);
    1.21  //static gboolean gst_mythtv_src_query ( GstPad * pad, GstQuery * query );
    1.22  
    1.23 @@ -131,7 +135,7 @@
    1.24  GST_BOILERPLATE_FULL (GstMythtvSrc, gst_mythtv_src, GstPushSrc,
    1.25      GST_TYPE_PUSH_SRC, _urihandler_init)
    1.26      
    1.27 -  static void
    1.28 +static void
    1.29  gst_mythtv_src_base_init (gpointer g_class)
    1.30  {
    1.31    GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
    1.32 @@ -222,9 +226,9 @@
    1.33    gstbasesrc_class->start = gst_mythtv_src_start;
    1.34    gstbasesrc_class->stop = gst_mythtv_src_stop;
    1.35    gstbasesrc_class->get_size = gst_mythtv_src_get_size;
    1.36 -  //gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable;
    1.37 +  gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable;
    1.38    
    1.39 -  //gstbasesrc_class->create = gst_mythtv_src_create;
    1.40 +  gstbasesrc_class->do_seek = gst_mythtv_src_do_seek;
    1.41    gstpushsrc_class->create = gst_mythtv_src_create;
    1.42      
    1.43    GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0,
    1.44 @@ -271,16 +275,16 @@
    1.45    this->th_mutex = NULL;
    1.46    
    1.47    this->srcpad = gst_pad_new_from_static_template (&srctemplate, "src");
    1.48 -  //gst_pad_set_chain_function ( GST_BASE_SRC_PAD( GST_BASE_SRC( this ) ), 
    1.49 -  //		GST_DEBUG_FUNCPTR ( gst_mythtv_src_chain ) );
    1.50    gst_element_add_pad (GST_ELEMENT (this), this->srcpad);
    1.51    
    1.52 -  //gst_base_src_set_format( GST_BASE_SRC( this ), GST_FORMAT_BYTES );  
    1.53 +  gst_base_src_set_format( GST_BASE_SRC( this ), GST_FORMAT_BYTES );  
    1.54  
    1.55 -  gst_base_src_set_live ( GST_BASE_SRC( this ), TRUE );
    1.56 +  //gst_base_src_set_live ( GST_BASE_SRC( this ), TRUE );
    1.57    
    1.58   // gst_pad_set_event_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
    1.59    //    gst_mythtv_src_handle_event );
    1.60 +  gst_pad_set_query_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
    1.61 +     gst_mythtv_src_handle_query );
    1.62  
    1.63  }
    1.64  
    1.65 @@ -338,7 +342,7 @@
    1.66    gint len = 0;
    1.67    gint8 *data_ptr = g_malloc0( size );
    1.68    
    1.69 -  //GST_OBJECT_LOCK(src);
    1.70 +  GST_OBJECT_LOCK(src);
    1.71  
    1.72    while ( sizetoread > 0 ) {
    1.73  
    1.74 @@ -422,7 +426,7 @@
    1.75    src->eos = TRUE;
    1.76  
    1.77  done:
    1.78 -  //GST_OBJECT_UNLOCK(src);
    1.79 +  GST_OBJECT_UNLOCK(src);
    1.80  
    1.81    return read;
    1.82  }
    1.83 @@ -598,13 +602,10 @@
    1.84    if ( G_UNLIKELY (src->update_prog_chain) )
    1.85      goto change_progchain;
    1.86  
    1.87 -	//gint64 new_offset = -1;
    1.88 -	/* just get from the adapter, no network effort... */
    1.89 -	//do	
    1.90 -	//{		
    1.91 -	/* Create the buffer. */
    1.92 +  /* just get from the adapter, no network effort... */
    1.93 +  /* Create the buffer. */
    1.94    ret = gst_pad_alloc_buffer ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
    1.95 -      GST_BUFFER_OFFSET_NONE, MAX_READ_SIZE,
    1.96 +      src->read_offset /*GST_BUFFER_OFFSET_NONE*/, MAX_READ_SIZE,
    1.97        GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf );
    1.98  
    1.99    if (G_UNLIKELY (ret != GST_FLOW_OK)) {
   1.100 @@ -616,7 +617,7 @@
   1.101    
   1.102    read = do_read_request_response ( src, src->read_offset, MAX_READ_SIZE, outbuf );	  
   1.103    
   1.104 -  if (G_UNLIKELY (src->update_prog_chain) )
   1.105 +  if ( G_UNLIKELY (src->update_prog_chain) )
   1.106      goto change_progchain;
   1.107  
   1.108    if (G_UNLIKELY (read <= 0) || *outbuf == NULL) {
   1.109 @@ -625,8 +626,6 @@
   1.110      else
   1.111      	goto read_error;
   1.112    }
   1.113 -	  							
   1.114 -	//} while ( TRUE );
   1.115  
   1.116  done:
   1.117   {
   1.118 @@ -695,6 +694,64 @@
   1.119  
   1.120  }
   1.121  
   1.122 +static gboolean
   1.123 +gst_mythtv_src_do_seek( GstBaseSrc *base, GstSegment *segment )
   1.124 +{
   1.125 +  GstMythtvSrc *src = GST_MYTHTV_SRC( base );
   1.126 +  gint64 new_offset = 0;
   1.127 +  gboolean ret = TRUE;
   1.128 +
   1.129 +  g_print( "[%s]DO Seek called! (start = %lld, stop = %lld)\n", __FUNCTION__, segment->start, segment->stop );
   1.130 +
   1.131 +  /* verify if it needs to seek */
   1.132 +  if ( src->read_offset != segment->start ) 
   1.133 +  {
   1.134 +
   1.135 +    new_offset = gmyth_file_transfer_seek( src->file_transfer, segment->start, SEEK_SET );
   1.136 +
   1.137 +    g_print( "[%s] Segment offset start = %lld, SRC Offset = %lld, NEW actual backend SEEK Offset = %lld.\n",
   1.138 +	__FUNCTION__, segment->start, src->read_offset, new_offset );
   1.139 +    if ( G_UNLIKELY (new_offset < 0 ) )
   1.140 +    {
   1.141 +      ret = FALSE;
   1.142 +      if ( src->live_tv )
   1.143 +	goto change_progchain;
   1.144 +      else
   1.145 +	goto eos;
   1.146 +    }
   1.147 +
   1.148 +    src->read_offset = new_offset;
   1.149 +
   1.150 +  }
   1.151 +  
   1.152 +   return ret;
   1.153 +
   1.154 +eos:
   1.155 +  {
   1.156 +
   1.157 +    GST_DEBUG_OBJECT (src, "EOS found on seeking!!!");
   1.158 +    gst_object_unref( src );
   1.159 +    return FALSE;
   1.160 +  }
   1.161 +change_progchain:
   1.162 +  {
   1.163 +    GST_ELEMENT_ERROR (src, RESOURCE, READ,
   1.164 +	(NULL), ("Seek failed, go to the next program info... (%i, %s)", read,
   1.165 +		 src->uri_name));
   1.166 +
   1.167 +    gst_pad_push_event ( GST_BASE_SRC_PAD (base),
   1.168 +	gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1, 0 ) );
   1.169 +    /* go to the next program chain */
   1.170 +    src->unique_setup = FALSE;
   1.171 +    src->update_prog_chain = TRUE;
   1.172 +
   1.173 +    gst_mythtv_src_next_program_chain( src );
   1.174 +
   1.175 +    return TRUE;
   1.176 +  }
   1.177 +
   1.178 +}
   1.179 +
   1.180  #if 0
   1.181  static void 
   1.182  gst_mythtv_src_read_ahead ( void *data ) {
   1.183 @@ -814,7 +871,9 @@
   1.184    	//src->adapter = gst_adapter_new();
   1.185    	//g_static_rec_mutex_init( src->th_mutex );
   1.186    	//src->th_read_ahead = gst_task_create( (GstTaskFunction)gst_mythtv_src_read_ahead, src );
   1.187 -  }  	
   1.188 +  }
   1.189 +  //gst_pad_push_event ( GST_BASE_SRC_PAD (bsrc),
   1.190 +  //	gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_BYTES, 0, src->content_size, 0 ) );
   1.191  
   1.192    //GST_OBJECT_UNLOCK(src);
   1.193  
   1.194 @@ -946,8 +1005,11 @@
   1.195  #endif
   1.196  
   1.197    src->content_size = src->file_transfer->filesize;
   1.198 -  while ( src->content_size < GMYTHTV_TRANSFER_MAX_BUFFER*4 )
   1.199 -    src->content_size = gst_mythtv_src_get_position( src );
   1.200 +  if ( src->live_tv ) {
   1.201 +  	wait_to_transfer = 0;
   1.202 +	  while ( wait_to_transfer++ < GMYTHTV_TRANSFER_MAX_WAITS && src->content_size < GMYTHTV_TRANSFER_MAX_BUFFER )
   1.203 +	    src->content_size = gst_mythtv_src_get_position( src );
   1.204 +  }
   1.205  
   1.206    src->read_offset = 0;  
   1.207    
   1.208 @@ -977,74 +1039,6 @@
   1.209  
   1.210  }
   1.211  
   1.212 -#if 0
   1.213 -/* handles queries for location in the stream in the requested format */
   1.214 -static gboolean
   1.215 -gst_mythtv_src_query ( GstPad * pad, GstQuery * query )
   1.216 -{
   1.217 -  gboolean res = TRUE;
   1.218 -  GstMythtvSrc *mythtv;
   1.219 -
   1.220 -  guint64 size = 0;
   1.221 -
   1.222 -  mythtv = GST_GMYTHTV_SRC( GST_PAD_PARENT (pad) );
   1.223 -
   1.224 -  size = gst_mythtv_src_get_position (mythtv);
   1.225 -
   1.226 -  switch (GST_QUERY_TYPE (query)) {
   1.227 -
   1.228 -    case GST_QUERY_POSITION:
   1.229 -      {
   1.230 -
   1.231 -	//GstFormat format;
   1.232 -	gint64 cur = 0;
   1.233 -
   1.234 -	/* save requested format */
   1.235 -	gst_query_parse_position (query, NULL, &cur);
   1.236 -
   1.237 -	/* query peer for current position in time */
   1.238 -	g_print( "[%s] Actual size is %s than current size from sink. [ %lld, %lld ]\n", __FUNCTION__, 
   1.239 -	    ( size > cur ) ? "greater" : "lower", size, cur );
   1.240 -	gst_query_set_position (query, GST_FORMAT_BYTES, size);
   1.241 -	if ( size < cur )
   1.242 -	  goto error;
   1.243 -
   1.244 -	break;
   1.245 -      }
   1.246 -     #if 0
   1.247 -    case GST_QUERY_DURATION:
   1.248 -      {
   1.249 -	//GstFormat format;
   1.250 -	gint64 cur = 0;
   1.251 -
   1.252 -	/* save requested format */
   1.253 -	gst_query_parse_position (query, NULL, &cur);
   1.254 -
   1.255 -	/* query peer for current position in time */
   1.256 -	g_print( "[%s] Actual size is %s than current size from sink. [ %lld, %lld ]\n", __FUNCTION__, 
   1.257 -	    ( size * GST_SECOND > cur * GST_SECOND ) ? "greater" : "lower", size * GST_SECOND, 
   1.258 -	    cur * GST_SECOND );
   1.259 -	gst_query_set_position (query, GST_FORMAT_TIME, size * GST_SECOND );
   1.260 -
   1.261 -	if ( size * GST_SECOND < cur * GST_SECOND )
   1.262 -	  goto error;
   1.263 -
   1.264 -	break;
   1.265 -      }
   1.266 -	#endif
   1.267 -    default:
   1.268 -      res = FALSE;
   1.269 -      break;
   1.270 -  }
   1.271 -
   1.272 -  return res;
   1.273 -
   1.274 -error:
   1.275 -
   1.276 -  return FALSE;
   1.277 -}
   1.278 -#endif
   1.279 -
   1.280  static gboolean
   1.281  gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size)
   1.282  {
   1.283 @@ -1053,8 +1047,8 @@
   1.284    g_print( "[%s] Differs from previous content size: %d (max.: %d)\n", __FUNCTION__, 
   1.285    			abs( src->content_size - src->prev_content_size ), GMYTHTV_TRANSFER_MAX_BUFFER );
   1.286  
   1.287 -  if (src->content_size <= 0) {
   1.288 -    ret= FALSE;
   1.289 +  if (src->content_size == -1) {
   1.290 +    //ret= FALSE;
   1.291    } else if ( src->live_tv && ( abs( src->content_size - src->bytes_read ) < 
   1.292  				GMYTHTV_TRANSFER_MAX_BUFFER ) ) {
   1.293      //g_static_mutex_lock( &update_size_mutex );
   1.294 @@ -1090,7 +1084,7 @@
   1.295  
   1.296    *size = src->content_size;
   1.297    g_print( "[%s] Content size = %lld\n", __FUNCTION__, src->content_size );
   1.298 -
   1.299 +  
   1.300    return ret;
   1.301  
   1.302  }
   1.303 @@ -1210,155 +1204,62 @@
   1.304  }
   1.305  #endif
   1.306  
   1.307 -#if 0
   1.308  static gboolean
   1.309  gst_mythtv_src_is_seekable( GstBaseSrc *push_src )
   1.310  {
   1.311    return TRUE;
   1.312  }
   1.313 +
   1.314 +static gboolean
   1.315 +gst_mythtv_src_handle_query (GstPad * pad, GstQuery * query)
   1.316 +{
   1.317 +  gboolean res = FALSE;
   1.318 +  GstMythtvSrc *myth = GST_MYTHTV_SRC (gst_pad_get_parent (pad));
   1.319 +
   1.320 +  switch (GST_QUERY_TYPE (query)) {
   1.321 +    case GST_QUERY_POSITION:
   1.322 +      gst_query_set_position (query, GST_FORMAT_BYTES,
   1.323 +	  myth->read_offset );
   1.324 +      res = TRUE;
   1.325 +      GST_DEBUG_OBJECT (myth, "POS %d", myth->read_offset);
   1.326 +      break;
   1.327 +    case GST_QUERY_DURATION:
   1.328 +#if 0
   1.329 +      if (myth->duration != 0) {
   1.330 +	gint64 total;
   1.331 +	gint64 fps;
   1.332 +
   1.333 +	fps = nuv->h->i_fpsn / nuv->h->i_fpsd;
   1.334 +	total = gst_util_uint64_scale_int (GST_SECOND, nuv->h->i_video_blocks, fps);
   1.335  #endif
   1.336 -
   1.337 -#if 0
   1.338 -static GstFlowReturn
   1.339 -gst_mythtv_src_file_transfer( GstMythtvSrc *src )
   1.340 -{
   1.341 -	GstFlowReturn ret = GST_FLOW_OK;
   1.342 -  GstBuffer *buf = NULL;
   1.343 -  gint read = -1;
   1.344 -  
   1.345 -  /* The caller should know the number of bytes and not read beyond EOS. */
   1.346 -  if ( G_UNLIKELY (src->eos) )
   1.347 -    goto eos;
   1.348 -  if ( G_UNLIKELY (src->update_prog_chain) )
   1.349 -    goto change_progchain;
   1.350 -
   1.351 -  do {
   1.352 -  
   1.353 -	  /* Create the buffer. */
   1.354 -	  buf = gst_buffer_new_and_alloc (4096);
   1.355 -	  
   1.356 -	  ret = gst_mythtv_src_read_bytes( src, GST_BUFFER_SIZE(buf), TRUE, &buf );	  
   1.357 -		if ( ret != GST_FLOW_OK )
   1.358 -			return ret;
   1.359 -	  
   1.360 -	  read = do_read_request_response ( src, src->read_offset, GST_BUFFER_SIZE(buf), &buf );
   1.361 -	  
   1.362 -	  if (G_UNLIKELY (src->update_prog_chain) )
   1.363 -	    goto change_progchain;
   1.364 -	
   1.365 -	  if (G_UNLIKELY (read <= 0) || buf == NULL) {
   1.366 -	  	if ( src->live_tv )
   1.367 -	    	goto change_progchain;
   1.368 -	    else
   1.369 -	    	goto read_error;
   1.370 -	  }
   1.371 -	  
   1.372 -	  if ( GST_FLOW_OK != ( ret = gst_pad_push ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)), buf ) ) ) {
   1.373 -	    goto done;
   1.374 -	  }  
   1.375 -  
   1.376 -	} while(TRUE);
   1.377 -
   1.378 -done:
   1.379 - {
   1.380 -    const gchar *reason = gst_flow_get_name (ret);
   1.381 -
   1.382 -    GST_DEBUG_OBJECT (src, "DONE task, reason %s", reason);
   1.383 -  	return ret;
   1.384 - }
   1.385 -eos:
   1.386 -  {
   1.387 -    const gchar *reason = gst_flow_get_name (ret);
   1.388 -
   1.389 -    GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);
   1.390 -    return GST_FLOW_UNEXPECTED;
   1.391 -  }
   1.392 -  /* ERRORS */
   1.393 -read_error:
   1.394 -  {
   1.395 -    GST_ELEMENT_ERROR (src, RESOURCE, READ,
   1.396 -	(NULL), ("Could not read any bytes (%i, %s)", read,
   1.397 -	  src->uri_name));
   1.398 -    return GST_FLOW_ERROR;
   1.399 -  }
   1.400 -change_progchain:
   1.401 -  {
   1.402 -    GST_ELEMENT_ERROR (src, RESOURCE, READ,
   1.403 -		(NULL), ("Seek failed, go to the next program info... (%i, %s)", read,
   1.404 -		  src->uri_name));
   1.405 -		// go to the next program chain
   1.406 -		src->unique_setup = FALSE;
   1.407 -		src->update_prog_chain = TRUE;
   1.408 -		src->mode = GST_MYTHTV_SRC_NEXT_PROGRAM_CHAIN;
   1.409 -		
   1.410 -		//GST_OBJECT_LOCK(src);
   1.411 -		//gst_mythtv_src_next_program_chain( src );
   1.412 -		//GST_OBJECT_UNLOCK(src);		  
   1.413 -    return GST_FLOW_OK;//GST_FLOW_ERROR_NO_DATA;
   1.414 -  }
   1.415 -}
   1.416 -
   1.417 -static GstFlowReturn
   1.418 -gst_mythtv_src_play (GstPad * pad)
   1.419 -{
   1.420 -  GstFlowReturn res = GST_FLOW_OK;
   1.421 -  GstMythtvSrc *src = GST_MYTHTV_SRC (GST_PAD_PARENT (pad));
   1.422 -  
   1.423 -	switch ( src->state ) {
   1.424 -    case GST_MYTHTV_SRC_FILE_TRANSFER:
   1.425 -    	res = gst_mythtv_src_file_transfer( src );
   1.426 -			if ((res != GST_FLOW_OK) && (res != GST_FLOW_ERROR_NO_DATA)) {
   1.427 -      	goto pause;
   1.428 -      }
   1.429 -      break;
   1.430 -    case GST_MYTHTV_SRC_NEXT_PROGRAM_CHAIN:
   1.431 -      src->read_offset = 0;
   1.432 -			src->bytes_read = 0;
   1.433 -			src->unique_setup = FALSE;
   1.434 -			if ( !gst_mythtv_src_next_program_chain( src ) ) {
   1.435 -        goto pause;
   1.436 -      }
   1.437 -      src->state = GST_MYTHTV_SRC_FILE_TRANSFER;
   1.438 -      break;
   1.439 -    case GST_MYTHTV_SRC_INVALID_DATA:
   1.440 -      goto pause;
   1.441 +	//gst_query_set_duration (query, GST_FORMAT_TIME, myth->content_size);
   1.442 +	GST_DEBUG_OBJECT (myth, "DURATION %d", myth->content_size);
   1.443 +	res = FALSE;
   1.444        break;
   1.445      default:
   1.446 -      g_assert_not_reached ();
   1.447 +      res = FALSE;
   1.448 +      break;
   1.449    }
   1.450  
   1.451 -  GST_DEBUG_OBJECT (src, "state: %d res:%s", src->state,
   1.452 -      gst_flow_get_name (res));
   1.453 +  gst_object_unref (myth);
   1.454  
   1.455 -  return GST_FLOW_OK;
   1.456 -
   1.457 -pause:
   1.458 -  GST_LOG_OBJECT (src, "pausing task, reason %s", gst_flow_get_name (res));
   1.459 -  gst_pad_pause_task (src->srcpad);
   1.460 -  if (GST_FLOW_IS_FATAL (res)) {
   1.461 -    GST_ELEMENT_ERROR (src, STREAM, FAILED,
   1.462 -        ("Internal data stream error."),
   1.463 -        ("streaming stopped, reason %s", gst_flow_get_name (res)));
   1.464 -    gst_pad_send_event( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)), gst_event_new_eos() );
   1.465 -  }
   1.466    return res;
   1.467  }
   1.468 -#endif
   1.469  
   1.470  static GstStateChangeReturn
   1.471  gst_mythtv_src_change_state (GstElement * element, GstStateChange transition)
   1.472  {
   1.473 -  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;//GST_STATE_CHANGE_NO_PREROLL;
   1.474 +  GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;//GST_STATE_CHANGE_NO_PREROLL;
   1.475    GstMythtvSrc *src = GST_MYTHTV_SRC (element);
   1.476  
   1.477    switch (transition) {
   1.478      case GST_STATE_CHANGE_NULL_TO_READY:
   1.479 -      src->do_start = TRUE;
   1.480 -      src->unique_setup = FALSE;
   1.481 +      //src->do_start = TRUE;
   1.482 +      //src->unique_setup = FALSE;
   1.483        break;
   1.484      case GST_STATE_CHANGE_READY_TO_PAUSED:
   1.485      case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
   1.486 -      src->eos = FALSE;
   1.487 +      //src->eos = FALSE;
   1.488        break;
   1.489      default:
   1.490        break;
   1.491 @@ -1603,7 +1504,7 @@
   1.492    return TRUE;
   1.493  }
   1.494  
   1.495 -  static void
   1.496 + static void
   1.497  gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
   1.498  {
   1.499    GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;