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)