gst-plugins-nuvdemux/nuvdemux/gstnuvdemux.c
branchtrunk
changeset 77 bca1fb717911
parent 75 761a8bbe4278
child 78 ac7e49c234d8
     1.1 --- a/gst-plugins-nuvdemux/nuvdemux/gstnuvdemux.c	Thu Nov 09 19:45:27 2006 +0000
     1.2 +++ b/gst-plugins-nuvdemux/nuvdemux/gstnuvdemux.c	Fri Nov 10 19:21:45 2006 +0000
     1.3 @@ -87,15 +87,6 @@
     1.4      GST_PAD_SOMETIMES,
     1.5      GST_STATIC_CAPS_ANY);
     1.6  
     1.7 -/* NUV Demux indexes init/dispose callers */
     1.8 -static void gst_nuv_demux_index_init( nuv_demux_index **p_idx );
     1.9 -static void gst_nuv_demux_index_clean( nuv_demux_index **p_idx );
    1.10 -
    1.11 -/* NUV Demux indexes manipulation functions */
    1.12 -//static gint64 gst_nuv_demux_index_find_offset( GstNuvDemux *nuv, gint64 i_offset );
    1.13 -static void gst_nuv_demux_index_append( GstNuvDemux *nuv, gint64 i_time, gint64 i_offset );
    1.14 -static gint64 gst_nuv_demux_index_convert_time( GstNuvDemux *nuv, gint64 i_time );
    1.15 -
    1.16  /* NUV Demux plug-in time-line functions */
    1.17  static void gst_nuv_demux_finalize (GObject * object);
    1.18  static GstStateChangeReturn gst_nuv_demux_change_state (GstElement * element,
    1.19 @@ -105,16 +96,12 @@
    1.20  static GstFlowReturn gst_nuv_demux_play (GstPad * pad);
    1.21  static gboolean gst_nuv_demux_sink_activate_pull (GstPad * sinkpad,
    1.22      gboolean active);
    1.23 +static gboolean gst_nuv_demux_sink_activate_push (GstPad * pad, 
    1.24 +    gboolean active);
    1.25  static gboolean gst_nuv_demux_sink_activate (GstPad * sinkpad);
    1.26  static GstFlowReturn gst_nuv_demux_read_bytes (GstNuvDemux * nuv, guint64 size,
    1.27      gboolean move, GstBuffer ** buffer);
    1.28  static void gst_nuv_demux_reset (GstNuvDemux * nuv);
    1.29 -static gboolean gst_nuv_demux_handle_sink_event (GstPad * sinkpad,
    1.30 -    GstEvent * event);
    1.31 -static gboolean gst_nuv_demux_handle_audio_src_event (GstPad * sinkpad,
    1.32 -    GstEvent * event);
    1.33 -static gboolean gst_nuv_demux_handle_video_src_event (GstPad * sinkpad,
    1.34 -    GstEvent * event);
    1.35  static void gst_nuv_demux_destoy_src_pad (GstNuvDemux * nuv);
    1.36  static void gst_nuv_demux_send_eos (GstNuvDemux * nuv);
    1.37  
    1.38 @@ -182,11 +169,12 @@
    1.39    gst_pad_set_activatepull_function (nuv->sinkpad,
    1.40        gst_nuv_demux_sink_activate_pull);
    1.41  
    1.42 +  gst_pad_set_activatepush_function (nuv->sinkpad, 
    1.43 +      gst_nuv_demux_sink_activate_push);
    1.44 +
    1.45    gst_pad_set_chain_function (nuv->sinkpad,
    1.46        GST_DEBUG_FUNCPTR (gst_nuv_demux_chain));
    1.47  
    1.48 -  gst_pad_set_event_function (nuv->sinkpad, gst_nuv_demux_handle_sink_event);
    1.49 -
    1.50    gst_element_add_pad (GST_ELEMENT (nuv), nuv->sinkpad);
    1.51    
    1.52    gst_nuv_demux_index_init( &nuv->index_entries );
    1.53 @@ -222,149 +210,6 @@
    1.54  }
    1.55  
    1.56  
    1.57 -/*****************************************************************************
    1.58 - * Indexes (timecode offset conversion) functions
    1.59 - *****************************************************************************/
    1.60 -
    1.61 -static void 
    1.62 -gst_nuv_demux_index_init( nuv_demux_index **p_idx )
    1.63 -{
    1.64 -	*p_idx = g_new0( nuv_demux_index, 1 );
    1.65 -	(*p_idx)->i_idx = 0;
    1.66 -	(*p_idx)->i_idx_max = 0;
    1.67 -}
    1.68 -
    1.69 -static void 
    1.70 -gst_nuv_demux_index_clean( nuv_demux_index **p_idx )
    1.71 -{
    1.72 -	if ( *p_idx != NULL ) {
    1.73 -		g_free( *p_idx );
    1.74 -		*p_idx = NULL;
    1.75 -	}
    1.76 -
    1.77 -}
    1.78 -
    1.79 -static void 
    1.80 -gst_nuv_demux_index_append( GstNuvDemux *nuv, gint64 i_time, gint64 i_offset )
    1.81 -{
    1.82 -	nuv_demux_index *p_idx = nuv->index_entries;
    1.83 -
    1.84 -	//if ( p_idx == NULL )
    1.85 -	//	return;
    1.86 -
    1.87 -	/* Be sure to append new entry (we don't insert point) */
    1.88 -	if( p_idx != NULL && p_idx->i_idx > 0 && p_idx->idx[p_idx->i_idx-1].i_time >= i_time )
    1.89 -		return;
    1.90 -
    1.91 -	/* */
    1.92 -	if( p_idx->i_idx >= p_idx->i_idx_max )
    1.93 -	{
    1.94 -		if( p_idx->i_idx >= DEMUX_INDEX_SIZE_MAX )
    1.95 -		{
    1.96 -			/* Avoid too big index */
    1.97 -			const gint64 i_length = p_idx->idx[p_idx->i_idx-1].i_time -
    1.98 -				p_idx->idx[0].i_time;
    1.99 -			const gint i_count = DEMUX_INDEX_SIZE_MAX/2;
   1.100 -			gint i, j;
   1.101 -
   1.102 -			/* We try to reduce the resolution of the index by a factor 2 */
   1.103 -			for( i = 1, j = 1; i < p_idx->i_idx; i++ )
   1.104 -			{
   1.105 -				if( p_idx->idx[i].i_time < j * i_length / i_count )
   1.106 -					continue;
   1.107 -
   1.108 -				p_idx->idx[j++] = p_idx->idx[i];
   1.109 -			}
   1.110 -			p_idx->i_idx = j;
   1.111 -
   1.112 -			if( p_idx->i_idx > 3 * DEMUX_INDEX_SIZE_MAX / 4 )
   1.113 -			{
   1.114 -				/* We haven't created enough space
   1.115 -				 * (This method won't create a good index but work for sure) */
   1.116 -				for( i = 0; i < p_idx->i_idx/2; i++ )
   1.117 -					p_idx->idx[i] = p_idx->idx[2*i];
   1.118 -				p_idx->i_idx /= 2;
   1.119 -			}
   1.120 -		}
   1.121 -		else
   1.122 -		{
   1.123 -			p_idx->i_idx_max += 1000;
   1.124 -		}
   1.125 -	}
   1.126 -
   1.127 -	/* */
   1.128 -	p_idx->idx[p_idx->i_idx].i_time = i_time;
   1.129 -	p_idx->idx[p_idx->i_idx].i_offset = i_offset;
   1.130 -
   1.131 -	p_idx->i_idx++;
   1.132 -}
   1.133 -
   1.134 -static gint64 
   1.135 -gst_nuv_demux_index_convert_time( GstNuvDemux *nuv, gint64 i_time )
   1.136 -{
   1.137 -	nuv_demux_index *p_idx = nuv->index_entries;
   1.138 -
   1.139 -	g_return_val_if_fail( p_idx != NULL , i_time );
   1.140 -
   1.141 -	gint i_min = 0;
   1.142 -	gint i_max = p_idx->i_idx-1;
   1.143 -
   1.144 -	/* Empty index */
   1.145 -	if( p_idx->i_idx <= 0 )
   1.146 -		return -1;
   1.147 -
   1.148 -	/* Special border case */
   1.149 -	if( i_time <= p_idx->idx[0].i_time )
   1.150 -		return p_idx->idx[0].i_offset;
   1.151 -	if( i_time >= p_idx->idx[i_max].i_time )
   1.152 -		return p_idx->idx[i_max].i_offset;
   1.153 -
   1.154 -	/* Dicho */
   1.155 -	for( ;; )
   1.156 -	{
   1.157 -		gint i_med;
   1.158 -
   1.159 -		if( i_max - i_min <= 1 )
   1.160 -			break;
   1.161 -
   1.162 -		i_med = (i_min+i_max)/2;
   1.163 -		if( p_idx->idx[i_med].i_time < i_time )
   1.164 -			i_min = i_med;
   1.165 -		else if( p_idx->idx[i_med].i_time > i_time )
   1.166 -			i_max = i_med;
   1.167 -		else
   1.168 -			return p_idx->idx[i_med].i_offset;
   1.169 -	}
   1.170 -
   1.171 -	/* return nearest in time */
   1.172 -	if( i_time - p_idx->idx[i_min].i_time < p_idx->idx[i_max].i_time - i_time )
   1.173 -		return p_idx->idx[i_min].i_offset;
   1.174 -	else
   1.175 -		return p_idx->idx[i_max].i_offset;
   1.176 -}
   1.177 -
   1.178 -/*****************************************************************************
   1.179 - * Utils functions
   1.180 - *****************************************************************************/
   1.181 -
   1.182 -static gboolean
   1.183 -gst_nuv_demux_handle_sink_event (GstPad * sinkpad, GstEvent * event)
   1.184 -{
   1.185 -  gboolean res = FALSE;
   1.186 -
   1.187 -  switch (GST_EVENT_TYPE (event)) {
   1.188 -    case GST_EVENT_NEWSEGMENT:
   1.189 -      res = TRUE;
   1.190 -      break;
   1.191 -    default:
   1.192 -      return gst_pad_event_default (sinkpad, event);
   1.193 -      break;
   1.194 -  }
   1.195 -
   1.196 -  gst_event_unref (event);
   1.197 -  return res;
   1.198 -}
   1.199 -
   1.200  /* HeaderLoad:
   1.201   */
   1.202  static GstFlowReturn
   1.203 @@ -384,7 +229,7 @@
   1.204    h->i_height = GST_READ_UINT32_LE (&buffer->data[24]);
   1.205    h->i_width_desired = GST_READ_UINT32_LE (&buffer->data[28]);
   1.206    h->i_height_desired = GST_READ_UINT32_LE (&buffer->data[32]);
   1.207 -  h->i_mode = buffer->data[36];
   1.208 +  h->i_mode = GPOINTER_TO_INT (buffer->data[36]);
   1.209    h->d_aspect = READ_DOUBLE_FROM_LE (&buffer->data[40]);
   1.210    h->d_fps = READ_DOUBLE_FROM_LE (&buffer->data[48]);
   1.211    h->i_video_blocks = GST_READ_UINT32_LE (&buffer->data[56]);
   1.212 @@ -462,15 +307,13 @@
   1.213    h = g_new0 (nuv_frame_header, 1);
   1.214    data = buf->data;
   1.215  
   1.216 -  h->i_type = data[0];
   1.217 -  h->i_compression = data[1];
   1.218 -  h->i_keyframe = data[2];
   1.219 -  h->i_filters = data[3];
   1.220 -
   1.221 +  h->i_type = GPOINTER_TO_INT (data[0]);
   1.222 +  h->i_compression = GPOINTER_TO_INT (data[1]);
   1.223 +  h->i_keyframe = GPOINTER_TO_INT (data[2]);
   1.224 +  h->i_filters = GPOINTER_TO_INT (data[3]);
   1.225    h->i_timecode = GST_READ_UINT32_LE (&data[4]);
   1.226 -
   1.227 -
   1.228    h->i_length = GST_READ_UINT32_LE (&data[8]);
   1.229 +  
   1.230    GST_DEBUG_OBJECT (nuv, "frame hdr: t=%c c=%c k=%d f=0x%x timecode=%d l=%d",
   1.231        h->i_type,
   1.232        h->i_compression ? h->i_compression : ' ',
   1.233 @@ -535,20 +378,6 @@
   1.234    return res;
   1.235  }
   1.236  
   1.237 -static gboolean
   1.238 -gst_nuv_demux_handle_audio_src_event (GstPad * pad, GstEvent * event)
   1.239 -{
   1.240 -  gst_event_unref (event);
   1.241 -  return FALSE;
   1.242 -}
   1.243 -
   1.244 -static gboolean
   1.245 -gst_nuv_demux_handle_video_src_event (GstPad * pad, GstEvent * event)
   1.246 -{
   1.247 -  gst_event_unref (event);
   1.248 -  return FALSE;
   1.249 -}
   1.250 -
   1.251  static void
   1.252  gst_nuv_demux_create_pads (GstNuvDemux * nuv)
   1.253  {
   1.254 @@ -563,14 +392,12 @@
   1.255          "width", G_TYPE_INT, nuv->h->i_width,
   1.256          "height", G_TYPE_INT, nuv->h->i_height,
   1.257          "framerate", GST_TYPE_FRACTION, (gint) (nuv->h->d_fps * 1000.0f), 1000,
   1.258 +        "format", GST_TYPE_FOURCC, nuv->eh->i_video_fcc,
   1.259          "pixel-aspect-ratio", GST_TYPE_FRACTION,
   1.260          (gint) (nuv->h->d_aspect * 1000.0f), 1000, NULL);
   1.261  
   1.262      gst_pad_use_fixed_caps (nuv->src_video_pad);
   1.263      gst_pad_set_caps (nuv->src_video_pad, video_caps);
   1.264 -
   1.265 -    gst_pad_set_event_function (nuv->src_video_pad,
   1.266 -	    	gst_nuv_demux_handle_video_src_event);
   1.267      gst_pad_set_active (nuv->src_video_pad, TRUE);
   1.268      gst_element_add_pad (GST_ELEMENT (nuv), nuv->src_video_pad);
   1.269  
   1.270 @@ -591,12 +418,8 @@
   1.271  
   1.272      gst_pad_use_fixed_caps (nuv->src_audio_pad);
   1.273      gst_pad_set_caps (nuv->src_audio_pad, audio_caps);
   1.274 -    
   1.275 -    gst_pad_set_event_function (nuv->src_audio_pad,
   1.276 -  		  gst_nuv_demux_handle_audio_src_event);
   1.277      gst_pad_set_active (nuv->src_audio_pad, TRUE);
   1.278      gst_element_add_pad (GST_ELEMENT (nuv), nuv->src_audio_pad);
   1.279 -
   1.280      gst_caps_unref (audio_caps);
   1.281    }
   1.282  
   1.283 @@ -608,6 +431,12 @@
   1.284  {
   1.285    GstFlowReturn ret = GST_FLOW_OK;
   1.286  
   1.287 +  if (nuv->fh != NULL) 
   1.288 +  {
   1.289 +    g_free (nuv->fh);
   1.290 +    nuv->fh = NULL;
   1.291 +  }
   1.292 +  
   1.293    ret = gst_nuv_demux_frame_header_load (nuv, &nuv->fh);
   1.294    if (ret != GST_FLOW_OK)
   1.295      return ret;
   1.296 @@ -622,38 +451,35 @@
   1.297    GstFlowReturn ret = GST_FLOW_OK;
   1.298    GstBuffer *buf = NULL;
   1.299    nuv_frame_header *h = nuv->fh;
   1.300 -  
   1.301 -  gint64 table_timecode = 0;
   1.302  
   1.303    if (h->i_type == 'R')
   1.304      goto done;
   1.305      
   1.306 -  table_timecode = h->i_timecode;
   1.307 -
   1.308 -  /* append the frame's header timecode field, and the actual offset */
   1.309 -  if ( h->i_type == 'V' ) 
   1.310 -  	gst_nuv_demux_index_append( nuv, h->i_timecode, nuv->video_offset );
   1.311 -  else if ( h->i_type == 'A' ) 
   1.312 -  	gst_nuv_demux_index_append( nuv, h->i_timecode, nuv->audio_offset );  	
   1.313 - 
   1.314    if (h->i_length > 0) {
   1.315  	  ret = gst_nuv_demux_read_bytes (nuv, h->i_length, TRUE, &buf);
   1.316  	  if (ret != GST_FLOW_OK)
   1.317  		  return ret;
   1.318  
   1.319 -	  /* search for a valid timecode in the indexes list (find the nearest valid timecode) */
   1.320 -	  if ( h->i_timecode < 0 ) {
   1.321 -		  /* convert this actual timecode to a valid index in the timecode's table */
   1.322 -		  gint64 pos = gst_nuv_demux_index_convert_time( nuv, h->i_timecode );
   1.323 +      if ((h->i_type == 'V') || (h->i_type == 'A')) {
   1.324 +        if (h->i_timecode < 0) {
   1.325 +            nuv->last_time = 1;
   1.326 +            h->i_timecode = 0;
   1.327 +        }
   1.328 +        else if (nuv->last_time == 1)
   1.329 +        {
   1.330 +          nuv->last_time = 0;
   1.331 +          gst_pad_push_event (nuv->src_video_pad,
   1.332 +              gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, 
   1.333 +              		GST_CLOCK_TIME_NONE, 0));
   1.334  
   1.335 -		  /* just get the timecode from the timecode's table */		  
   1.336 -		  table_timecode = nuv->index_entries->idx[pos].i_time * GST_MSECOND;
   1.337 -	  } else {  
   1.338 -			table_timecode = h->i_timecode * GST_MSECOND;
   1.339 -	  }
   1.340 -	  
   1.341 -	  GST_BUFFER_TIMESTAMP (buf) = table_timecode;
   1.342 -  }  
   1.343 +          gst_pad_push_event (nuv->src_audio_pad,
   1.344 +              gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, 
   1.345 +              		GST_CLOCK_TIME_NONE, 0));
   1.346 +        }
   1.347 +
   1.348 +        GST_BUFFER_TIMESTAMP (buf) = h->i_timecode * GST_MSECOND;
   1.349 +      }    
   1.350 +  }
   1.351  
   1.352    switch (h->i_type) {
   1.353      case 'V':
   1.354 @@ -664,14 +490,13 @@
   1.355        if ( !gst_pad_is_linked( nuv->src_video_pad ) )
   1.356        	break;
   1.357        
   1.358 -      //GST_PAD_STREAM_LOCK(nuv->src_video_pad);
   1.359 -      
   1.360        GST_BUFFER_SIZE (buf) = h->i_length;
   1.361        gst_buffer_set_caps (buf, GST_PAD_CAPS (nuv->src_video_pad));
   1.362        ret = gst_pad_push (nuv->src_video_pad, buf);
   1.363 -      nuv->video_offset += h->i_length;
   1.364 -      
   1.365 -      //GST_PAD_STREAM_UNLOCK(nuv->src_video_pad);
   1.366 +      if (ret != GST_FLOW_OK) {
   1.367 +        GST_WARNING_OBJECT (nuv, "error pushing on srcpad %s, is linked? = %d",
   1.368 +            gst_pad_get_name (nuv->src_video_pad), gst_pad_is_linked (nuv->src_video_pad));
   1.369 +      }
   1.370        break;
   1.371      }
   1.372      case 'A':
   1.373 @@ -682,42 +507,41 @@
   1.374        if ( !gst_pad_is_linked( nuv->src_audio_pad ) )
   1.375        	break;
   1.376          
   1.377 -      //GST_PAD_STREAM_LOCK(nuv->src_audio_pad);
   1.378 -      
   1.379        GST_BUFFER_SIZE (buf) = h->i_length;
   1.380        gst_buffer_set_caps (buf, GST_PAD_CAPS (nuv->src_audio_pad));
   1.381        ret = gst_pad_push (nuv->src_audio_pad, buf);
   1.382 -      nuv->audio_offset += h->i_length;
   1.383 -      
   1.384 -      //GST_PAD_STREAM_UNLOCK(nuv->src_audio_pad);
   1.385 +      if (ret != GST_FLOW_OK) {
   1.386 +        GST_WARNING_OBJECT (nuv, "Error pushing on srcpad %s, is linked? = %d",
   1.387 +            gst_pad_get_name (nuv->src_audio_pad), gst_pad_is_linked (nuv->src_audio_pad));
   1.388 +      }
   1.389        break;
   1.390      }
   1.391      case 'S':
   1.392      {
   1.393        switch (h->i_compression) {
   1.394          case 'V':
   1.395 -		      if ( !gst_pad_is_linked( nuv->src_video_pad ) )
   1.396 -		      	break;
   1.397 +		  if ( !gst_pad_is_linked( nuv->src_video_pad ) )
   1.398 +		    break;
   1.399  
   1.400 -        	//GST_PAD_STREAM_LOCK(nuv->src_video_pad);
   1.401 +          GST_DEBUG_OBJECT (nuv, "sending new video segment: %d", h->i_timecode);
   1.402            gst_pad_push_event (nuv->src_video_pad,
   1.403 -              gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, table_timecode, 
   1.404 +              gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, h->i_timecode * GST_MSECOND, 
   1.405                		GST_CLOCK_TIME_NONE, 0));
   1.406 -          //GST_PAD_STREAM_UNLOCK(nuv->src_video_pad);
   1.407            break;
   1.408          case 'A':        
   1.409  		      if ( !gst_pad_is_linked( nuv->src_audio_pad ) )
   1.410  		      	break;
   1.411  
   1.412 -        	//GST_PAD_STREAM_LOCK(nuv->src_audio_pad);
   1.413 +          GST_DEBUG_OBJECT (nuv, "sending new audio segment: %d", h->i_timecode);
   1.414            gst_pad_push_event (nuv->src_audio_pad,
   1.415 -              gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, table_timecode, 
   1.416 +              gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, 
   1.417                		GST_CLOCK_TIME_NONE, 0));
   1.418 -          //GST_PAD_STREAM_UNLOCK(nuv->src_audio_pad);
   1.419            break;
   1.420          default:
   1.421            break;
   1.422        }
   1.423 +      if (buf != NULL)
   1.424 +        gst_buffer_unref (buf);
   1.425      }
   1.426      default:
   1.427        if (buf != NULL)
   1.428 @@ -743,7 +567,7 @@
   1.429        gst_nuv_demux_read_bytes (nuv, nuv->mpeg_data_size, TRUE,
   1.430        &nuv->mpeg_buffer);
   1.431    if (ret != GST_FLOW_OK) {
   1.432 -    return ret; //GST_FLOW_ERROR;
   1.433 +    return ret; 
   1.434    }
   1.435    GST_BUFFER_SIZE (nuv->mpeg_buffer) = nuv->mpeg_data_size;
   1.436    nuv->state = GST_NUV_DEMUX_EXTEND_HEADER;
   1.437 @@ -904,7 +728,7 @@
   1.438  
   1.439      case GST_NUV_DEMUX_MOVI:
   1.440        res = gst_nuv_demux_stream_data (nuv);
   1.441 -      if ((res != GST_FLOW_OK) && (res != GST_FLOW_ERROR_NO_DATA) && (res != GST_FLOW_CUSTOM_ERROR)) {
   1.442 +      if ((res != GST_FLOW_OK) && (res != GST_FLOW_ERROR_NO_DATA)) {
   1.443          goto pause;
   1.444        }
   1.445        break;
   1.446 @@ -959,11 +783,14 @@
   1.447    if (nuv->mode == 0) {
   1.448      ret = gst_pad_pull_range (nuv->sinkpad, nuv->offset, size, buffer);
   1.449      if (ret == GST_FLOW_OK) {
   1.450 -    		if (move) {
   1.451 -					nuv->offset += size;
   1.452 -				}    	
   1.453 +        if (move) {
   1.454 +		    nuv->offset += size;
   1.455 +		}
   1.456        /* got eos */
   1.457      } else if (ret == GST_FLOW_UNEXPECTED) {
   1.458 +      if (buffer != NULL)
   1.459 +          gst_buffer_unref (buffer);
   1.460 +      
   1.461        gst_nuv_demux_send_eos (nuv);
   1.462        return GST_FLOW_WRONG_STATE;
   1.463      }
   1.464 @@ -972,17 +799,17 @@
   1.465        return GST_FLOW_ERROR_NO_DATA;
   1.466  
   1.467      if (move) {
   1.468 -      *buffer = gst_adapter_take_buffer (nuv->adapter, size);
   1.469 +      guint8 *data = NULL;
   1.470 +      data = (guint8 *) gst_adapter_take (nuv->adapter, size);
   1.471 +      *buffer = gst_buffer_new ();
   1.472 +      gst_buffer_set_data (*buffer, data, size);
   1.473      } else {
   1.474        guint8 *data = NULL;
   1.475 -
   1.476        data = (guint8 *) gst_adapter_peek (nuv->adapter, size);
   1.477        *buffer = gst_buffer_new ();
   1.478        gst_buffer_set_data (*buffer, data, size);
   1.479      }
   1.480    }
   1.481 -  
   1.482 -	
   1.483    return ret;
   1.484  }
   1.485  
   1.486 @@ -1009,7 +836,6 @@
   1.487      }
   1.488      res = gst_pad_activate_push (sinkpad, TRUE);
   1.489    }
   1.490 -
   1.491    g_object_unref (nuv);
   1.492    return res;
   1.493  }
   1.494 @@ -1029,6 +855,22 @@
   1.495    return TRUE;
   1.496  }
   1.497  
   1.498 +static gboolean
   1.499 +gst_nuv_demux_sink_activate_push (GstPad * pad, gboolean active)
   1.500 +{
   1.501 +  GstNuvDemux *nuv = GST_NUV_DEMUX (gst_pad_get_parent (pad));
   1.502 +
   1.503 +  if (active) {
   1.504 +    GST_DEBUG_OBJECT (nuv, "activating push/chain function");
   1.505 +  } else {
   1.506 +    GST_DEBUG_OBJECT (nuv, "deactivating push/chain function");
   1.507 +  }
   1.508 +
   1.509 +  gst_object_unref (nuv);
   1.510 +
   1.511 +  return TRUE;
   1.512 +}
   1.513 +
   1.514  static GstFlowReturn
   1.515  gst_nuv_demux_chain (GstPad * pad, GstBuffer * buf)
   1.516  {
   1.517 @@ -1036,6 +878,8 @@
   1.518  
   1.519    gst_adapter_push (nuv->adapter, buf);
   1.520  
   1.521 +  gst_object_unref (nuv);
   1.522 +
   1.523    return gst_nuv_demux_play (pad);
   1.524  }
   1.525  
   1.526 @@ -1051,8 +895,7 @@
   1.527    nuv->state = GST_NUV_DEMUX_START;
   1.528    nuv->mode = 0;
   1.529    nuv->offset = 0;
   1.530 -  nuv->video_offset = 0;
   1.531 -  nuv->audio_offset = 0;
   1.532 +  nuv->last_time = 0;
   1.533  
   1.534    if (nuv->adapter != NULL)
   1.535      gst_adapter_clear (nuv->adapter);