gst-plugins-nuvdemux/src/gstnuvdemux.c
branchtrunk
changeset 68 8113a3dce6ce
parent 62 2a552f003c4e
child 73 959df0ca7621
     1.1 --- a/gst-plugins-nuvdemux/src/gstnuvdemux.c	Fri Oct 27 23:42:34 2006 +0100
     1.2 +++ b/gst-plugins-nuvdemux/src/gstnuvdemux.c	Mon Nov 06 22:57:44 2006 +0000
     1.3 @@ -60,6 +60,7 @@
     1.4  #define GST_CAT_DEFAULT nuvdemux_debug
     1.5  
     1.6  
     1.7 +#define DEMUX_INDEX_SIZE_MAX (100000)
     1.8  #define GST_FLOW_ERROR_NO_DATA  -101
     1.9  
    1.10  GST_DEBUG_CATEGORY_EXTERN (GST_CAT_EVENT);
    1.11 @@ -89,8 +90,8 @@
    1.12      GST_STATIC_CAPS_ANY);
    1.13  
    1.14  /* NUV Demux indexes init/dispose callers */
    1.15 -static void gst_nuv_demux_index_init( nuv_demux_index **p_idx );
    1.16 -static void gst_nuv_demux_index_clean( nuv_demux_index **p_idx );
    1.17 +static nuv_demux_index* gst_nuv_demux_index_new (void);
    1.18 +static void gst_nuv_demux_index_destroy (nuv_demux_index *p_idx);
    1.19  
    1.20  /* NUV Demux indexes manipulation functions */
    1.21  static gint64 gst_nuv_demux_index_find_offset( GstNuvDemux *nuv, gint64 i_offset );
    1.22 @@ -106,12 +107,12 @@
    1.23  static GstFlowReturn gst_nuv_demux_play (GstPad * pad);
    1.24  static gboolean gst_nuv_demux_sink_activate_pull (GstPad * sinkpad,
    1.25      gboolean active);
    1.26 +static gboolean gst_nuv_demux_sink_activate_push (GstPad * pad, 
    1.27 +    gboolean active);
    1.28  static gboolean gst_nuv_demux_sink_activate (GstPad * sinkpad);
    1.29  static GstFlowReturn gst_nuv_demux_read_bytes (GstNuvDemux * nuv, guint64 size,
    1.30      gboolean move, GstBuffer ** buffer);
    1.31  static void gst_nuv_demux_reset (GstNuvDemux * nuv);
    1.32 -static gboolean gst_nuv_demux_handle_sink_event (GstPad * sinkpad,
    1.33 -    GstEvent * event);
    1.34  static void gst_nuv_demux_destoy_src_pad (GstNuvDemux * nuv);
    1.35  static void gst_nuv_demux_send_eos (GstNuvDemux * nuv);
    1.36  
    1.37 @@ -179,14 +180,15 @@
    1.38    gst_pad_set_activatepull_function (nuv->sinkpad,
    1.39        gst_nuv_demux_sink_activate_pull);
    1.40  
    1.41 +  gst_pad_set_activatepush_function (nuv->sinkpad, 
    1.42 +      gst_nuv_demux_sink_activate_push);
    1.43 +
    1.44    gst_pad_set_chain_function (nuv->sinkpad,
    1.45        GST_DEBUG_FUNCPTR (gst_nuv_demux_chain));
    1.46  
    1.47 -  gst_pad_set_event_function (nuv->sinkpad, gst_nuv_demux_handle_sink_event);
    1.48 -
    1.49    gst_element_add_pad (GST_ELEMENT (nuv), nuv->sinkpad);
    1.50    
    1.51 -  gst_nuv_demux_index_init( &nuv->index_entries );
    1.52 +  nuv->index_entries = gst_nuv_demux_index_new ();
    1.53  
    1.54    nuv->adapter = NULL;
    1.55    nuv->mpeg_buffer = NULL;
    1.56 @@ -206,7 +208,7 @@
    1.57    }
    1.58    
    1.59    if ( nuv->index_entries != NULL ) {
    1.60 -  	gst_nuv_demux_index_clean( &nuv->index_entries );
    1.61 +  	gst_nuv_demux_index_destroy (nuv->index_entries);
    1.62    	nuv->index_entries = NULL;
    1.63    }
    1.64  
    1.65 @@ -223,22 +225,20 @@
    1.66   * Indexes (timecode offset conversion) functions
    1.67   *****************************************************************************/
    1.68  
    1.69 -static void 
    1.70 -gst_nuv_demux_index_init( nuv_demux_index **p_idx )
    1.71 +static nuv_demux_index*
    1.72 +gst_nuv_demux_index_new (void)
    1.73  {
    1.74 -	*p_idx = g_new0( nuv_demux_index, 1 );
    1.75 -	(*p_idx)->i_idx = 0;
    1.76 -	(*p_idx)->i_idx_max = 0;
    1.77 +	return g_new0 (nuv_demux_index, 1);
    1.78  }
    1.79  
    1.80  static void 
    1.81 -gst_nuv_demux_index_clean( nuv_demux_index **p_idx )
    1.82 +gst_nuv_demux_index_destroy (nuv_demux_index *p_idx)
    1.83  {
    1.84 -	if ( *p_idx != NULL ) {
    1.85 -		g_free( *p_idx );
    1.86 -		*p_idx = NULL;
    1.87 +	if (p_idx != NULL) {
    1.88 +        g_free (p_idx->idx);        
    1.89 +        p_idx->idx = NULL;
    1.90 +		g_free (p_idx);
    1.91  	}
    1.92 -
    1.93  }
    1.94  
    1.95  static void 
    1.96 @@ -250,13 +250,13 @@
    1.97  	//	return;
    1.98  
    1.99  	/* Be sure to append new entry (we don't insert point) */
   1.100 -	if( p_idx != NULL && p_idx->i_idx > 0 && p_idx->idx[p_idx->i_idx-1].i_time >= i_time )
   1.101 +	if (p_idx != NULL && p_idx->i_idx > 0 && p_idx->idx[p_idx->i_idx-1].i_time >= i_time)
   1.102  		return;
   1.103  
   1.104  	/* */
   1.105 -	if( p_idx->i_idx >= p_idx->i_idx_max )
   1.106 +	if (p_idx->i_idx >= p_idx->i_idx_max)
   1.107  	{
   1.108 -		if( p_idx->i_idx >= DEMUX_INDEX_SIZE_MAX )
   1.109 +		if (p_idx->i_idx >= DEMUX_INDEX_SIZE_MAX)
   1.110  		{
   1.111  			/* Avoid too big index */
   1.112  			const gint64 i_length = p_idx->idx[p_idx->i_idx-1].i_time -
   1.113 @@ -265,20 +265,20 @@
   1.114  			gint i, j;
   1.115  
   1.116  			/* We try to reduce the resolution of the index by a factor 2 */
   1.117 -			for( i = 1, j = 1; i < p_idx->i_idx; i++ )
   1.118 +			for (i = 1, j = 1; i < p_idx->i_idx; i++)
   1.119  			{
   1.120 -				if( p_idx->idx[i].i_time < j * i_length / i_count )
   1.121 +				if (p_idx->idx[i].i_time < j * i_length / i_count)
   1.122  					continue;
   1.123  
   1.124  				p_idx->idx[j++] = p_idx->idx[i];
   1.125  			}
   1.126  			p_idx->i_idx = j;
   1.127  
   1.128 -			if( p_idx->i_idx > 3 * DEMUX_INDEX_SIZE_MAX / 4 )
   1.129 +			if (p_idx->i_idx > 3 * DEMUX_INDEX_SIZE_MAX / 4)
   1.130  			{
   1.131  				/* We haven't created enough space
   1.132  				 * (This method won't create a good index but work for sure) */
   1.133 -				for( i = 0; i < p_idx->i_idx/2; i++ )
   1.134 +				for (i = 0; i < p_idx->i_idx/2; i++)
   1.135  					p_idx->idx[i] = p_idx->idx[2*i];
   1.136  				p_idx->i_idx /= 2;
   1.137  			}
   1.138 @@ -286,8 +286,8 @@
   1.139  		else
   1.140  		{
   1.141  			p_idx->i_idx_max += 1000;
   1.142 -			//p_idx->idx = g_realloc( p_idx->idx,
   1.143 -					//p_idx->i_idx_max*sizeof(nuv_demux_index_entry));
   1.144 +			p_idx->idx = g_realloc (p_idx->idx, 
   1.145 +                    p_idx->i_idx_max*sizeof(nuv_demux_index_entry));
   1.146  		}
   1.147  	}
   1.148  
   1.149 @@ -388,29 +388,6 @@
   1.150  		return p_idx->idx[i_max].i_offset;
   1.151  }
   1.152  
   1.153 -/*****************************************************************************
   1.154 - * Utils functions
   1.155 - *****************************************************************************/
   1.156 -
   1.157 -static gboolean
   1.158 -gst_nuv_demux_handle_sink_event (GstPad * sinkpad, GstEvent * event)
   1.159 -{
   1.160 -  gboolean res = FALSE;
   1.161 -
   1.162 -  switch (GST_EVENT_TYPE (event)) {
   1.163 -    case GST_EVENT_NEWSEGMENT:
   1.164 -      res = TRUE;
   1.165 -      break;
   1.166 -    default:
   1.167 -      return gst_pad_event_default (sinkpad, event);
   1.168 -      break;
   1.169 -  }
   1.170 -
   1.171 -  gst_event_unref (event);
   1.172 -  return res;
   1.173 -}
   1.174 -
   1.175 -
   1.176  /* HeaderLoad:
   1.177   */
   1.178  static GstFlowReturn
   1.179 @@ -610,10 +587,11 @@
   1.180      gst_pad_set_active (nuv->src_video_pad, TRUE);
   1.181      gst_pad_set_caps (nuv->src_video_pad, video_caps);
   1.182  
   1.183 +    gst_pad_set_active (nuv->src_video_pad, TRUE);
   1.184 +    gst_element_add_pad (GST_ELEMENT (nuv), nuv->src_video_pad);
   1.185 +
   1.186      gst_pad_set_event_function (nuv->src_video_pad,
   1.187          gst_nuv_demux_handle_src_event);
   1.188 -    gst_pad_set_active (nuv->src_video_pad, TRUE);
   1.189 -    gst_element_add_pad (GST_ELEMENT (nuv), nuv->src_video_pad);
   1.190  
   1.191      gst_caps_unref (video_caps);
   1.192    }
   1.193 @@ -681,11 +659,11 @@
   1.194  	  /* search for a valid timecode in the indexes list (find the nearest valid timecode) */
   1.195  	  if ( h->i_timecode < 0 ) {
   1.196  		  /* convert this actual timecode to a valid index in the timecode's table */
   1.197 -		  gint64 pos = gst_nuv_demux_index_convert_time( nuv, h->i_timecode );
   1.198 +		  gint64 pos = gst_nuv_demux_index_convert_time (nuv, h->i_timecode);
   1.199  
   1.200  		  /* find the nearest empty frame slot */		  
   1.201 -		  gint64 near_off = gst_nuv_demux_index_find_offset( nuv, pos );
   1.202 -            near_off = 0;
   1.203 +		  gint64 near_off = gst_nuv_demux_index_find_offset  (nuv, pos);
   1.204 +
   1.205  		  /* just get the timecode from the timecode's table */		  
   1.206  		  GST_BUFFER_TIMESTAMP (buf) = nuv->index_entries->idx[near_off].i_time * GST_MSECOND;
   1.207  	  } else {  
   1.208 @@ -704,6 +682,10 @@
   1.209        GST_BUFFER_OFFSET (buf) = nuv->video_offset;
   1.210        gst_buffer_set_caps (buf, GST_PAD_CAPS (nuv->src_video_pad));
   1.211        ret = gst_pad_push (nuv->src_video_pad, buf);
   1.212 +      if (ret != GST_FLOW_OK) {
   1.213 +        GST_WARNING_OBJECT (nuv, "error pushing on srcpad %s, is linked? = %d",
   1.214 +            gst_pad_get_name (nuv->src_video_pad), gst_pad_is_linked (nuv->src_video_pad));
   1.215 +      }
   1.216        nuv->video_offset++;
   1.217        break;
   1.218      }
   1.219 @@ -715,24 +697,33 @@
   1.220        GST_BUFFER_OFFSET (buf) = nuv->audio_offset;
   1.221        gst_buffer_set_caps (buf, GST_PAD_CAPS (nuv->src_audio_pad));
   1.222        ret = gst_pad_push (nuv->src_audio_pad, buf);
   1.223 +      if (ret != GST_FLOW_OK) {
   1.224 +        GST_WARNING_OBJECT (nuv, "Error pushing on srcpad %s, is linked? = %d",
   1.225 +            gst_pad_get_name (nuv->src_audio_pad), gst_pad_is_linked (nuv->src_audio_pad));
   1.226 +      }
   1.227        nuv->audio_offset++;
   1.228        break;
   1.229      }
   1.230      case 'S':
   1.231      {
   1.232 +        /*
   1.233        switch (h->i_compression) {
   1.234          case 'V':
   1.235 +          GST_DEBUG_OBJECT (nuv, "Video New Segment");
   1.236 +          nuv->video_offset = 0;
   1.237            gst_pad_push_event (nuv->src_video_pad,
   1.238                gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1,
   1.239 -                  h->i_timecode));
   1.240 +                  0));
   1.241            break;
   1.242          case 'A':
   1.243 +          GST_DEBUG_OBJECT (nuv, "Audio New Segment");
   1.244            gst_pad_push_event (nuv->src_audio_pad,
   1.245                gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1, 0));
   1.246            break;
   1.247          default:
   1.248            break;
   1.249        }
   1.250 +      */
   1.251      }
   1.252      default:
   1.253        if (buf != NULL)
   1.254 @@ -741,7 +732,7 @@
   1.255        break;
   1.256    }
   1.257  
   1.258 - GST_DEBUG_OBJECT (nuv, "data sended");
   1.259 + GST_DEBUG_OBJECT (nuv, "data sent");
   1.260  
   1.261  done:
   1.262    nuv->state = GST_NUV_DEMUX_FRAME_HEADER;
   1.263 @@ -938,6 +929,8 @@
   1.264    return GST_FLOW_OK;
   1.265  
   1.266  pause:
   1.267 +  g_debug ("PAUSE");
   1.268 +
   1.269    GST_LOG_OBJECT (nuv, "pausing task, reason %s", gst_flow_get_name (res));
   1.270    gst_pad_pause_task (nuv->sinkpad);
   1.271    if (GST_FLOW_IS_FATAL (res)) {
   1.272 @@ -989,7 +982,11 @@
   1.273        return GST_FLOW_ERROR_NO_DATA;
   1.274  
   1.275      if (move) {
   1.276 -      *buffer = gst_adapter_take_buffer (nuv->adapter, size);
   1.277 +      guint8 *data = NULL;
   1.278 +
   1.279 +      data = (guint8 *) gst_adapter_take (nuv->adapter, size);
   1.280 +      *buffer = gst_buffer_new ();
   1.281 +      gst_buffer_set_data (*buffer, data, size);
   1.282      } else {
   1.283        guint8 *data = NULL;
   1.284  
   1.285 @@ -1038,6 +1035,22 @@
   1.286    return TRUE;
   1.287  }
   1.288  
   1.289 +static gboolean
   1.290 +gst_nuv_demux_sink_activate_push (GstPad * pad, gboolean active)
   1.291 +{
   1.292 +  GstNuvDemux *nuv = GST_NUV_DEMUX (gst_pad_get_parent (pad));
   1.293 +
   1.294 +  if (active) {
   1.295 +    GST_DEBUG_OBJECT (nuv, "activating push/chain function");
   1.296 +  } else {
   1.297 +    GST_DEBUG_OBJECT (nuv, "deactivating push/chain function");
   1.298 +  }
   1.299 +
   1.300 +  gst_object_unref (nuv);
   1.301 +
   1.302 +  return TRUE;
   1.303 +}
   1.304 +
   1.305  static GstFlowReturn
   1.306  gst_nuv_demux_chain (GstPad * pad, GstBuffer * buf)
   1.307  {
   1.308 @@ -1047,6 +1060,8 @@
   1.309  
   1.310    GST_DEBUG_OBJECT (nuv, "PUSH adapter %d", gst_adapter_available (nuv->adapter));
   1.311  
   1.312 +  gst_object_unref (nuv);
   1.313 +
   1.314    return gst_nuv_demux_play (pad);
   1.315  }
   1.316  
   1.317 @@ -1101,7 +1116,7 @@
   1.318  gst_nuv_demux_change_state (GstElement * element, GstStateChange transition)
   1.319  {
   1.320    GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
   1.321 -
   1.322 +  
   1.323    switch (transition) {
   1.324      case GST_STATE_CHANGE_READY_TO_PAUSED:
   1.325        break;
   1.326 @@ -1115,7 +1130,7 @@
   1.327  
   1.328    switch (transition) {
   1.329      case GST_STATE_CHANGE_PAUSED_TO_READY:
   1.330 -      //gst_nuv_demux_destoy_src_pad (GST_NUV_DEMUX (element));
   1.331 +      gst_nuv_demux_destoy_src_pad (GST_NUV_DEMUX (element));
   1.332        gst_nuv_demux_reset (GST_NUV_DEMUX (element));
   1.333        break;
   1.334      default: