gst-plugins-nuvdemux/nuvdemux/gstnuvdemux.c
branchtrunk
changeset 430 4476d11d6b9a
parent 425 9638cccfa1fe
child 431 d22290a50589
     1.1 --- a/gst-plugins-nuvdemux/nuvdemux/gstnuvdemux.c	Wed Mar 21 21:35:20 2007 +0000
     1.2 +++ b/gst-plugins-nuvdemux/nuvdemux/gstnuvdemux.c	Thu Mar 22 18:54:35 2007 +0000
     1.3 @@ -141,6 +141,7 @@
     1.4                             S: length of packet correl */
     1.5  } nuv_frame_header;
     1.6  
     1.7 +
     1.8  /* FIXME Not sure of this one */
     1.9  typedef struct
    1.10  {
    1.11 @@ -160,11 +161,18 @@
    1.12      gint             i_lavc_qmin;
    1.13      gint             i_lavc_qmax;
    1.14      gint             i_lavc_maxqdiff;
    1.15 -    gint64         	 i_seekable_offset;
    1.16 +    gint64           i_seekable_offset;
    1.17      gint64           i_keyframe_adjust_offset;
    1.18  
    1.19  } nuv_extended_header;
    1.20  
    1.21 +typedef struct
    1.22 +{
    1.23 +  gint64 timecode;
    1.24 +  gint64 offset;
    1.25 +
    1.26 +} frame_index_data;
    1.27 +
    1.28  typedef enum {
    1.29    GST_NUV_DEMUX_START,
    1.30    GST_NUV_DEMUX_HEADER_DATA,
    1.31 @@ -172,6 +180,7 @@
    1.32    GST_NUV_DEMUX_MPEG_DATA,
    1.33    GST_NUV_DEMUX_EXTEND_HEADER,
    1.34    GST_NUV_DEMUX_EXTEND_HEADER_DATA,
    1.35 +  GST_NUV_DEMUX_INDEX_CREATE,
    1.36    GST_NUV_DEMUX_FRAME_HEADER,
    1.37    GST_NUV_DEMUX_MOVI,
    1.38    GST_NUV_DEMUX_INVALID_DATA
    1.39 @@ -196,15 +205,13 @@
    1.40  
    1.41    /* NUV decoding state */
    1.42    GstNuvDemuxState  state;
    1.43 -  GstSegment        segment;
    1.44 -  guint64           last_update;
    1.45    guint64           offset;
    1.46 -  guint64           streamer_offset;
    1.47  
    1.48    /* duration information */
    1.49 -  gint64            duration_bytes;
    1.50 -  gint64            duration_time;
    1.51 -  gint64            duration_average;
    1.52 +  guint64            duration_bytes;
    1.53 +  guint64            duration_time;
    1.54 +  guint64            segment_stop;
    1.55 +  guint64            segment_start;
    1.56  
    1.57    /* segment control info */
    1.58    gboolean          new_audio_segment;
    1.59 @@ -220,10 +227,12 @@
    1.60    nuv_frame_header fh;
    1.61  
    1.62    /* anothers info */
    1.63 +  gint64            header_lengh;
    1.64    gint64            time_start;
    1.65    gint64            time_diff;
    1.66    gint64            time_qos;
    1.67    guint64           last_frame_time;
    1.68 +  GSList            *index;
    1.69  };
    1.70  
    1.71  
    1.72 @@ -256,8 +265,12 @@
    1.73  static gboolean gst_nuv_demux_sink_activate_push (GstPad * pad,
    1.74      gboolean active);
    1.75  static gboolean gst_nuv_demux_sink_activate (GstPad * sinkpad);
    1.76 -static gboolean gst_nuv_demux_sink_event    (GstPad *pad, GstEvent *event);
    1.77 +//static gboolean gst_nuv_demux_sink_event    (GstPad *pad, GstEvent *event);
    1.78  static gboolean gst_nuv_demux_srcpad_event  (GstPad * pad, GstEvent * event);
    1.79 +static frame_index_data * gst_nuv_demux_do_seek_index (GstNuvDemux *nuv, gint64 seek_pos, 
    1.80 +  gint64 segment_stop, GstFormat format);
    1.81 +
    1.82 +
    1.83  
    1.84  static GstFlowReturn gst_nuv_demux_read_bytes (GstNuvDemux * nuv, guint64 size,
    1.85      gboolean move, GstBuffer ** buffer);
    1.86 @@ -267,6 +280,8 @@
    1.87  static void gst_nuv_demux_update_duration (GstNuvDemux *nuv, guint64 current_timestamp);
    1.88  static gint64 gst_nuv_demux_get_bytes_duration (GstNuvDemux *nuv);
    1.89  static gint64 gst_nuv_demux_get_time_duration (GstNuvDemux *nuv);
    1.90 +static void gst_nuv_demux_create_seek_index (GstNuvDemux * nuv);
    1.91 +
    1.92  
    1.93  #if (GST_VERSION_MINOR == 10) && (GST_VERSION_MICRO < 6) 
    1.94  GstBuffer * gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes);
    1.95 @@ -375,8 +390,10 @@
    1.96        gst_nuv_demux_sink_activate_push);
    1.97    gst_pad_set_chain_function (nuv->priv->sinkpad,
    1.98        GST_DEBUG_FUNCPTR (gst_nuv_demux_chain));
    1.99 +/*
   1.100    gst_pad_set_event_function (nuv->priv->sinkpad,
   1.101        gst_nuv_demux_sink_event);
   1.102 +*/
   1.103  
   1.104    gst_element_add_pad (GST_ELEMENT (nuv), nuv->priv->sinkpad);
   1.105  
   1.106 @@ -523,6 +540,7 @@
   1.107        gst_buffer_unref (buf);
   1.108        buf = NULL;
   1.109    }
   1.110 +
   1.111    return res;
   1.112  }
   1.113  
   1.114 @@ -599,21 +617,16 @@
   1.115    switch (GST_QUERY_TYPE (query)) {
   1.116      case GST_QUERY_POSITION:
   1.117        if (GST_CLOCK_TIME_IS_VALID (nuv->priv->last_frame_time)) {
   1.118 -
   1.119          gst_query_set_position (query, GST_FORMAT_TIME, nuv->priv->last_frame_time);
   1.120          res = TRUE;
   1.121        }
   1.122        break;
   1.123      case GST_QUERY_DURATION:
   1.124        {
   1.125 -        gint64 duration = 0;
   1.126 -        duration = gst_nuv_demux_get_time_duration (nuv);
   1.127 -        if (duration == GST_CLOCK_TIME_NONE) {
   1.128 -            duration = nuv->priv->duration_average;
   1.129 -        }
   1.130 -        if (duration != GST_CLOCK_TIME_NONE) {
   1.131 -            gst_query_set_duration (query, GST_FORMAT_TIME, duration);
   1.132 -            res = TRUE;
   1.133 +  	g_debug ("QUERY DURATION %" G_GUINT64_FORMAT, nuv->priv->duration_time); 
   1.134 +        if (nuv->priv->duration_time == GST_CLOCK_TIME_NONE) {
   1.135 +            gst_query_set_duration (query, GST_FORMAT_TIME, nuv->priv->duration_time);
   1.136 +	    res = TRUE;
   1.137          }
   1.138        }
   1.139        break;
   1.140 @@ -636,8 +649,9 @@
   1.141      gst_pad_set_active (pad, TRUE);
   1.142      gst_pad_use_fixed_caps (pad);
   1.143      gst_element_add_pad (GST_ELEMENT (nuv), pad);
   1.144 -    gst_pad_set_event_function (pad, 
   1.145 -        GST_DEBUG_FUNCPTR (gst_nuv_demux_srcpad_event));
   1.146 +
   1.147 +    gst_pad_set_event_function (pad,
   1.148 +      gst_nuv_demux_srcpad_event);
   1.149  
   1.150      return pad;
   1.151  }
   1.152 @@ -721,6 +735,7 @@
   1.153      case 'S':
   1.154      case 'R':
   1.155      case 'D':
   1.156 +    case 'Q':
   1.157        valid  = TRUE;
   1.158        break;
   1.159      default:
   1.160 @@ -744,14 +759,12 @@
   1.161      }
   1.162  
   1.163      if (gst_nuv_demux_validate_header (&nuv->priv->fh) == TRUE)
   1.164 -	valid = TRUE;
   1.165 +	    valid = TRUE;
   1.166      else 
   1.167 -       g_debug ("Invalid frame header");
   1.168 +      g_debug ("Invalid frame header");
   1.169  
   1.170    } while (valid == FALSE);
   1.171  
   1.172 -//  } while (gst_nuv_demux_validate_header (nuv->priv->fh));    
   1.173 -
   1.174    nuv->priv->state = GST_NUV_DEMUX_MOVI;
   1.175    return ret;
   1.176  }
   1.177 @@ -871,11 +884,6 @@
   1.178    }
   1.179  
   1.180    if ((buf != NULL) && (pad != NULL)) {
   1.181 -      /* update average time */
   1.182 -      nuv->priv->streamer_offset += h.i_length;
   1.183 -      gst_segment_set_last_stop (&nuv->priv->segment, GST_FORMAT_TIME, timestamp);
   1.184 -      gst_nuv_demux_update_duration (nuv, timestamp);
   1.185 -
   1.186        /* pushing the buffer */
   1.187        gst_buffer_set_caps (buf, GST_PAD_CAPS (pad));
   1.188        ret = gst_pad_push (pad, buf);
   1.189 @@ -971,7 +979,7 @@
   1.190      return ret;
   1.191  
   1.192    gst_nuv_demux_create_pads (nuv);
   1.193 -  nuv->priv->state = GST_NUV_DEMUX_FRAME_HEADER;
   1.194 +  nuv->priv->state = GST_NUV_DEMUX_INDEX_CREATE;
   1.195    return ret;
   1.196  }
   1.197  
   1.198 @@ -1012,6 +1020,38 @@
   1.199    return res;
   1.200  }
   1.201  
   1.202 +static void
   1.203 +gst_nuv_demux_create_seek_index (GstNuvDemux * nuv)
   1.204 +{
   1.205 +  GstMessage *msg;
   1.206 +  nuv_frame_header h;
   1.207 +  g_debug ("CREATING INDEX");
   1.208 +
   1.209 +  while (gst_nuv_demux_frame_header_load (nuv, &h) == GST_FLOW_OK) {
   1.210 +    if (h.i_keyframe == 0) {
   1.211 +    //if (h.i_type == 'V') {
   1.212 +      frame_index_data *f = g_new0 (frame_index_data, 1);
   1.213 +      g_debug ("KEY FRAME AT %lld", nuv->priv->offset);
   1.214 +
   1.215 +      f->offset = nuv->priv->offset - 12;
   1.216 +      f->timecode = h.i_timecode * GST_MSECOND;
   1.217 +
   1.218 +      nuv->priv->index = g_slist_append (nuv->priv->index, f);
   1.219 +    } 
   1.220 +    if (h.i_type != 'R') {
   1.221 +      nuv->priv->offset += h.i_length;
   1.222 +		  if (h.i_type == 'A' || h.i_type == 'V')
   1.223 +  		  nuv->priv->duration_time = h.i_timecode * GST_MSECOND;
   1.224 +    }
   1.225 +  }
   1.226 +  g_debug ("CREATING INDEX: DONE : DURATION Bytes/Sec: %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, nuv->priv->offset, nuv->priv->duration_time);
   1.227 +  nuv->priv->duration_bytes = nuv->priv->offset;
   1.228 +  nuv->priv->offset = nuv->priv->header_lengh;
   1.229 +
   1.230 +  msg = gst_message_new_duration (GST_OBJECT (nuv), GST_FORMAT_TIME, nuv->priv->duration_time);
   1.231 +  gst_element_post_message (GST_ELEMENT (nuv), msg);
   1.232 +}
   1.233 +
   1.234  
   1.235  static GstFlowReturn
   1.236  gst_nuv_demux_play (GstPad * pad)
   1.237 @@ -1060,6 +1100,15 @@
   1.238        if ((res != GST_FLOW_OK) && (res != GST_FLOW_ERROR_NO_DATA)) {
   1.239          goto pause;
   1.240        }
   1.241 +      //store file header size
   1.242 +      nuv->priv->header_lengh = nuv->priv->offset;
   1.243 +      break;
   1.244 +
   1.245 +    case GST_NUV_DEMUX_INDEX_CREATE:
   1.246 +      if (nuv->priv->mode = NUV_PULL_MODE) {
   1.247 +        gst_nuv_demux_create_seek_index (nuv);
   1.248 +      }
   1.249 +      nuv->priv->state = GST_NUV_DEMUX_FRAME_HEADER;
   1.250        break;
   1.251  
   1.252      case GST_NUV_DEMUX_FRAME_HEADER:
   1.253 @@ -1123,15 +1172,13 @@
   1.254    if (nuv->priv->mode == NUV_PULL_MODE) {
   1.255      ret = gst_pad_pull_range (nuv->priv->sinkpad, nuv->priv->offset, size, buffer);
   1.256      if (ret == GST_FLOW_OK) {
   1.257 -        if (move) {
   1.258 -		    nuv->priv->offset += size;
   1.259 -		}
   1.260 +      if (move) {
   1.261 +        nuv->priv->offset += size;
   1.262 +      }
   1.263        /* got eos */
   1.264      } else if (ret == GST_FLOW_UNEXPECTED) {
   1.265 -      if (buffer != NULL)
   1.266 -          gst_buffer_unref (buffer);
   1.267 -
   1.268 -      gst_nuv_demux_send_eos (nuv);
   1.269 +      g_debug ("GOT EOS");
   1.270 +      //gst_nuv_demux_send_eos (nuv);
   1.271        return GST_FLOW_WRONG_STATE;
   1.272      }
   1.273    } else {
   1.274 @@ -1213,6 +1260,41 @@
   1.275    return TRUE;
   1.276  }
   1.277  
   1.278 +static frame_index_data *
   1.279 +gst_nuv_demux_do_seek_index (GstNuvDemux *nuv, gint64 seek_pos, 
   1.280 +  gint64 segment_stop, GstFormat format)
   1.281 +{
   1.282 +  GSList *l;
   1.283 +  frame_index_data *ret = NULL;
   1.284 +
   1.285 +  if (nuv->priv->index == NULL) {
   1.286 +    return NULL;
   1.287 +  }
   1.288 +
   1.289 +  /* find keyframe closest to the requested position  */
   1.290 +  for (l = nuv->priv->index; l != NULL; l = l->next) {
   1.291 +    frame_index_data *f = (frame_index_data *) l->data;  
   1.292 +    gint64 pos = 0;
   1.293 +   
   1.294 +    if (format == GST_FORMAT_BYTES) {     
   1.295 +      pos = f->offset;
   1.296 +    } else if (format == GST_FORMAT_TIME) {
   1.297 +      pos = f->timecode;
   1.298 +    } else {
   1.299 +      return NULL;
   1.300 +    }
   1.301 +
   1.302 +	  if (pos >= seek_pos) {
   1.303 +  	  ret = f;
   1.304 +    	break;
   1.305 +    }
   1.306 +    if ((segment_stop != -1) && (pos > segment_stop))
   1.307 +      break;
   1.308 +  }  
   1.309 +
   1.310 +  return ret;
   1.311 +}
   1.312 +
   1.313  static gboolean
   1.314  gst_nuv_demux_do_seek (GstNuvDemux *nuv, GstEvent * event)
   1.315  {
   1.316 @@ -1224,57 +1306,150 @@
   1.317    GstSeekType stop_type;
   1.318    gint64 stop;
   1.319    gboolean flush;
   1.320 +  frame_index_data *entry;
   1.321 +  gint64 segment_start;
   1.322 +  gint64 segment_stop;
   1.323 +  GstEvent *newsegment_event;
   1.324 +
   1.325  
   1.326    g_debug ("DEMUX SEEK");
   1.327    gst_event_parse_seek (event, &rate, &format, &flags,
   1.328        &cur_type, &cur, &stop_type, &stop);
   1.329  
   1.330 -  if (format == GST_FORMAT_BYTES &&
   1.331 -          nuv->priv->state > GST_NUV_DEMUX_EXTEND_HEADER_DATA &&
   1.332 -          gst_pad_is_linked (nuv->priv->sinkpad)) {
   1.333 +/*
   1.334 +  if (format == GST_FORMAT_TIME) {
   1.335 +    GST_DEBUG_OBJECT (nuv, "Can only seek on BYTES");
   1.336 +    return FALSE;
   1.337 +  }
   1.338 +*/
   1.339  
   1.340 -    flush = flags & GST_SEEK_FLAG_FLUSH;
   1.341 -    if (flush) {
   1.342 -      gst_pad_push_event (nuv->priv->sinkpad, gst_event_new_flush_start ());
   1.343 -
   1.344 -      if (nuv->priv->src_video_pad != NULL) {
   1.345 -        gst_pad_push_event (nuv->priv->src_video_pad, gst_event_new_flush_start ());
   1.346 -      }
   1.347 -
   1.348 -      if (nuv->priv->src_audio_pad != NULL) {
   1.349 -        gst_pad_push_event (nuv->priv->src_audio_pad, gst_event_new_flush_start ());
   1.350 -      }
   1.351 +  if (rate <= 0.0) {
   1.352 +    GST_DEBUG_OBJECT (nuv, "Can only seek with positive rate");
   1.353 +    return FALSE;
   1.354 +  }
   1.355 +  
   1.356 +  if (cur_type == GST_SEEK_TYPE_SET) {
   1.357 +    GST_OBJECT_LOCK (nuv);
   1.358 +    if (gst_nuv_demux_do_seek_index (nuv, cur, -1, format) == NULL) {
   1.359 +      GST_DEBUG_OBJECT (nuv, "No matching seek entry in index");
   1.360 +      GST_OBJECT_UNLOCK (nuv);
   1.361 +      return FALSE;
   1.362      }
   1.363 -    else {
   1.364 -	gst_pad_pause_task (nuv->priv->sinkpad);
   1.365 +    GST_OBJECT_UNLOCK (nuv);
   1.366 +  }
   1.367 +  flush = !!(flags & GST_SEEK_FLAG_FLUSH);
   1.368 +  
   1.369 +  if (flush) {
   1.370 +    gst_pad_push_event (nuv->priv->sinkpad, gst_event_new_flush_start ());
   1.371 +    if (nuv->priv->src_video_pad != NULL) {
   1.372 +      gst_pad_push_event (nuv->priv->src_video_pad, gst_event_new_flush_start ());
   1.373      }
   1.374  
   1.375 -    GST_PAD_STREAM_LOCK (nuv->priv->sinkpad);
   1.376 +    if (nuv->priv->src_audio_pad != NULL) {
   1.377 +      gst_pad_push_event (nuv->priv->src_audio_pad, gst_event_new_flush_start ());
   1.378 +    }
   1.379 +  }
   1.380 +  else {
   1.381 +	  gst_pad_pause_task (nuv->priv->sinkpad);
   1.382 +  }
   1.383  
   1.384 -    g_debug ("offset %ld, cur %ld", nuv->priv->offset, cur);
   1.385 +  GST_PAD_STREAM_LOCK (nuv->priv->sinkpad);
   1.386 +  GST_OBJECT_LOCK (nuv);
   1.387  
   1.388 -    nuv->priv->state = GST_NUV_DEMUX_FRAME_HEADER;
   1.389  
   1.390 -    if (flush) {
   1.391 -      gst_pad_push_event (nuv->priv->sinkpad, gst_event_new_flush_stop ());
   1.392 +  if (cur == GST_CLOCK_TIME_NONE)
   1.393 +    cur = 0;
   1.394  
   1.395 -      if (nuv->priv->src_video_pad != NULL) {
   1.396 -        gst_pad_push_event (nuv->priv->src_video_pad, gst_event_new_flush_stop ());
   1.397 -      }
   1.398  
   1.399 -      if (nuv->priv->src_audio_pad != NULL) {
   1.400 -        gst_pad_push_event (nuv->priv->src_audio_pad, gst_event_new_flush_stop ());
   1.401 -      }
   1.402 +//  if (stop == GST_CLOCK_TIME_NONE)
   1.403 +//    stop = nuv->priv->duration_time;
   1.404 +
   1.405 +  if (cur_type == GST_SEEK_TYPE_SET)
   1.406 +    segment_start = cur;
   1.407 +  else if (cur_type == GST_SEEK_TYPE_CUR)
   1.408 +    segment_start = nuv->priv->segment_start + cur;
   1.409 +  else
   1.410 +    segment_start = nuv->priv->segment_start;
   1.411 +
   1.412 +  if (stop_type == GST_SEEK_TYPE_SET)
   1.413 +    segment_stop = stop;
   1.414 +  else if (stop_type == GST_SEEK_TYPE_CUR)
   1.415 +    segment_stop = nuv->priv->segment_stop + stop;
   1.416 +  else
   1.417 +    segment_stop = nuv->priv->segment_stop;
   1.418 +
   1.419 +//  segment_start = CLAMP (segment_start, 0, nuv->priv->duration_bytes);
   1.420 +//  segment_stop = CLAMP (segment_stop, 0, nuv->priv->duration_bytes);
   1.421 +
   1.422 +  entry = gst_nuv_demux_do_seek_index (nuv, segment_start,
   1.423 +      segment_stop, format);
   1.424 +
   1.425 +  if (entry == NULL) {
   1.426 +    GST_DEBUG_OBJECT (nuv, "No matching seek entry in index");
   1.427 +    goto seek_error;
   1.428 +  }
   1.429 +
   1.430 +  g_debug ("found frame at %lld", entry->offset);
   1.431 +  nuv->priv->offset = entry->offset;
   1.432 +
   1.433 +  segment_start = entry->timecode;
   1.434 +
   1.435 +  nuv->priv->segment_start = segment_start;
   1.436 +  nuv->priv->segment_stop = segment_stop;
   1.437 +
   1.438 +  GST_OBJECT_UNLOCK (nuv);
   1.439 +
   1.440 +/*
   1.441 +  {
   1.442 +  GstMessage *msg;
   1.443 +  msg = gst_message_new_segment_start (GST_OBJECT (nuv), GST_FORMAT_TIME,
   1.444 +    nuv->priv->segment_start);
   1.445 +  
   1.446 +  gst_element_post_message (GST_ELEMENT (nuv), msg);
   1.447 +  }
   1.448 +*/
   1.449 +
   1.450 +
   1.451 +//  newsegment_event = gst_event_new_new_segment (FALSE, rate,
   1.452 +//    GST_FORMAT_TIME, segment_start, segment_stop, segment_start);
   1.453 +
   1.454 +
   1.455 +  if (flush) {
   1.456 +    gst_pad_push_event (nuv->priv->sinkpad, gst_event_new_flush_stop ());
   1.457 +    if (nuv->priv->src_video_pad != NULL) {
   1.458 +      gst_pad_push_event (nuv->priv->src_video_pad, gst_event_new_flush_stop ());
   1.459      }
   1.460  
   1.461 -    g_debug ("STARTING TASK AGAIN");
   1.462 -    gst_pad_start_task (nuv->priv->sinkpad, (GstTaskFunction) gst_nuv_demux_loop,
   1.463 -        nuv->priv->sinkpad);
   1.464 +    if (nuv->priv->src_audio_pad != NULL) {
   1.465 +      gst_pad_push_event (nuv->priv->src_audio_pad, gst_event_new_flush_stop ());
   1.466 +    }
   1.467 +  }
   1.468  
   1.469 -    GST_PAD_STREAM_UNLOCK (nuv->priv->sinkpad);
   1.470 -    return TRUE;
   1.471 +/*
   1.472 +  
   1.473 +  if (nuv->priv->src_video_pad != NULL) {
   1.474 +    gst_pad_push_event (nuv->priv->src_video_pad, newsegment_event);
   1.475    }
   1.476 +  if (nuv->priv->src_audio_pad != NULL) {
   1.477 +    gst_pad_push_event (nuv->priv->src_audio_pad, newsegment_event);
   1.478 +  } 
   1.479 +
   1.480 +*/
   1.481 +
   1.482 +  g_debug ("STARTING TASK AGAIN");
   1.483 +  nuv->priv->state = GST_NUV_DEMUX_FRAME_HEADER;
   1.484 +  gst_pad_start_task (nuv->priv->sinkpad, (GstTaskFunction) gst_nuv_demux_loop,
   1.485 +      nuv->priv->sinkpad);
   1.486 +
   1.487 +  GST_PAD_STREAM_UNLOCK (nuv->priv->sinkpad);
   1.488 +  return TRUE;
   1.489 +
   1.490 +seek_error:
   1.491 +  GST_DEBUG_OBJECT (nuv, "Got a seek error");
   1.492 +  GST_OBJECT_UNLOCK (nuv);
   1.493 +  GST_PAD_STREAM_UNLOCK (nuv->priv->sinkpad);
   1.494    return FALSE;
   1.495 +
   1.496  }
   1.497  
   1.498  static gboolean
   1.499 @@ -1287,60 +1462,14 @@
   1.500    
   1.501    switch (GST_EVENT_TYPE (event)) {
   1.502      case GST_EVENT_SEEK:
   1.503 +      g_debug ("SEEK");
   1.504        res = gst_nuv_demux_do_seek (nuv, event);
   1.505        break;
   1.506      default:
   1.507        res = FALSE;
   1.508        break;
   1.509    }
   1.510 -  return res;
   1.511 -}
   1.512 -
   1.513 -static gboolean
   1.514 -gst_nuv_demux_sink_event (GstPad *pad, GstEvent *event)
   1.515 -{
   1.516 -  gboolean res = FALSE;
   1.517 -  GstNuvDemux *nuv;
   1.518 -
   1.519 -  nuv = GST_NUV_DEMUX (gst_pad_get_parent (pad));
   1.520 -
   1.521 -  switch (GST_EVENT_TYPE (event)) {
   1.522 -    case GST_EVENT_SEEK:
   1.523 -    {
   1.524 -      gdouble rate;
   1.525 -      GstFormat format;
   1.526 -      GstSeekFlags flags;
   1.527 -      GstSeekType cur_type;
   1.528 -      gint64 cur;
   1.529 -      GstSeekType stop_type;
   1.530 -      gint64 stop;
   1.531 -
   1.532 -      gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur, &stop_type, &stop);
   1.533 -      GST_DEBUG_OBJECT (nuv, "got seek, start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, cur, stop);
   1.534 -      g_debug ("got seek, start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, cur, stop);
   1.535 -      res = gst_pad_event_default (pad, event);
   1.536 -      break;
   1.537 -    }
   1.538 -    case GST_EVENT_NEWSEGMENT:
   1.539 -    {
   1.540 -      gint64 start, stop, time;
   1.541 -      gdouble rate;
   1.542 -      GstFormat format;
   1.543 -      gboolean update;
   1.544 -
   1.545 -      gst_event_parse_new_segment (event, &update, &rate, &format, &start, &stop, &time);
   1.546 -      GST_DEBUG_OBJECT (nuv, "got newsegment, start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, start, stop);
   1.547 -      g_debug ("got newsegment, start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, start, stop);
   1.548 -      //nuv->priv->duration_bytes = stop - start;
   1.549 -      res = gst_pad_event_default (pad, event);
   1.550 -      break;
   1.551 -    }
   1.552 -    case GST_EVENT_EOS:
   1.553 -    default:
   1.554 -      res = gst_pad_event_default (pad, event);
   1.555 -      break;
   1.556 -  }
   1.557 -
   1.558 +  
   1.559    gst_object_unref (nuv);
   1.560    return res;
   1.561  }
   1.562 @@ -1377,19 +1506,33 @@
   1.563  }
   1.564  
   1.565  static void
   1.566 +gst_nuv_demux_index_free (gpointer data, gpointer user_data)
   1.567 +{
   1.568 +  g_free (data);
   1.569 +}
   1.570 +
   1.571 +static void
   1.572  gst_nuv_demux_reset (GstNuvDemux * nuv)
   1.573  {
   1.574 +  g_debug ("RESET");
   1.575    nuv->priv->more_data = FALSE;
   1.576    nuv->priv->state = GST_NUV_DEMUX_START;
   1.577    nuv->priv->mode = NUV_PUSH_MODE;
   1.578    nuv->priv->offset = 0;
   1.579 -  nuv->priv->streamer_offset = 0;
   1.580    nuv->priv->time_start = 0;
   1.581    nuv->priv->time_qos = GST_CLOCK_TIME_NONE;
   1.582    nuv->priv->duration_bytes = GST_CLOCK_TIME_NONE;
   1.583    nuv->priv->duration_time = GST_CLOCK_TIME_NONE;
   1.584 -  nuv->priv->duration_average = GST_CLOCK_TIME_NONE;
   1.585 -  gst_segment_init (&nuv->priv->segment, GST_FORMAT_TIME);
   1.586 +  nuv->priv->last_video_return = GST_FLOW_OK;
   1.587 +  nuv->priv->last_audio_return = GST_FLOW_OK;
   1.588 +  nuv->priv->header_lengh = 0;
   1.589 +  nuv->priv->segment_stop = GST_CLOCK_TIME_NONE;
   1.590 +  nuv->priv->segment_start = GST_CLOCK_TIME_NONE;
   1.591 +
   1.592 +  //clear index list
   1.593 +  g_slist_foreach (nuv->priv->index, gst_nuv_demux_index_free, NULL);
   1.594 +  g_slist_free (nuv->priv->index);
   1.595 +  nuv->priv->index = NULL;
   1.596  
   1.597    gst_adapter_clear (nuv->priv->adapter);
   1.598  
   1.599 @@ -1435,7 +1578,7 @@
   1.600  
   1.601    switch (transition) {
   1.602      case GST_STATE_CHANGE_PAUSED_TO_READY:
   1.603 -    //case GST_STATE_CHANGE_READY_TO_NULL:
   1.604 +    case GST_STATE_CHANGE_READY_TO_NULL:
   1.605        g_debug ("PAUSED_TO_READY");
   1.606        gst_nuv_demux_reset (GST_NUV_DEMUX (element));
   1.607        gst_nuv_demux_destoy_src_pad (GST_NUV_DEMUX (element));
   1.608 @@ -1448,76 +1591,6 @@
   1.609    return ret;
   1.610  }
   1.611  
   1.612 -static void
   1.613 -gst_nuv_demux_update_duration (GstNuvDemux *nuv, guint64 current_timestamp)
   1.614 -{
   1.615 -    guint64 interval = 0;
   1.616 -
   1.617 -    if (gst_nuv_demux_get_time_duration (nuv) != GST_CLOCK_TIME_NONE)
   1.618 -        return;
   1.619 -
   1.620 -    interval  = current_timestamp - nuv->priv->last_update;
   1.621 -
   1.622 -    if (interval > (10 * GST_SECOND)) {
   1.623 -        GstMessage* msg = NULL;
   1.624 -        gint64 average = 0;
   1.625 -        gint64 duration_bytes = gst_nuv_demux_get_bytes_duration (nuv);
   1.626 -
   1.627 -        if (duration_bytes == GST_CLOCK_TIME_NONE) {
   1.628 -            return;
   1.629 -        }
   1.630 -
   1.631 -        interval = gst_util_uint64_scale (1, current_timestamp - nuv->priv->time_start, GST_SECOND);
   1.632 -        if (interval > 0) {
   1.633 -            average = gst_util_uint64_scale (1 , nuv->priv->streamer_offset, interval);
   1.634 -        }
   1.635 -        if (average > 0) {
   1.636 -            nuv->priv->duration_average = gst_util_uint64_scale (GST_SECOND, duration_bytes, average);
   1.637 -        }
   1.638 -        
   1.639 -        nuv->priv->last_update = current_timestamp;
   1.640 -        msg = gst_message_new_duration (GST_OBJECT (nuv), GST_FORMAT_TIME, nuv->priv->duration_average);
   1.641 -        gst_element_post_message (GST_ELEMENT (nuv), msg);
   1.642 -        GST_DEBUG_OBJECT (nuv, "New Duration Average %"G_GUINT64_FORMAT, nuv->priv->duration_average);
   1.643 -        g_debug ("New Duration Average %"G_GUINT64_FORMAT, nuv->priv->duration_average);
   1.644 -    }
   1.645 -}
   1.646 -
   1.647 -static gint64
   1.648 -gst_nuv_demux_get_bytes_duration (GstNuvDemux *nuv)
   1.649 -{
   1.650 -    if (nuv->priv->duration_bytes == GST_CLOCK_TIME_NONE) {
   1.651 -        GstPad *peer = gst_pad_get_peer (nuv->priv->sinkpad);
   1.652 -        GstQuery *query = gst_query_new_duration (GST_FORMAT_BYTES);
   1.653 -        if (gst_pad_query (peer, query)) {
   1.654 -            gint64 duration;
   1.655 -
   1.656 -            gst_query_parse_duration (query, NULL, &duration);
   1.657 -            nuv->priv->duration_bytes = duration;
   1.658 -        }
   1.659 -        gst_object_unref (peer);
   1.660 -        gst_query_unref (query);
   1.661 -    }
   1.662 -    return nuv->priv->duration_bytes;
   1.663 -}
   1.664 -
   1.665 -static gint64
   1.666 -gst_nuv_demux_get_time_duration (GstNuvDemux *nuv)
   1.667 -{
   1.668 -    if (nuv->priv->duration_time == GST_CLOCK_TIME_NONE) {
   1.669 -        GstPad *peer = gst_pad_get_peer (nuv->priv->sinkpad);
   1.670 -        GstQuery *query = gst_query_new_duration (GST_FORMAT_TIME);
   1.671 -        if (gst_pad_query (peer, query)) {
   1.672 -            gint64 duration;
   1.673 -            gst_query_parse_duration (query, NULL, &duration);
   1.674 -            nuv->priv->duration_time = duration;
   1.675 -        }
   1.676 -        gst_object_unref (peer);
   1.677 -        gst_query_unref (query);
   1.678 -    }
   1.679 -    return nuv->priv->duration_time;
   1.680 -}
   1.681 -
   1.682  #if (GST_VERSION_MINOR == 10) && (GST_VERSION_MICRO < 6) 
   1.683  GstBuffer *
   1.684  gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)