summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--gst/qtdemux/qtdemux.c77
-rw-r--r--gst/qtdemux/qtdemux.h2
3 files changed, 53 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index d4a40b56..6ad2380b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2006-01-17 Tim-Philipp Müller <tim at centricular dot net>
+
+ * gst/qtdemux/qtdemux.c: (gst_qtdemux_init),
+ (gst_qtdemux_send_event), (gst_qtdemux_handle_src_event),
+ (gst_qtdemux_change_state), (gst_qtdemux_loop_header):
+ * gst/qtdemux/qtdemux.h:
+ Fix seeking for quicktime files. Could still use some more
+ love and sophistication.
+
2006-01-16 Edgard Lima <edgard.lima@indt.org.br>
* ext/libmms/gstmms.c: gst_mms_init:
diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c
index a230f20b..b1a507e6 100644
--- a/gst/qtdemux/qtdemux.c
+++ b/gst/qtdemux/qtdemux.c
@@ -233,8 +233,6 @@ gst_qtdemux_init (GstQTDemux * qtdemux)
qtdemux->state = QTDEMUX_STATE_HEADER;
qtdemux->last_ts = GST_CLOCK_TIME_NONE;
- qtdemux->need_discont = TRUE;
- qtdemux->need_flush = FALSE;
}
#if 0
@@ -331,6 +329,22 @@ gst_qtdemux_handle_src_query (GstPad * pad, GstQuery * query)
return res;
}
+/* sends event to all source pads; takes ownership of the event */
+static void
+gst_qtdemux_send_event (GstQTDemux * qtdemux, GstEvent * event)
+{
+ guint n;
+
+ GST_DEBUG_OBJECT (qtdemux, "pushing %s event on all source pads",
+ GST_EVENT_TYPE_NAME (event));
+
+ for (n = 0; n < qtdemux->n_streams; n++) {
+ gst_event_ref (event);
+ gst_pad_push_event (qtdemux->streams[n]->pad, event);
+ }
+ gst_event_unref (event);
+}
+
static gboolean
gst_qtdemux_handle_src_event (GstPad * pad, GstEvent * event)
{
@@ -359,22 +373,32 @@ gst_qtdemux_handle_src_event (GstPad * pad, GstEvent * event)
break;
}
- gst_pad_event_default (pad, gst_event_new_flush_start ());
+ gst_pad_push_event (qtdemux->sinkpad, gst_event_new_flush_start ());
GST_PAD_STREAM_LOCK (pad);
+ gst_qtdemux_send_event (qtdemux, gst_event_new_flush_start ());
+
/* resync to new time */
for (n = 0; n < qtdemux->n_streams; n++) {
QtDemuxStream *str = qtdemux->streams[n];
for (i = 0; i < str->n_samples; i++) {
- if (str->samples[i].timestamp > desired_offset)
+ /* Seek to the sample just before the desired offset and
+ * let downstream throw away bits outside of the segment */
+ if (str->samples[i].timestamp > desired_offset) {
+ if (i > 0)
+ --i;
break;
+ }
}
str->sample_index = i;
}
- gst_pad_event_default (pad, gst_event_new_flush_stop ());
- qtdemux->need_discont = TRUE;
- qtdemux->need_flush = TRUE;
+ gst_pad_push_event (qtdemux->sinkpad, gst_event_new_flush_stop ());
+ gst_qtdemux_send_event (qtdemux, gst_event_new_flush_stop ());
+
+ gst_qtdemux_send_event (qtdemux,
+ gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,
+ desired_offset, GST_CLOCK_TIME_NONE, desired_offset));
/* and restart */
gst_pad_start_task (qtdemux->sinkpad,
@@ -468,8 +492,6 @@ gst_qtdemux_change_state (GstElement * element, GstStateChange transition)
qtdemux->state = QTDEMUX_STATE_HEADER;
qtdemux->last_ts = GST_CLOCK_TIME_NONE;
- qtdemux->need_discont = TRUE;
- qtdemux->need_flush = FALSE;
for (n = 0; n < qtdemux->n_streams; n++) {
gst_element_remove_pad (element, qtdemux->streams[n]->pad);
g_free (qtdemux->streams[n]->samples);
@@ -621,7 +643,9 @@ gst_qtdemux_loop_header (GstPad * pad)
buf = NULL;
if (size > 0) {
- GST_DEBUG_OBJECT (qtdemux, "reading %d bytes @ ", size);
+ GST_LOG_OBJECT (qtdemux, "reading %d bytes @ " G_GINT64_FORMAT,
+ size, offset);
+
if (gst_pad_pull_range (qtdemux->sinkpad, offset,
size, &buf) != GST_FLOW_OK)
goto error;
@@ -643,6 +667,13 @@ gst_qtdemux_loop_header (GstPad * pad)
*/
}
+ /* first buffer? */
+ if (qtdemux->last_ts == GST_CLOCK_TIME_NONE) {
+ gst_qtdemux_send_event (qtdemux,
+ gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,
+ 0, GST_CLOCK_TIME_NONE, 0));
+ }
+
/* timestamps of AMR aren't known... */
if (stream->fourcc != GST_MAKE_FOURCC ('s', 'a', 'm', 'r')) {
GST_BUFFER_TIMESTAMP (buf) =
@@ -652,33 +683,13 @@ gst_qtdemux_loop_header (GstPad * pad)
GST_SECOND * stream->samples[stream->sample_index].duration
/ stream->timescale;
}
- if (qtdemux->need_discont) {
- GstEvent *event = gst_event_new_new_segment (FALSE, 1.0,
- GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buf),
- GST_CLOCK_TIME_NONE, 0);
- gint n;
-
- GST_DEBUG ("Discont to %" GST_TIME_FORMAT,
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
- qtdemux->need_discont = FALSE;
- for (n = 0; n < qtdemux->n_streams; n++) {
- gst_event_ref (event);
- gst_pad_push_event (qtdemux->streams[n]->pad, event);
- }
- gst_event_unref (event);
- }
- if (qtdemux->need_flush) {
- /* ? */
- qtdemux->need_flush = FALSE;
- }
- GST_DEBUG ("Pushing buf with time=%" GST_TIME_FORMAT,
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
+
+ GST_DEBUG ("Pushing buffer with time %" GST_TIME_FORMAT " on pad %p",
+ GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), stream->pad);
gst_buffer_set_caps (buf, stream->caps);
ret = gst_pad_push (stream->pad, buf);
if (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_LINKED)
goto error;
-
- GST_INFO ("pushing buffer on %" GST_PTR_FORMAT, stream->pad);
}
stream->sample_index++;
break;
diff --git a/gst/qtdemux/qtdemux.h b/gst/qtdemux/qtdemux.h
index a5653fe2..ff09c843 100644
--- a/gst/qtdemux/qtdemux.h
+++ b/gst/qtdemux/qtdemux.h
@@ -71,8 +71,6 @@ struct _GstQTDemux {
/* track stuff */
guint64 last_ts;
- gboolean need_discont;
- gboolean need_flush;
};
struct _GstQTDemuxClass {